WifiNative.java revision 98bdf92ffcda361a6e1465cd0e606c6746d0e506
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;
39c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadhamimport com.android.server.connectivity.KeepalivePacketData;
404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Piusimport com.android.server.net.BaseNetworkObserver;
41590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tanimport com.android.server.wifi.util.FrameParser;
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";
7118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final String mInterfaceName;
72b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final SupplicantStaIfaceHal mSupplicantStaIfaceHal;
73295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private final HostapdHal mHostapdHal;
74b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final WifiVendorHal mWifiVendorHal;
75b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final WificondControl mWificondControl;
764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private final INetworkManagementService mNwManagementService;
771d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private final PropertyService mPropertyService;
78d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private final WifiMetrics mWifiMetrics;
79b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    // TODO(b/69426063): Remove interfaceName from constructor once WifiStateMachine switches over
814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    // to the new interface management methods.
82b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public WifiNative(String interfaceName, WifiVendorHal vendorHal,
83295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                      SupplicantStaIfaceHal staIfaceHal, HostapdHal hostapdHal,
84295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                      WificondControl condControl, INetworkManagementService nwService,
85d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                      PropertyService propertyService, WifiMetrics wifiMetrics) {
86b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mInterfaceName = interfaceName;
87b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWifiVendorHal = vendorHal;
88b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mSupplicantStaIfaceHal = staIfaceHal;
89295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        mHostapdHal = hostapdHal;
90b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWificondControl = condControl;
914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        mNwManagementService = nwService;
921d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        mPropertyService = propertyService;
93d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        mWifiMetrics = wifiMetrics;
94155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
95155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
9618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getInterfaceName() {
9718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return mInterfaceName;
98e26ad459b63271548abbdeba4f8d77fcca9f88bdxinhe    }
99e26ad459b63271548abbdeba4f8d77fcca9f88bdxinhe
100b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
101b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable verbose logging for all sub modules.
102b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
103b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void enableVerboseLogging(int verbose) {
104b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWificondControl.enableVerboseLogging(verbose > 0 ? true : false);
105b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mSupplicantStaIfaceHal.enableVerboseLogging(verbose > 0);
106b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWifiVendorHal.enableVerboseLogging(verbose > 0);
107ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    }
108ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle
10998bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius    /********************************************************
11098bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius     * Interface management related methods.
11198bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius     ********************************************************/
112d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
113e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     * Meta-info about every iface that is active.
114e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     */
115e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private static class Iface {
116e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Type of ifaces possible */
117e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public static final int IFACE_TYPE_AP = 0;
118e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public static final int IFACE_TYPE_STA = 1;
119e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
120e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        @IntDef({IFACE_TYPE_AP, IFACE_TYPE_STA})
121e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        @Retention(RetentionPolicy.SOURCE)
122e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public @interface IfaceType{}
123e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
124e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Identifier allocated for the interface */
125e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public final int id;
126e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Type of the iface: STA or AP */
127e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public final @IfaceType int type;
128e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Name of the interface */
129e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public String name;
130e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** External iface destroyed listener for the iface */
131e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public InterfaceCallback externalListener;
1324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Network observer registered for this interface */
1334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public NetworkObserverInternal networkObserver;
134e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
135e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        Iface(int id, @Iface.IfaceType int type) {
136e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            this.id = id;
137e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            this.type = type;
138e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
139e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    }
140e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
141e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
142e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     * Iface Management entity. This class maintains list of all the active ifaces.
143e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     */
144e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private static class IfaceManager {
145e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Integer to allocate for the next iface being created */
146e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private int mNextId;
147e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Map of the id to the iface structure */
148e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private HashMap<Integer, Iface> mIfaces = new HashMap<>();
149e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
150e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Allocate a new iface for the given type */
151e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface allocateIface(@Iface.IfaceType  int type) {
152e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            Iface iface = new Iface(mNextId, type);
153e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            mIfaces.put(mNextId, iface);
154e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            mNextId++;
155e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return iface;
156e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
157e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
158e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Remove the iface using the provided id */
159e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface removeIface(int id) {
160e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.remove(id);
161e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
162e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
163e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Lookup the iface using the provided id */
164e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface getIface(int id) {
165e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.get(id);
166e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
167e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
168e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Lookup the iface using the provided name */
169e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface getIface(@NonNull String ifaceName) {
170e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            for (Iface iface : mIfaces.values()) {
171e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                if (TextUtils.equals(iface.name, ifaceName)) {
172e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                    return iface;
173e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                }
174e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            }
175e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return null;
176e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
177e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
178e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Iterator to use for deleting all the ifaces while performing teardown on each of them */
179e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iterator<Integer> getIfaceIdIter() {
180e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.keySet().iterator();
181e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
182e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
183e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any iface active. */
184e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyIface() {
185e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return !mIfaces.isEmpty();
186e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
187e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
188e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any iface of the given type active. */
189e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyIfaceOfType(@Iface.IfaceType int type) {
190e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            for (Iface iface : mIfaces.values()) {
191e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                if (iface.type == type) {
192e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                    return true;
193e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                }
194e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            }
195e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return false;
196e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
197e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
198b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        /** Checks if there are any iface of the given type active. */
199b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        private Iface findAnyIfaceOfType(@Iface.IfaceType int type) {
200b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            for (Iface iface : mIfaces.values()) {
201b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                if (iface.type == type) {
202b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                    return iface;
203b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                }
204b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            }
205b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            return null;
206b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        }
207b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
208e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any STA iface active. */
209e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyStaIface() {
210e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return hasAnyIfaceOfType(Iface.IFACE_TYPE_STA);
211e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
212e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
213e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any AP iface active. */
214e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyApIface() {
215e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return hasAnyIfaceOfType(Iface.IFACE_TYPE_AP);
216e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
217b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
218b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        private String findAnyStaIfaceName() {
219b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            Iface iface = findAnyIfaceOfType(Iface.IFACE_TYPE_STA);
220b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            if (iface == null) {
221b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                return null;
222b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            }
223b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            return iface.name;
224b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        }
2251d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
226840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        private String findAnyApIfaceName() {
227840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Iface iface = findAnyIfaceOfType(Iface.IFACE_TYPE_AP);
228840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            if (iface == null) {
229840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                return null;
230840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            }
231840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            return iface.name;
232840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        }
233840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
2341d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        /** Removes the existing iface that does not match the provided id. */
2351d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        public Iface removeExistingIface(int newIfaceId) {
2361d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Iface removedIface = null;
2371d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            // The number of ifaces in the database could be 1 existing & 1 new at the max.
2381d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mIfaces.size() > 2) {
2391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.wtf(TAG, "More than 1 existing interface found");
2401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
2411d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Iterator<Map.Entry<Integer, Iface>> iter = mIfaces.entrySet().iterator();
2421d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            while (iter.hasNext()) {
2431d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Map.Entry<Integer, Iface> entry = iter.next();
2441d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (entry.getKey() != newIfaceId) {
2451d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    removedIface = entry.getValue();
2461d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    iter.remove();
2471d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                }
2481d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
2491d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            return removedIface;
2501d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
251e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    }
252e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
253e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private Object mLock = new Object();
254e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private final IfaceManager mIfaceMgr = new IfaceManager();
255e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private HashSet<StatusListener> mStatusListeners = new HashSet<>();
256e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
2574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to start supplicant if there were no ifaces */
2584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean startHal() {
2594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
2604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyIface()) {
2611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (mWifiVendorHal.isVendorHalSupported()) {
2621d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    if (!mWifiVendorHal.startVendorHal()) {
2631d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        Log.e(TAG, "Failed to start vendor HAL");
2641d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        return false;
2651d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    }
2661d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                } else {
2671d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.i(TAG, "Vendor Hal not supported, ignoring start.");
2684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
2694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
2704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
2714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
2724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
2734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
2744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to stop HAL if there are no more ifaces */
2754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void stopHalAndWificondIfNecessary() {
2764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
2774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyIface()) {
2784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.tearDownInterfaces()) {
2791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to teardown ifaces from wificond");
2801d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                }
2811d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (mWifiVendorHal.isVendorHalSupported()) {
2821d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    mWifiVendorHal.stopVendorHal();
2831d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                } else {
2841d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.i(TAG, "Vendor Hal not supported, ignoring stop.");
2854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
2864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
2874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
2884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
2894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
2904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private static final int CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS = 100;
2914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private static final int CONNECT_TO_SUPPLICANT_RETRY_TIMES = 50;
2924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
2934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * This method is called to wait for establishing connection to wpa_supplicant.
2944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     *
2954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * @return true if connection is established, false otherwise.
2964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
2974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean waitForSupplicantConnection() {
2984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        // Start initialization if not already started.
2994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        if (!mSupplicantStaIfaceHal.isInitializationStarted()
3004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                && !mSupplicantStaIfaceHal.initialize()) {
3014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        boolean connected = false;
3044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        int connectTries = 0;
3054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
3064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Check if the initialization is complete.
3074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            connected = mSupplicantStaIfaceHal.isInitializationComplete();
3084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (connected) {
3094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                break;
3104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            try {
3124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
3134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } catch (InterruptedException ignore) {
3144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return connected;
3174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to start supplicant if there were no STA ifaces */
3204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean startSupplicant() {
3214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyStaIface()) {
3234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.enableSupplicant()) {
3241d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to enable supplicant");
3254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!waitForSupplicantConnection()) {
3281d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to connect to supplicant");
3294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
331d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                if (!mSupplicantStaIfaceHal.registerDeathHandler(
332d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                        new SupplicantDeathHandlerInternal())) {
3331d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to register supplicant death handler");
3344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
3384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to stop supplicant if there are no more STA ifaces */
3424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void stopSupplicantIfNecessary() {
3434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyStaIface()) {
3454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mSupplicantStaIfaceHal.deregisterDeathHandler()) {
3461d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to deregister supplicant death handler");
3474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.disableSupplicant()) {
3491d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to disable supplicant");
3504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method to register a network observer and return it */
3564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean registerNetworkObserver(@NonNull NetworkObserverInternal observer) {
3574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        try {
3584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mNwManagementService.registerObserver(observer);
3594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        } catch (RemoteException e) {
3604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3614ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return true;
3634ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method to register a network observer and return it */
3664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean unregisterNetworkObserver(@NonNull NetworkObserverInternal observer) {
3674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        try {
3684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mNwManagementService.unregisterObserver(observer);
3694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        } catch (RemoteException e) {
3704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return true;
3734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown client iface and perform necessary cleanup */
3764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onClientInterfaceDestroyed(@NonNull Iface iface) {
3774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!unregisterNetworkObserver(iface.networkObserver)) {
3791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to unregister network observer for iface=" + iface.name);
3804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.teardownIface(iface.name)) {
3821d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to teardown iface in supplicant=" + iface.name);
3834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.tearDownClientInterface(iface.name)) {
3851d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to teardown iface in wificond=" + iface.name);
3864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopSupplicantIfNecessary();
3884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopHalAndWificondIfNecessary();
3894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown softAp iface and perform necessary cleanup */
3934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onSoftApInterfaceDestroyed(@NonNull Iface iface) {
3944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!unregisterNetworkObserver(iface.networkObserver)) {
3961d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to unregister network observer for iface=" + iface.name);
3974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
398295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (!mHostapdHal.removeAccessPoint(iface.name)) {
399295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                Log.e(TAG, "Failed to remove access point on iface=" + iface.name);
400295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
401295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            // TODO(b/71513606): Move this to a global operation.
402295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (!mWificondControl.stopHostapd(iface.name)) {
403295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                Log.e(TAG, "Failed to stop hostapd on iface=" + iface.name);
4044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.tearDownSoftApInterface(iface.name)) {
4061d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to teardown iface in wificond=" + iface.name);
4074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopHalAndWificondIfNecessary();
4094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown iface and perform necessary cleanup */
4134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onInterfaceDestroyed(@NonNull Iface iface) {
4144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
4154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
4164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onClientInterfaceDestroyed(iface);
4174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
4184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onSoftApInterfaceDestroyed(iface);
4194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Invoke the external callback.
4214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener.onDestroyed(iface.name);
4224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
4264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Callback to be invoked by HalDeviceManager when an interface is destroyed.
4274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
4284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class InterfaceDestoyedListenerInternal
4294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            implements HalDeviceManager.InterfaceDestroyedListener {
4304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Identifier allocated for the interface */
4314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        private final int mInterfaceId;
4324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        InterfaceDestoyedListenerInternal(int ifaceId) {
4344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mInterfaceId = ifaceId;
4354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void onDestroyed(@NonNull String ifaceName) {
4394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
4404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                final Iface iface = mIfaceMgr.removeIface(mInterfaceId);
4414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (iface == null) {
4421d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Received iface destroyed notification on an invalid iface="
4434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                            + ifaceName);
4444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
4454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
4464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onInterfaceDestroyed(iface);
4471d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Successfully torn down iface=" + ifaceName);
4484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
452d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    /** Helper method invoked to cleanup state after one of the native daemon's death. */
453d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private void onNativeDaemonDeath() {
454d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        synchronized (mLock) {
455d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            Log.i(TAG, "One of the daemons died. Tearing down everything");
456d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            Iterator<Integer> ifaceIdIter = mIfaceMgr.getIfaceIdIter();
457d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            while (ifaceIdIter.hasNext()) {
458d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Iface iface = mIfaceMgr.getIface(ifaceIdIter.next());
459d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                ifaceIdIter.remove();
460d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onInterfaceDestroyed(iface);
461d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "Successfully torn down iface=" + iface.name);
462d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
463d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            for (StatusListener listener : mStatusListeners) {
464d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                listener.onStatusChanged(false);
465d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
466d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            // TODO(70572148): Do we need to wait to mark the system ready again?
467d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            for (StatusListener listener : mStatusListeners) {
468d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                listener.onStatusChanged(true);
469d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
470d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
471d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
472d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
4734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
474d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the Vendor HAL daemon.
4754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
476d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class VendorHalDeathHandlerInternal implements VendorHalDeathEventHandler {
4774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void onDeath() {
4794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
480d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "Vendor HAL died. Cleaning up internal state.");
481d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
482d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumHalCrashes();
483d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
484d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
485d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
486d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
487d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    /**
488d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the wificond daemon.
489d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     */
490d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class WificondDeathHandlerInternal implements WificondDeathEventHandler {
491d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        @Override
492d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        public void onDeath() {
493d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            synchronized (mLock) {
494d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "wificond died. Cleaning up internal state.");
495d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
496d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWificondCrashes();
497d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
498d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
499d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
500d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
501d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    /**
502d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the supplicant daemon.
503d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     */
504d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class SupplicantDeathHandlerInternal implements SupplicantDeathEventHandler {
505d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        @Override
506d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        public void onDeath() {
507d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            synchronized (mLock) {
508d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "wpa_supplicant died. Cleaning up internal state.");
509d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
510d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumSupplicantCrashes();
5114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
5124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
5144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
5164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Network observer to use for all interface up/down notifications.
5174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
5184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class NetworkObserverInternal extends BaseNetworkObserver {
5194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Identifier allocated for the interface */
5204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        private final int mInterfaceId;
5214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        NetworkObserverInternal(int id) {
5234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mInterfaceId = id;
5244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
5274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void interfaceLinkStateChanged(String ifaceName, boolean isUp) {
5284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
5291d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Interface link state changed=" + ifaceName + ", isUp=" + isUp);
5304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                final Iface iface = mIfaceMgr.getIface(mInterfaceId);
5314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (iface == null) {
5321d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Received iface up/down notification on an invalid iface="
5334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                            + ifaceName);
5344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
5354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
5364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (isUp) {
5374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    iface.externalListener.onUp(ifaceName);
5384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                } else {
5394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    iface.externalListener.onDown(ifaceName);
5404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
5414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
5424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
5444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5451d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // For devices that don't support the vendor HAL, we will not support any concurrency.
5461d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // So simulate the HalDeviceManager behavior by triggering the destroy listener for
5471d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // any active interface.
5481d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String handleIfaceCreationWhenVendorHalNotSupported(@NonNull Iface newIface) {
5491d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        Iface existingIface = mIfaceMgr.removeExistingIface(newIface.id);
5501d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        if (existingIface != null) {
5511d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            onInterfaceDestroyed(existingIface);
5521d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully torn down iface=" + existingIface.name);
5531d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
5541d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        // Return the interface name directly from the system property.
5551d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        return mPropertyService.getString("wifi.interface", "wlan0");
5561d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
5571d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
5581d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
5591d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle creation of STA iface.
5601d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
5611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
5621d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
5631d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String createStaIface(@NonNull Iface iface) {
5641d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
5651d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
5661d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.createStaIface(
5671d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        new InterfaceDestoyedListenerInternal(iface.id));
5681d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
5691d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface.");
5701d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceCreationWhenVendorHalNotSupported(iface);
5711d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
5721d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
5731d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
5741d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
5751d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
5761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle creation of AP iface.
5771d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
5781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
5791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
5801d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String createApIface(@NonNull Iface iface) {
5811d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
5821d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
5831d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.createApIface(
5841d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        new InterfaceDestoyedListenerInternal(iface.id));
5851d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
5861d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring createApIface.");
5871d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceCreationWhenVendorHalNotSupported(iface);
5881d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
5891d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
5901d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
5911d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
5921d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // For devices that don't support the vendor HAL, we will not support any concurrency.
5931d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // So simulate the HalDeviceManager behavior by triggering the destroy listener for
5941d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // the interface.
5951d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean handleIfaceRemovalWhenVendorHalNotSupported(@NonNull Iface iface) {
5961d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        mIfaceMgr.removeIface(iface.id);
5971d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        onInterfaceDestroyed(iface);
5981d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        Log.i(TAG, "Successfully torn down iface=" + iface.name);
5991d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        return true;
6001d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6011d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6021d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6031d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle removal of STA iface.
6041d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
6051d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
6061d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6071d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean removeStaIface(@NonNull Iface iface) {
6081d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6091d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6101d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.removeStaIface(iface.name);
6111d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6121d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring removeStaIface.");
6131d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceRemovalWhenVendorHalNotSupported(iface);
6141d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6151d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6161d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6171d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6181d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6191d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle removal of STA iface.
6201d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6211d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean removeApIface(@NonNull Iface iface) {
6221d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6231d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6241d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.removeApIface(iface.name);
6251d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6261d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring removeApIface.");
6271d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceRemovalWhenVendorHalNotSupported(iface);
6281d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6291d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6301d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6311d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
632e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
633d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Initialize the native modules.
634d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
635d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return true on success, false otherwise.
636d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
637d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public boolean initialize() {
6384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
639e59dd55ea7446c3325be8cde31fbeca1e14fb263Roshan Pius            if (!mWifiVendorHal.initialize(new VendorHalDeathHandlerInternal())) {
6401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to initialize vendor HAL");
6414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
6424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
643d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            if (!mWificondControl.registerDeathHandler(new WificondDeathHandlerInternal())) {
6441d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to initialize wificond");
6454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
6464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
6484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
649d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
650d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
651d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
652d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the status of one of the native daemons
653d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL) changes.
654d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
655d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface StatusListener {
656d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
657d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param allReady Indicates if all the native daemons are ready for operation or not.
658d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
659d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onStatusChanged(boolean allReady);
660d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
661d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
662d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
663d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Register a StatusListener to get notified about any status changes from the native daemons.
664d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
665d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * It is safe to re-register the same callback object - duplicates are detected and only a
666d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * single copy kept.
667d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
668d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param listener StatusListener listener object.
669d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
670d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void registerStatusListener(@NonNull StatusListener listener) {
671e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        mStatusListeners.add(listener);
672d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
673d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
674d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
675d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the associated interface is destroyed, up or down.
676d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
677d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface InterfaceCallback {
678d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
679d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface destroyed by HalDeviceManager.
680d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
681d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
682d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
683d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDestroyed(String ifaceName);
684d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
685d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
686d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is up.
687d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
688d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
689d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
690d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onUp(String ifaceName);
691d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
692d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
693d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is down.
694d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
695d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
696d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
697d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDown(String ifaceName);
698d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
699d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
700fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    private void initializeNwParamsForClientInterface(@NonNull String ifaceName) {
701fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        try {
702fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // A runtime crash or shutting down AP mode can leave
703fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IP addresses configured, and this affects
704fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // connectivity when supplicant starts up.
705fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Ensure we have no IP addresses before a supplicant start.
706fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.clearInterfaceAddresses(ifaceName);
707fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
708fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Set privacy extensions
709fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.setInterfaceIpv6PrivacyExtensions(ifaceName, true);
710fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
711fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IPv6 is enabled only as long as access point is connected since:
712fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - IPv6 addresses and routes stick around after disconnection
713fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel is unaware when connected and fails to start IPv6 negotiation
714fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel can start autoconfiguration when 802.1x is not complete
715fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.disableIpv6(ifaceName);
716fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (RemoteException re) {
7171d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Unable to change interface settings: " + re);
718fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (IllegalStateException ie) {
7191d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Unable to change interface settings: " + ie);
720fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        }
721fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    }
722fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
723d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
724d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Client mode operations.
725d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
726d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in STA mode in all the native daemons
727d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
728d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
729d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
730d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
731d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
732d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public String setupInterfaceForClientMode(@NonNull InterfaceCallback interfaceCallback) {
7334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
7344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
7351d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start Hal");
736d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
7374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startSupplicant()) {
7401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start supplicant");
741d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToSupplicant();
7424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
7454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
7461d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to allocate new STA iface");
7474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
7501d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            iface.name = createStaIface(iface);
7514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
7521d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to create iface in vendor HAL");
7534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
754d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
7554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
7581d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to setup iface in wificond=" + iface.name);
7594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
760d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToWificond();
7614ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7634ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
7641d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to setup iface in supplicant=" + iface.name);
7654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
766d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToSupplicant();
7674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
7704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
7711d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
7724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
7734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
775fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            initializeNwParamsForClientInterface(iface.name);
7761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully setup iface=" + iface.name);
7774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
7784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
779d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
780d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
781d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
782d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Soft AP mode operations.
783d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
784d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in AP mode in all the native daemons
785d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
786d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
787d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
788d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
789d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
790d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public String setupInterfaceForSoftApMode(@NonNull InterfaceCallback interfaceCallback) {
7914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
7924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
7931d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start Hal");
794d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
7954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_AP);
7984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
7991d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to allocate new AP iface");
8004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
8031d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            iface.name = createApIface(iface);
8044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
8051d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to create iface in vendor HAL");
8064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
807d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                // TODO(b/68716726): Separate SoftAp metrics
808d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
8094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForSoftApMode(iface.name) == null) {
8121d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to setup iface in wificond=" + iface.name);
8134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
814d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                // TODO(b/68716726): Separate SoftAp metrics
815d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToWificond();
8164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
8194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
8201d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
8214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
8224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8241d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully setup iface=" + iface.name);
8254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
8264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
827d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
828d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
829d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
8309c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * Check if the interface is up or down.
8319c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     *
8329c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @param ifaceName Name of the interface.
8339c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @return true if iface is up, false if it's down or on error.
8349c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     */
8359c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    public boolean isInterfaceUp(@NonNull String ifaceName) {
8369c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        synchronized (mLock) {
8379c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
8389c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (iface == null) {
8391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Trying to get iface state on invalid iface=" + ifaceName);
8409c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
8419c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
8429c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            InterfaceConfiguration config = null;
8439c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            try {
8449c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                config = mNwManagementService.getInterfaceConfig(ifaceName);
8459c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            } catch (RemoteException e) {
8469c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
8479c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (config == null) {
8489c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
8499c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
8509c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            return config.isUp();
8519c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        }
8529c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    }
8539c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius
8549c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    /**
855d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Teardown an interface in Client/AP mode.
856d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
857d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method tears down the associated interface from all the native daemons
858d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
859840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Also, brings down the HAL, supplicant or hostapd as necessary.
860d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
861d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param ifaceName Name of the interface.
862d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
863d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void teardownInterface(@NonNull String ifaceName) {
8644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
8654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
8664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
8671d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Trying to teardown an invalid iface=" + ifaceName);
8684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return;
8694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Trigger the iface removal from HAL. The rest of the cleanup will be triggered
8714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // from the interface destroyed callback.
8724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
8731d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (!removeStaIface(iface)) {
8741d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to remove iface in vendor HAL=" + ifaceName);
8754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
8764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
8774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
8781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (!removeApIface(iface)) {
8791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to remove iface in vendor HAL=" + ifaceName);
8804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
8814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
8824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8831d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully initiated teardown for iface=" + ifaceName);
8844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
885d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
886d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
887b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    /**
888840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Teardown all the active interfaces.
889840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
890840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * This method tears down the associated interfaces from all the native daemons
891840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
892840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Also, brings down the HAL, supplicant or hostapd as necessary.
893840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     */
894840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    public void teardownAllInterfaces() {
895840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        synchronized (mLock) {
896840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Iterator<Integer> ifaceIdIter = mIfaceMgr.getIfaceIdIter();
897840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            while (ifaceIdIter.hasNext()) {
898840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                Iface iface = mIfaceMgr.getIface(ifaceIdIter.next());
899840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                teardownInterface(iface.name);
900840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            }
901840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Log.i(TAG, "Successfully initiated teardown for all ifaces");
902840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        }
903840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    }
904840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
905840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    /**
906b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * Get name of the client interface.
907b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
908b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * This is mainly used by external modules that needs to perform some
909b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * client operations on the STA interface.
910b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
911b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * TODO(b/70932231): This may need to be reworked once we start supporting STA + STA.
912b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
913b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * @return Interface name of any active client interface, null if no active client interface
914b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * exist.
915b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * Return Values for the different scenarios are listed below:
916b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * a) When there are no client interfaces, returns null.
917b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * b) when there is 1 client interface, returns the name of that interface.
918b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * c) When there are 2 or more client interface, returns the name of any client interface.
919b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     */
920b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    public String getClientInterfaceName() {
921b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        return mIfaceMgr.findAnyStaIfaceName();
922b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    }
923b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
924840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    /**
925840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Get name of the softap interface.
926840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
927840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * This is mainly used by external modules that needs to perform some
928840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * operations on the AP interface.
929840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
930840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * TODO(b/70932231): This may need to be reworked once we start supporting AP + AP.
931840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
932840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * @return Interface name of any active softap interface, null if no active softap interface
933840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * exist.
934840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Return Values for the different scenarios are listed below:
935840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * a) When there are no softap interfaces, returns null.
936840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * b) when there is 1 softap interface, returns the name of that interface.
937840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * c) When there are 2 or more softap interface, returns the name of any softap interface.
938840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     */
939840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    public String getSoftApInterfaceName() {
940840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        return mIfaceMgr.findAnyApIfaceName();
941840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    }
942840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
943b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
944b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Wificond operations
945b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
946b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
947b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Result of a signal poll.
948b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
949b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class SignalPollResult {
950b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // RSSI value in dBM.
951b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int currentRssi;
952b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        //Transmission bit rate in Mbps.
953b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txBitrate;
954b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Association frequency in MHz.
955b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int associationFrequency;
956b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
957b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
958b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
959b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * WiFi interface transimission counters.
960b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
961b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class TxPacketCounters {
962b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of successfully transmitted packets.
963b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txSucceeded;
964b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of tramsmission failures.
965b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txFailed;
966b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
967b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
96870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
96955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     * Callback to notify wificond death.
97055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     */
97155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    public interface WificondDeathEventHandler {
97255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        /**
97355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         * Invoked when the wificond dies.
97455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         */
97555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        void onDeath();
97655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    }
97755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius
97855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    /**
979d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Request signal polling to wificond.
980d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns an SignalPollResult object.
981d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns null on failure.
982d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    */
983d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public SignalPollResult signalPoll() {
98491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.signalPoll(mInterfaceName);
985d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
986d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
987d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
988d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * Fetch TX packet counters on current connection from wificond.
989d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns an TxPacketCounters object.
990d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns null on failure.
991d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    */
992d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public TxPacketCounters getTxPacketCounters() {
99391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.getTxPacketCounters(mInterfaceName);
994d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
995d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
99624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
997a70c07d019065187112945c091fc2e924af18980Roshan Pius     * Query the list of valid frequencies for the provided band.
998a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The result depends on the on the country code that has been set.
999a70c07d019065187112945c091fc2e924af18980Roshan Pius     *
1000a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants.
1001a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The following bands are supported:
1002a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_24_GHZ
1003a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ
1004a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY
1005a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @return frequencies vector of valid frequencies (MHz), or null for error.
1006a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @throws IllegalArgumentException if band is not recognized.
1007a70c07d019065187112945c091fc2e924af18980Roshan Pius     */
1008a70c07d019065187112945c091fc2e924af18980Roshan Pius    public int [] getChannelsForBand(int band) {
1009a70c07d019065187112945c091fc2e924af18980Roshan Pius        return mWificondControl.getChannelsForBand(band);
1010a70c07d019065187112945c091fc2e924af18980Roshan Pius    }
1011a70c07d019065187112945c091fc2e924af18980Roshan Pius
1012a70c07d019065187112945c091fc2e924af18980Roshan Pius    /**
1013b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start a scan using wificond for the given parameters.
1014b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param freqs list of frequencies to scan for, if null scan all supported channels.
1015b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
1016b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns true on success.
101724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
1018b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean scan(Set<Integer> freqs, Set<String> hiddenNetworkSSIDs) {
101991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.scan(mInterfaceName, freqs, hiddenNetworkSSIDs);
1020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
102218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /**
1023b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetch the latest scan result from kernel via wificond.
1024b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns an ArrayList of ScanDetail.
1025b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Returns an empty ArrayList on failure.
102618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
1027b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public ArrayList<ScanDetail> getScanResults() {
102891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.getScanResults(
102991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius                mInterfaceName, WificondControl.SCAN_TYPE_SINGLE_SCAN);
103071c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    }
103171c4c2a898a827a867564159ce78e41aedd2295bSohani Rao
103271c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    /**
103371c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Fetch the latest scan result from kernel via wificond.
103471c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * @return Returns an ArrayList of ScanDetail.
103571c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Returns an empty ArrayList on failure.
103671c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     */
103771c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    public ArrayList<ScanDetail> getPnoScanResults() {
103891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.getScanResults(mInterfaceName, WificondControl.SCAN_TYPE_PNO_SCAN);
1039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1041b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1042b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start PNO scan.
1043b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pnoSettings Pno scan configuration.
1044b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
104518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
1046b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean startPnoScan(PnoSettings pnoSettings) {
104791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.startPnoScan(mInterfaceName, pnoSettings);
1048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1050b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1051b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop PNO scan.
1052b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
1053b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1054b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean stopPnoScan() {
105591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.stopPnoScan(mInterfaceName);
105618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
105718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
1058045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1059045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Callbacks for SoftAp interface.
1060045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
1061045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    public interface SoftApListener {
1062045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        /**
1063045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         * Invoked when the number of associated stations changes.
1064045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         */
1065045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        void onNumAssociatedStationsChanged(int numStations);
1066045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1067045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1068295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private static final int CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS = 100;
1069295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private static final int CONNECT_TO_HOSTAPD_RETRY_TIMES = 50;
1070295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    /**
1071295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     * This method is called to wait for establishing connection to hostapd.
1072295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     *
1073295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     * @return true if connection is established, false otherwise.
1074295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     */
1075295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private boolean waitForHostapdConnection() {
1076295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        // Start initialization if not already started.
1077295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!mHostapdHal.isInitializationStarted()
1078295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                && !mHostapdHal.initialize()) {
1079295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1080295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1081295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        boolean connected = false;
1082295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        int connectTries = 0;
1083295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        while (!connected && connectTries++ < CONNECT_TO_HOSTAPD_RETRY_TIMES) {
1084295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            // Check if the initialization is complete.
1085295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            connected = mHostapdHal.isInitializationComplete();
1086295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (connected) {
1087295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                break;
1088295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
1089295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            try {
1090295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                Thread.sleep(CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS);
1091295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            } catch (InterruptedException ignore) {
1092295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
1093295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1094295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return connected;
1095295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    }
1096295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius
1097045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1098045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Start Soft AP operation using the provided configuration.
1099045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
1100045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param config Configuration to use for the soft ap created.
1101045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param listener Callback for AP events.
1102045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
1103045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
1104045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    public boolean startSoftAp(WifiConfiguration config, SoftApListener listener) {
1105295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!mWificondControl.startHostapd(mInterfaceName, listener)) {
1106295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to start hostapd");
1107295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1108295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1109295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!waitForHostapdConnection()) {
1110295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to establish connection to hostapd");
1111295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1112295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1113295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!mHostapdHal.addAccessPoint(mInterfaceName, config)) {
1114295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to add acccess point");
1115295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1116295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1117295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return true;
1118045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1119045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1120045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1121045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Stop the ongoing Soft AP operation.
1122045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
1123045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
1124045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
1125045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    public boolean stopSoftAp() {
1126295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!mHostapdHal.removeAccessPoint(mInterfaceName)) {
1127295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to remove access point");
1128295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1129295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return mWificondControl.stopHostapd(mInterfaceName);
1130045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1131045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1132b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
113302367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     * Hostapd operations
113402367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     ********************************************************/
113502367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius
113602367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius    /**
113702367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     * Callback to notify hostapd death.
113802367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     */
113902367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius    public interface HostapdDeathEventHandler {
114002367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius        /**
114102367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius         * Invoked when the supplicant dies.
114202367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius         */
114302367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius        void onDeath();
1144045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1145045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1146b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1147b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Supplicant operations
1148b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1149f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius
1150f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    /**
1151fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     * Callback to notify supplicant death.
1152fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     */
1153fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    public interface SupplicantDeathEventHandler {
1154fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        /**
1155fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         * Invoked when the supplicant dies.
1156fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         */
1157fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        void onDeath();
1158fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    }
1159fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius
1160fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    /**
1161b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set supplicant log level
1162782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     *
1163b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param turnOnVerbose Whether to turn on verbose logging or not.
1164782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     */
1165b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void setSupplicantLogLevel(boolean turnOnVerbose) {
1166f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        mSupplicantStaIfaceHal.setLogLevel(turnOnVerbose);
1167e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    }
1168e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius
116938a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius    /**
1170b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reconnection if the iface is disconnected.
1171b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1172b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
117338a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius     */
1174b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean reconnect() {
1175b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.reconnect(mInterfaceName);
1176f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
11779d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius
11789d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius    /**
1179b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reassociation even if the iface is currently connected.
1180b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1181b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
11829d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     */
1183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean reassociate() {
1184b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.reassociate(mInterfaceName);
1185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1188b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a disconnection from the currently connected network.
1189b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1190b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1191b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1192b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean disconnect() {
1193b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.disconnect(mInterfaceName);
119477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
119577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
1196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1197b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Makes a callback to HIDL to getMacAddress from supplicant
1198b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1199b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return string containing the MAC address, or null on a failed call
1200b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1201b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public String getMacAddress() {
1202b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.getMacAddress(mInterfaceName);
1203446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    }
1204446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng
1205f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V4_MULTICAST = 0;
1206f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V6_MULTICAST = 1;
1207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V4 packets
1209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Multicast filtering rules work as follows:
1212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
1214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * a power optimized mode (typically when screen goes off).
1215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
1217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
1218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-ADD Num
1220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
1221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and DRIVER RXFILTER-START
1223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to stop the usage of these rules, we do
1224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-STOP
1226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-REMOVE Num
1227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num is as described for RXFILTER-ADD
1228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The  SETSUSPENDOPT driver command overrides the filtering rules
1230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startFilteringMulticastV4Packets() {
1232b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(mInterfaceName)
1233b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
1234b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                        mInterfaceName, RX_FILTER_TYPE_V4_MULTICAST)
1235b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(mInterfaceName);
1236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V4 packets.
1240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean stopFilteringMulticastV4Packets() {
1243b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(mInterfaceName)
1244b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
1245b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                        mInterfaceName, RX_FILTER_TYPE_V4_MULTICAST)
1246b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(mInterfaceName);
1247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V6 packets
1251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startFilteringMulticastV6Packets() {
1254b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(mInterfaceName)
1255b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
1256b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                        mInterfaceName, RX_FILTER_TYPE_V6_MULTICAST)
1257b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(mInterfaceName);
1258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V6 packets.
1262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean stopFilteringMulticastV6Packets() {
1265b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(mInterfaceName)
1266b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
1267b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                        mInterfaceName, RX_FILTER_TYPE_V6_MULTICAST)
1268b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(mInterfaceName);
1269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1271f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED  = 0;
1272f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
1273f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_SENSE    = 2;
12747ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    /**
12757ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * Sets the bluetooth coexistence mode.
12767ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *
12777ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
12787ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
12797ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
12807ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * @return Whether the mode was successfully set.
12817ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      */
1282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setBluetoothCoexistenceMode(int mode) {
1283b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceMode(mInterfaceName, mode);
1284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
1288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * some of the low-level scan parameters used by the driver are changed to
1289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * reduce interference with A2DP streaming.
1290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1291cc180872c51908b15ce5cbf834634ff323e036bcChristopher Wiley     * @param setCoexScanMode whether to enable or disable this mode
1292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the command succeeded, {@code false} otherwise.
1293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
1295b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceScanModeEnabled(
1296b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                mInterfaceName, setCoexScanMode);
1297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1299b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1300b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable suspend mode optimizations.
1301b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1302b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false otherwise.
1303b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1304b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setSuspendOptimizations(boolean enabled) {
1306b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setSuspendModeEnabled(mInterfaceName, enabled);
1307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
13099153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    /**
1310b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code.
1311b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1312b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode 2 byte ASCII string. For ex: US, CA.
1313b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
13149153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     */
1315b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setCountryCode(String countryCode) {
1316b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setCountryCode(mInterfaceName, countryCode);
131704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    }
131804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang
131904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    /**
1320b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate TDLS discover and setup or teardown with the specified peer.
1321b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1322b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param macAddr MAC Address of the peer.
1323b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enable true to start discovery and setup, false to teardown.
132404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang     */
1325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void startTdls(String macAddr, boolean enable) {
1326b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (enable) {
1327b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsDiscover(mInterfaceName, macAddr);
1328b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsSetup(mInterfaceName, macAddr);
1329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
1330b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsTeardown(mInterfaceName, macAddr);
1331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1334b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1335b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1336b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1337b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1338b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1339b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPbc(String bssid) {
1341b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.startWpsPbc(mInterfaceName, bssid);
1342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1344b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1345b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin keypad operation with the specified pin.
1346b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1347b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1348b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1349b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPinKeypad(String pin) {
1351b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinKeypad(mInterfaceName, pin);
1352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1354b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1355b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1356b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1357b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1358b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return new pin generated on success, null otherwise.
1359b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String startWpsPinDisplay(String bssid) {
1361b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinDisplay(mInterfaceName, bssid);
1362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1364b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1365b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sets whether to use external sim for SIM/USIM processing.
1366b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1367b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param external true to enable, false otherwise.
1368b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1369b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
137033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    public boolean setExternalSim(boolean external) {
1371b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setExternalSim(mInterfaceName, external);
137233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
137333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1374b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1375b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sim auth response types.
1376b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1377b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_GSM_AUTH = "GSM-AUTH";
1378b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTH = "UMTS-AUTH";
1379b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTS = "UMTS-AUTS";
1380b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1381b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1382b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the sim auth response for the currently configured network.
1383b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1384b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type |GSM-AUTH|, |UMTS-AUTH| or |UMTS-AUTS|.
1385b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param response Response params.
1386b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1387b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1388f97140d51d14ce0659d381f443c08dbd94dfea28Honore Tricot    public boolean simAuthResponse(int id, String type, String response) {
1389b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (SIM_AUTH_RESP_TYPE_GSM_AUTH.equals(type)) {
1390b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(
1391b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                    mInterfaceName, response);
1392b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTH.equals(type)) {
1393b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(
1394b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                    mInterfaceName, response);
1395b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTS.equals(type)) {
1396b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAutsResponse(
1397b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                    mInterfaceName, response);
13985cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
1399b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return false;
14005cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
140133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
140233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1403b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1404b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
1405b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1406b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1407b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
140826eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    public boolean simAuthFailedResponse(int id) {
1409b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure(mInterfaceName);
141026eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
141126eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1412b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1413b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim umts auth failure for the currently configured network.
1414b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1415b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1416b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
141726eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    public boolean umtsAuthFailedResponse(int id) {
1418b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure(mInterfaceName);
141926eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
142026eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1421b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1422b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap identity response for the currently configured network.
1423b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1424b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param response String to send.
1425b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1426b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1427ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    public boolean simIdentityResponse(int id, String response) {
1428b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(
1429b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                mInterfaceName, response);
1430ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    }
1431ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot
1432b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1433a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * This get anonymous identity from supplicant and returns it as a string.
1434a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     *
1435a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * @return anonymous identity string if succeeds, null otherwise.
1436a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     */
1437a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    public String getEapAnonymousIdentity() {
1438b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(mInterfaceName);
1439a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    }
1440a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang
1441a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    /**
1442b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
1443b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1444b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1445b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1446b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1447b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsRegistrar(String bssid, String pin) {
1449b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.startWpsRegistrar(mInterfaceName, bssid, pin);
1450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1452b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1453b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels any ongoing WPS requests.
1454b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1455b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1456b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1457155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean cancelWps() {
1458b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.cancelWps(mInterfaceName);
1459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1461b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1462b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device name.
1463b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1464b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param name String to be set.
1465b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1466b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1467155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setDeviceName(String name) {
1468b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceName(mInterfaceName, name);
1469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1471b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1472b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device type.
1473b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1474b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
1475b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1476b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setDeviceType(String type) {
1478b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceType(mInterfaceName, type);
1479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1481b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1482b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS config methods
1483b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1484b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param cfg List of config methods.
1485b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1486b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setConfigMethods(String cfg) {
1488b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsConfigMethods(mInterfaceName, cfg);
1489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1491b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1492b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS manufacturer.
1493b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1494b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1495b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1496b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1497155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setManufacturer(String value) {
1498b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsManufacturer(mInterfaceName, value);
1499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1501b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1502b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model name.
1503b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1504b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1505b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1506b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setModelName(String value) {
1508b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelName(mInterfaceName, value);
1509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1511b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1512b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model number.
1513b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1514b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1515b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1516b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setModelNumber(String value) {
1518b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelNumber(mInterfaceName, value);
1519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1521b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1522b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS serial number.
1523b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1524b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1525b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1526b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setSerialNumber(String value) {
1528b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsSerialNumber(mInterfaceName, value);
1529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1531b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1532b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable power save mode.
1533b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1534b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
1535b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setPowerSave(boolean enabled) {
1537b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        mSupplicantStaIfaceHal.setPowerSave(mInterfaceName, enabled);
1538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1540b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1541b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set concurrency priority between P2P & STA operations.
1542b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1543b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1544b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                            false otherwise.
1545b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1546b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1547b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1548b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mSupplicantStaIfaceHal.setConcurrencyPriority(isStaHigherPriority);
1549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
15523e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * Enable/Disable auto reconnect functionality in wpa_supplicant.
15533e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     *
15543e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @param enable true to enable auto reconnecting, false to disable.
15553e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @return true if request is sent successfully, false otherwise.
15563e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     */
15573e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    public boolean enableStaAutoReconnect(boolean enable) {
1558b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.enableAutoReconnect(mInterfaceName, enable);
15593e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    }
15603e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius
15613e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    /**
1562b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Migrate all the configured networks from wpa_supplicant.
1563b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1564b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
1565b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                      the networks.
1566b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
1567b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Max priority of all the configs.
1568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1569b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean migrateNetworksFromSupplicant(Map<String, WifiConfiguration> configs,
1570b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                                                 SparseArray<Map<String, String>> networkExtras) {
1571b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.loadNetworks(mInterfaceName, configs, networkExtras);
1572155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1573155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1574b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1575b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
1576b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This method does the following:
1577c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the connection request.
1578c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. Remove any existing network in wpa_supplicant(This implicitly triggers disconnect).
1579c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Add a new network to wpa_supplicant.
1580c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Save the provided configuration to wpa_supplicant.
1581c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 5. Select the new network in wpa_supplicant.
1582c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 6. Triggers reconnect command to wpa_supplicant.
1583b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1584b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1585b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1586b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1587a5936a61582404692c6046e3b496d3b1d22a94cbNingyuan Wang    public boolean connectToNetwork(WifiConfiguration configuration) {
1588c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock connection request.
158991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        mWificondControl.abortScan(mInterfaceName);
1590b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.connectToNetwork(mInterfaceName, configuration);
1591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1593b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1594b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
1595b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configuration provided does not match the already configured network, then this triggers
1596b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * a new connection attempt (instead of roam).
1597c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the roam request.
1598c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. First check if we're attempting to connect to the same network as we currently have
1599b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configured.
1600c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Set the new bssid for the network in wpa_supplicant.
1601c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Triggers reassociate command to wpa_supplicant.
1602b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1603b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1604b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1605b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1606b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean roamToNetwork(WifiConfiguration configuration) {
1607c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock roaming request.
160891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        mWificondControl.abortScan(mInterfaceName);
1609b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.roamToNetwork(mInterfaceName, configuration);
1610155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1611155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1612b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1613b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Remove all the networks.
1614b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1615b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1616b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1617b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean removeAllNetworks() {
1618b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.removeAllNetworks(mInterfaceName);
1619155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1620155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1621b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1622b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the BSSID for the currently configured network in wpa_supplicant.
1623b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1624b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if successful, false otherwise.
1625b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1626b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setConfiguredNetworkBSSID(String bssid) {
1627b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setCurrentNetworkBssid(mInterfaceName, bssid);
1628155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1629155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1630b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1631b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate ANQP query.
1632b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1633b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP to be queried
1634b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param anqpIds Set of anqp IDs.
1635b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hs20Subtypes Set of HS20 subtypes.
1636b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
1637b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1638b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean requestAnqp(String bssid, Set<Integer> anqpIds, Set<Integer> hs20Subtypes) {
1639b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || ((anqpIds == null || anqpIds.isEmpty())
1640b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && (hs20Subtypes == null || hs20Subtypes.isEmpty()))) {
16411d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Invalid arguments for ANQP request.");
1642155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
1643155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1644b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Short> anqpIdList = new ArrayList<>();
1645b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        for (Integer anqpId : anqpIds) {
1646b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            anqpIdList.add(anqpId.shortValue());
164761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
1648b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Integer> hs20SubtypeList = new ArrayList<>();
1649b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        hs20SubtypeList.addAll(hs20Subtypes);
1650b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.initiateAnqpQuery(
1651b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                mInterfaceName, bssid, anqpIdList, hs20SubtypeList);
1652155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1653155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1654b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1655b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request a passpoint icon file |filename| from the specified AP |bssid|.
1656b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP
1657b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param fileName name of the icon file
1658b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise
1659b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1660b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean requestIcon(String  bssid, String fileName) {
1661b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || fileName == null) {
16621d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Invalid arguments for Icon request.");
166361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return false;
1664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1665b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.initiateHs20IconQuery(mInterfaceName, bssid, fileName);
1666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1668b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1669b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the currently configured network's WPS NFC token.
1670b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1671b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Hex string corresponding to the WPS NFC token.
1672b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1673ba3f5bc64ef27f2ec0d3eae3f53c633ea9e66268Amin Shaikh    public String getCurrentNetworkWpsNfcConfigurationToken() {
1674b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken(mInterfaceName);
1675155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1676403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1677403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    /** Remove the request |networkId| from supplicant if it's the current network,
1678403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * if the current configured network matches |networkId|.
1679403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     *
1680403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * @param networkId network id of the network to be removed from supplicant.
1681403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     */
1682403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    public void removeNetworkIfCurrent(int networkId) {
1683b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        mSupplicantStaIfaceHal.removeNetworkIfCurrent(mInterfaceName, networkId);
1684403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    }
1685403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1686b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1687b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor HAL operations
1688b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1689af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    /**
1690af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     * Callback to notify vendor HAL death.
1691af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     */
1692af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    public interface VendorHalDeathEventHandler {
1693af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        /**
1694af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         * Invoked when the vendor HAL dies.
1695af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         */
1696af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        void onDeath();
1697af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    }
1698b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1699d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    /**
1700b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Tests whether the HAL is running or not
1701b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
170218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean isHalStarted() {
1703b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.isHalStarted();
17047f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
17057f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1706062e3f39e37874fedc01f267de5f4cf7dbebe2b4Randy Pan    // TODO: Change variable names to camel style.
1707e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanCapabilities {
1708297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_cache_size;
1709e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_scan_buckets;
1710e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_ap_cache_per_scan;
1711e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_rssi_sample_size;
1712297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_reporting_threshold;
1713e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1714e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1715b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1716b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the scan capabilities
1717b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1718b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param capabilities object to be filled in
1719b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success. false for failure
1720b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
17216ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public boolean getBgScanCapabilities(ScanCapabilities capabilities) {
1722d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getBgScanCapabilities(mInterfaceName, capabilities);
1723e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1724e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1725e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ChannelSettings {
1726712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int frequency;
1727712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int dwell_time_ms;
1728712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public boolean passive;
17297f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
17307f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1731e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class BucketSettings {
1732712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int bucket;
1733712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int band;
1734712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int period_ms;
1735712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_period_ms;
1736712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int step_count;
1737712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_events;
1738712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_channels;
1739712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public ChannelSettings[] channels;
1740e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
17417f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
17426259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    /**
17436259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * Network parameters for hidden networks to be scanned for.
17446259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     */
17456259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public static class HiddenNetwork {
17466259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public String ssid;
17476259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
17486259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        @Override
17496259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public boolean equals(Object otherObj) {
17506259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            if (this == otherObj) {
17516259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return true;
17526259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
17536259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return false;
17546259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            }
17556259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            HiddenNetwork other = (HiddenNetwork) otherObj;
17566259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return Objects.equals(ssid, other.ssid);
17576259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        }
1758ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1759ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1760ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1761ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return (ssid == null ? 0 : ssid.hashCode());
1762ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
17636259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    }
17646259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
1765e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanSettings {
1766712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int base_period_ms;
1767712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_ap_per_scan;
1768712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_percent;
1769712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_num_scans;
1770712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_buckets;
17716259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        /* Not used for bg scans. Only works for single scans. */
17726259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public HiddenNetwork[] hiddenNetworks;
1773712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public BucketSettings[] buckets;
1774e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
17757f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
177668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
17779bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Network parameters to start PNO scan.
17789bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
17799bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoNetwork {
17809bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public String ssid;
17819bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public byte flags;
1782ef3ea1092bc17673c0a85a845b053151b7c10e07Roshan Pius        public byte auth_bit_field;
17831bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius
17841bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        @Override
17851bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        public boolean equals(Object otherObj) {
17861bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            if (this == otherObj) {
17871bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return true;
17881bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
17891bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return false;
17901bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            }
17911bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            PnoNetwork other = (PnoNetwork) otherObj;
17926259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return ((Objects.equals(ssid, other.ssid)) && (flags == other.flags)
17931bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                    && (auth_bit_field == other.auth_bit_field));
17941bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        }
1795ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1796ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1797ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1798ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            int result = (ssid == null ? 0 : ssid.hashCode());
1799ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            result ^= ((int) flags * 31) + ((int) auth_bit_field << 8);
1800ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return result;
1801ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
18029bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
18039bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
18049bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
18059bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Parameters to start PNO scan. This holds the list of networks which are going to used for
18069bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * PNO scan.
18079bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
18089bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoSettings {
18099bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min5GHzRssi;
18109bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min24GHzRssi;
18119bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int initialScoreMax;
18129bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int currentConnectionBonus;
18139bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int sameNetworkBonus;
18149bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int secureBonus;
18159bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int band5GHzBonus;
181604c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang        public int periodInMs;
1817dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        public boolean isConnected;
18189bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public PnoNetwork[] networkList;
18199bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
18209bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
1821b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface ScanEventHandler {
182263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
182363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called for each AP as it is found with the entire contents of the beacon/probe response.
182463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Only called when WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT is specified.
182563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
1826c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills        void onFullScanResult(ScanResult fullScanResult, int bucketsScanned);
182763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
182863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Callback on an event during a gscan scan.
182963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * See WifiNative.WIFI_SCAN_* for possible values.
183063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
183163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        void onScanStatus(int event);
183263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
183363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is paused.
183463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
183583a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande        void onScanPaused(WifiScanner.ScanData[] data);
183663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
183763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is resumed.
183863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
1839b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        void onScanRestarted();
1840e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1841e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
18429bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
18439bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Handler to notify the occurrence of various events during PNO scan.
18449bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
18459bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public interface PnoEventHandler {
18469bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        /**
18479bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * Callback to notify when one of the shortlisted networks is found during PNO scan.
18489bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * @param results List of Scan results received.
18499bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         */
18509bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        void onPnoNetworkFound(ScanResult[] results);
1851063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius
1852063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        /**
1853063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         * Callback to notify when the PNO scan schedule fails.
1854063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         */
1855063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        void onPnoScanFailed();
18569bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
18579bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
185871af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
185971af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1;
186071af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2;
186171af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_FAILED = 3;
1862b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande
1863b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1864b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a background scan.
1865b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Any ongoing scan will be stopped first
1866b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1867b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param settings     to control the scan
1868b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param eventHandler to call with the results
1869b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
1870b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
18716ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public boolean startBgScan(ScanSettings settings, ScanEventHandler eventHandler) {
1872d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startBgScan(mInterfaceName, settings, eventHandler);
18737f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
18747f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1875b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1876b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops any ongoing backgound scan
1877b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
18786ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public void stopBgScan() {
1879d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        mWifiVendorHal.stopBgScan(mInterfaceName);
1880b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
1881b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
1882b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1883b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Pauses an ongoing backgound scan
1884b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
18856ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public void pauseBgScan() {
1886d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        mWifiVendorHal.pauseBgScan(mInterfaceName);
1887b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
1888b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
1889b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1890b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Restarts a paused scan
1891b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
18926ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public void restartBgScan() {
1893d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        mWifiVendorHal.restartBgScan(mInterfaceName);
1894e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1895e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1896b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1897b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the latest scan results received.
1898b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
18996ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public WifiScanner.ScanData[] getBgScanResults() {
1900d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getBgScanResults(mInterfaceName);
1901e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1902e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1903d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius    public WifiLinkLayerStats getWifiLinkLayerStats() {
1904d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getWifiLinkLayerStats(mInterfaceName);
19055c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales    }
19065c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
1907b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1908b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the supported features
1909b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1910b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return bitmask defined by WifiManager.WIFI_FEATURE_*
1911b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
191218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedFeatureSet() {
1913d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getSupportedFeatureSet(mInterfaceName);
1914a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    }
1915143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
1916143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public static interface RttEventHandler {
1917143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void onRttResults(RttManager.RttResult[] result);
1918143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
1919143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
1920b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1921b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a new rtt request
1922b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1923b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}.
1924b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked to notify any results.
1925b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if the request was successful, false otherwise.
1926b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
192718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean requestRtt(
1928143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttManager.RttParams[] params, RttEventHandler handler) {
1929b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.requestRtt(params, handler);
1930143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
1931143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
1932b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1933b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels an outstanding rtt request
1934b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1935b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}
1936b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if there was an outstanding request and it was successfully cancelled
1937b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
193818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean cancelRtt(RttManager.RttParams[] params) {
1939b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.cancelRtt(params);
1940143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
1941042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
194268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
194368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder
194468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * role is successfully enabled, {@code null} otherwise.
1945b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1946b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param timeoutSeconds timeout to use for the responder.
194768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
194868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    @Nullable
1949b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public ResponderConfig enableRttResponder(int timeoutSeconds) {
1950b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.enableRttResponder(timeoutSeconds);
195112cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe    }
1952939177ff615062ec826601d536466875d8457375xinhe
1953b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1954b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled,
1955b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * {@code false} otherwise.
1956b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1957b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean disableRttResponder() {
1958b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.disableRttResponder();
19596609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
19606609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
1961b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1962b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the MAC OUI during scanning.
1963b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * An OUI {Organizationally Unique Identifier} is a 24-bit number that
1964b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * uniquely identifies a vendor or manufacturer.
1965b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1966b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param oui OUI to set.
1967b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
1968b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1969b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setScanningMacOui(byte[] oui) {
1970d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.setScanningMacOui(mInterfaceName, oui);
19716609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
19726609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
1973b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1974b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * RTT (Round Trip Time) measurement capabilities of the device.
1975b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1976b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public RttManager.RttCapabilities getRttCapabilities() {
1977b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRttCapabilities();
1978d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
1979d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
1980b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1981b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the APF (Android Packet Filter) capabilities of the device
1982b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1983b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public ApfCapabilities getApfCapabilities() {
1984d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getApfCapabilities(mInterfaceName);
1985d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
1986d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
1987b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1988b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Installs an APF program on this iface, replacing any existing program.
1989b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1990b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param filter is the android packet filter program
1991b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
1992b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1993b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean installPacketFilter(byte[] filter) {
1994d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.installPacketFilter(mInterfaceName, filter);
1995d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
1996d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
1997b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1998b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code for this AP iface.
1999b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2000b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode - two-letter country code (as ISO 3166)
2001b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2002b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2003b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setCountryCodeHal(String countryCode) {
2004d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.setCountryCodeHal(mInterfaceName, countryCode);
2005d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2006d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2007a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    //---------------------------------------------------------------------------------
2008a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    /* Wifi Logger commands/events */
2009a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    public static interface WifiLoggerEventHandler {
20100bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onRingBufferData(RingBufferStatus status, byte[] buffer);
20110bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onWifiAlert(int errorCode, byte[] buffer);
2012a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2013a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2014b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2015b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Registers the logger callback and enables alerts.
2016b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Ring buffer data collection is only triggered when |startLoggingRingBuffer| is invoked.
2017b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2018b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked.
2019b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2020b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
202118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setLoggingEventHandler(WifiLoggerEventHandler handler) {
2022b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.setLoggingEventHandler(handler);
202303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
202403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2025b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2026b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Control debug data collection
2027b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2028b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param verboseLevel 0 to 3, inclusive. 0 stops logging.
2029b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param flags        Ignored.
2030b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxInterval  Maximum interval between reports; ignore if 0.
2031b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minDataSize  Minimum data size in buffer for report; ignore if 0.
2032b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName     Name of the ring for which data collection is to start.
2033b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2034b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
203518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval,
203603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            int minDataSize, String ringName){
2037b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.startLoggingRingBuffer(
2038b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                verboseLevel, flags, maxInterval, minDataSize, ringName);
203903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
204003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2041b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2042b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Logger features exposed.
2043b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This is a no-op now, will always return -1.
2044b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2045b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2046b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
204718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedLoggerFeatureSet() {
2048b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getSupportedLoggerFeatureSet();
204903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
205003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2051b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2052b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops all logging and resets the logger callback.
2053b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This stops both the alerts and ring buffer data collection.
2054b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2055b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
205618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean resetLogHandler() {
2057b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.resetLogHandler();
2058b797893fc1966803d0c013faac42e6396a37a384xinhe    }
2059b797893fc1966803d0c013faac42e6396a37a384xinhe
2060b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2061b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi driver version string
2062b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2063b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
2064b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
206518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getDriverVersion() {
2066b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverVersion();
206703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
206803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2069b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2070b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi firmware version string
2071b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2072b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
2073b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
207418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getFirmwareVersion() {
2075b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFirmwareVersion();
207603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
207703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
20780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static class RingBufferStatus{
20790bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        String name;
20800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int flag;
20810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferId;
20820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferByteSize;
20830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int verboseLevel;
20840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenBytes;
20850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int readBytes;
20860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenRecords;
20870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
208853f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        // Bit masks for interpreting |flag|
208953f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_BINARY_ENTRIES = (1 << 0);
209053f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_ASCII_ENTRIES = (1 << 1);
209153f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_PER_PACKET_ENTRIES = (1 << 2);
209253f278b6fed422a18d763b07216a21e96d9445f9Michael Plass
20930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
20940bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public String toString() {
20950bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
20960bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel +
20970bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenBytes: " + writtenBytes + " readBytes: " + readBytes +
20980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenRecords: " + writtenRecords;
20990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
21000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
21010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2102b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2103b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * API to get the status of all ring buffers supported by driver
2104b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
210518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public RingBufferStatus[] getRingBufferStatus() {
2106b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferStatus();
210703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
210803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2109b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2110b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Indicates to driver that all the data has to be uploaded urgently
2111b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2112b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName Name of the ring buffer requested.
2113b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2114b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
211518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean getRingBufferData(String ringName) {
2116b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferData(ringName);
211703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
2118127f7244183786e6ccae09e81eeccdac31973e69xinhe
2119b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2120b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the firmware
2121b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2122b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2123b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
212418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public byte[] getFwMemoryDump() {
2125b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFwMemoryDump();
2126a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2127dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
2128b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2129b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the driver
2130b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2131b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2132b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2133d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    public byte[] getDriverStateDump() {
2134b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverStateDump();
2135d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    }
2136d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal
2137dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    //---------------------------------------------------------------------------------
213809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /* Packet fate API */
213909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
214009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
214109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    abstract static class FateReport {
2142eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int USEC_PER_MSEC = 1000;
2143eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // The driver timestamp is a 32-bit counter, in microseconds. This field holds the
2144eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // maximal value of a driver timestamp in milliseconds.
2145eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000);
2146eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
2147eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
214809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFate;
214909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final long mDriverTimestampUSec;
215009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFrameType;
215109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte[] mFrameBytes;
2152eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final long mEstimatedWallclockMSec;
215309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
215409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
215509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFate = fate;
215609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mDriverTimestampUSec = driverTimestampUSec;
2157eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            mEstimatedWallclockMSec =
2158eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    convertDriverTimestampUSecToWallclockMSec(mDriverTimestampUSec);
215909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameType = frameType;
216009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameBytes = frameBytes;
216109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
21620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2163590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toTableRowString() {
2164590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2165590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2166590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
2167eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            dateFormatter.setTimeZone(TimeZone.getDefault());
2168eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2169eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    mDriverTimestampUSec,
2170eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    dateFormatter.format(new Date(mEstimatedWallclockMSec)),
2171eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    directionToString(), fateToString(), parser.mMostSpecificProtocolString,
2172eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    parser.mTypeString, parser.mResultString);
2173590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2174590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2175590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
2176590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toVerboseStringWithPiiAllowed() {
21770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            StringWriter sw = new StringWriter();
21780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            PrintWriter pw = new PrintWriter(sw);
2179590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
21800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame direction: %s\n", directionToString());
21810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame timestamp: %d\n", mDriverTimestampUSec);
21820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame fate: %s\n", fateToString());
21830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame type: %s\n", frameTypeToString(mFrameType));
2184590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol: %s\n", parser.mMostSpecificProtocolString);
2185590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol type: %s\n", parser.mTypeString);
21860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame length: %d\n", mFrameBytes.length);
21870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("Frame bytes");
2188590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.append(HexDump.dumpHexString(mFrameBytes));  // potentially contains PII
21890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("\n");
21900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return sw.toString();
21910fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
21920fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2193590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        /* Returns a header to match the output of toTableRowString(). */
2194590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public static String getTableHeader() {
2195590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2196590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2197eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("\n%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2198eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "Time usec", "Walltime", "Direction", "Fate", "Protocol", "Type", "Result");
2199eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2200eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "---------", "--------", "---------", "----", "--------", "----", "------");
2201590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2202590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2203590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
22040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String directionToString();
22050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
22060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String fateToString();
22070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
22080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        private static String frameTypeToString(byte frameType) {
22090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (frameType) {
22100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_UNKNOWN:
22110fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "unknown";
22120fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_ETHERNET_II:
22130fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "data";
22140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_80211_MGMT:
22150fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "802.11 management";
22160fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
22170fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(frameType);
22180fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
22190fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
2220eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2221eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        /**
2222eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * Converts a driver timestamp to a wallclock time, based on the current
2223eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * BOOTTIME to wallclock mapping. The driver timestamp is a 32-bit counter of
2224eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * microseconds, with the same base as BOOTTIME.
2225eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         */
2226eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        private static long convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec) {
2227eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long wallclockMillisNow = System.currentTimeMillis();
2228eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long boottimeMillisNow = SystemClock.elapsedRealtime();
2229eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long driverTimestampMillis = driverTimestampUSec / USEC_PER_MSEC;
2230eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2231eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            long boottimeTimestampMillis = boottimeMillisNow % MAX_DRIVER_TIMESTAMP_MSEC;
2232eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            if (boottimeTimestampMillis < driverTimestampMillis) {
2233eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // The 32-bit microsecond count has wrapped between the time that the driver
2234eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // recorded the packet, and the call to this function. Adjust the BOOTTIME
2235eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // timestamp, to compensate.
2236eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                //
2237eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // Note that overflow is not a concern here, since the result is less than
2238eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // 2 * MAX_DRIVER_TIMESTAMP_MSEC. (Given the modulus operation above,
2239eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // boottimeTimestampMillis must be less than MAX_DRIVER_TIMESTAMP_MSEC.) And, since
2240eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // MAX_DRIVER_TIMESTAMP_MSEC is an int, 2 * MAX_DRIVER_TIMESTAMP_MSEC must fit
2241eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // within a long.
2242eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                boottimeTimestampMillis += MAX_DRIVER_TIMESTAMP_MSEC;
2243eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            }
2244eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2245eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long millisSincePacketTimestamp = boottimeTimestampMillis - driverTimestampMillis;
2246eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            return wallclockMillisNow - millisSincePacketTimestamp;
2247eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        }
224809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
224909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
225009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
225109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one outbound packet.
225209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
225309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
225409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class TxFateReport extends FateReport {
225509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
225609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
225709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
22580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
22590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
22600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
22610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "TX";
22620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
22630fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
22640fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
22650fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
22660fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
22670fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_ACKED:
22680fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "acked";
22690fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_SENT:
22700fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "sent";
22710fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_QUEUED:
22720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
22730fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID:
22740fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
22750fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS:
22760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
22770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER:
22780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
22790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED:
22800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
22810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID:
22820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
22830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS:
22840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
22850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER:
22860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
22870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
22880fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
22890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
22900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
229109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
229209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
229309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
229409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one inbound packet.
229509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
229609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
229709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class RxFateReport extends FateReport {
229809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
229909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
230009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
23010fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23020fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
23030fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
23040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "RX";
23050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
23060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
23080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
23090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
23100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_SUCCESS:
23110fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "success";
23120fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_QUEUED:
23130fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
23140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER:
23150fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (filter)";
23160fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID:
23170fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
23180fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS:
23190fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
23200fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER:
23210fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
23220fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED:
23230fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
23240fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER:
23250fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (filter)";
23260fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID:
23270fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
23280fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS:
23290fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
23300fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER:
23310fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
23320fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
23330fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
23340fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
23350fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
233609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
233709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
23380fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
23390fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Ask the HAL to enable packet fate monitoring. Fails unless HAL is started.
2340b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2341b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
23420fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
23430fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean startPktFateMonitoring() {
2344d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startPktFateMonitoring(mInterfaceName);
23450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
23460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
23480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent TX packet fates from the HAL. Fails unless HAL is started.
2349b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2350b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
23510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
23520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean getTxPktFates(TxFateReport[] reportBufs) {
2353d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getTxPktFates(mInterfaceName, reportBufs);
23540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
23550fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23560fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
23570fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent RX packet fates from the HAL. Fails unless HAL is started.
23580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
23590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean getRxPktFates(RxFateReport[] reportBufs) {
2360d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getRxPktFates(mInterfaceName, reportBufs);
23610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
236209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
23635c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius    /**
2364b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start sending the specified keep alive packets periodically.
2365b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2366b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot Integer used to identify each request.
2367b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param keepAlivePacket Raw packet contents to send.
2368b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param period Period to use for sending these packets.
2369b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2370b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2371b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public int startSendingOffloadedPacket(int slot, KeepalivePacketData keepAlivePacket,
2372b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                                           int period) {
23733bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        String[] macAddrStr = getMacAddress().split(":");
23743bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        byte[] srcMac = new byte[6];
2375520fbe7db055661af039303c1081236c73b04abdRoshan Pius        for (int i = 0; i < 6; i++) {
23763bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham            Integer hexVal = Integer.parseInt(macAddrStr[i], 16);
23773bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham            srcMac[i] = hexVal.byteValue();
23783bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        }
2379d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startSendingOffloadedPacket(mInterfaceName,
2380b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                slot, srcMac, keepAlivePacket, period);
2381c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2382c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
2383b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2384b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop sending the specified keep alive packets.
2385b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2386b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot id - same as startSendingOffloadedPacket call.
2387b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2388b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2389b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public int stopSendingOffloadedPacket(int slot) {
2390d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.stopSendingOffloadedPacket(mInterfaceName, slot);
2391c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2392aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2393aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    public static interface WifiRssiEventHandler {
2394aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        void onRssiThresholdBreached(byte curRssi);
2395aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2396aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2397b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2398b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start RSSI monitoring on the currently connected access point.
2399b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2400b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxRssi          Maximum RSSI threshold.
2401b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minRssi          Minimum RSSI threshold.
2402b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param rssiEventHandler Called when RSSI goes above maxRssi or below minRssi
2403b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for failure
2404b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
240518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int startRssiMonitoring(byte maxRssi, byte minRssi,
2406b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                                   WifiRssiEventHandler rssiEventHandler) {
2407d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startRssiMonitoring(
2408d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius                mInterfaceName, maxRssi, minRssi, rssiEventHandler);
2409aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2410aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
241118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int stopRssiMonitoring() {
2412d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.stopRssiMonitoring(mInterfaceName);
2413aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
24145ea42964ba17901a8d724736b450ace6ed48880fPrerepa Viswanadham
24156bf6986d359556010638dfae332b585162f06520Roshan Pius    /**
24166bf6986d359556010638dfae332b585162f06520Roshan Pius     * Fetch the host wakeup reasons stats from wlan driver.
2417b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
24186bf6986d359556010638dfae332b585162f06520Roshan Pius     * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver.
24196bf6986d359556010638dfae332b585162f06520Roshan Pius     */
24206bf6986d359556010638dfae332b585162f06520Roshan Pius    public WifiWakeReasonAndCounts getWlanWakeReasonCount() {
2421b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getWlanWakeReasonCount();
24226bf6986d359556010638dfae332b585162f06520Roshan Pius    }
24233dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline
2424b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2425b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable/Disable Neighbour discovery offload functionality in the firmware.
2426b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2427b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
2428b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2429b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
24303dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    public boolean configureNeighborDiscoveryOffload(boolean enabled) {
2431d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.configureNeighborDiscoveryOffload(mInterfaceName, enabled);
24323dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    }
2433da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2434da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    // Firmware roaming control.
2435da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2436da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2437da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class to retrieve firmware roaming capability parameters.
2438da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2439da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingCapabilities {
2440da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxBlacklistSize;
2441da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxWhitelistSize;
2442da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2443da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2444da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2445da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Query the firmware roaming capabilities.
2446b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2447da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2448da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public boolean getRoamingCapabilities(RoamingCapabilities capabilities) {
2449d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getRoamingCapabilities(mInterfaceName, capabilities);
2450da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2451da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2452da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2453da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Macros for controlling firmware roaming.
2454da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2455da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int DISABLE_FIRMWARE_ROAMING = 0;
2456da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int ENABLE_FIRMWARE_ROAMING = 1;
2457da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2458da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2459da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Enable/disable firmware roaming.
2460b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2461b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return error code returned from HAL.
2462da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2463da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public int enableFirmwareRoaming(int state) {
2464d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.enableFirmwareRoaming(mInterfaceName, state);
2465da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2466da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2467da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2468da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class for specifying the roaming configurations.
2469da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2470da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingConfig {
2471da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> blacklistBssids;
2472da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> whitelistSsids;
2473da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2474da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2475da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2476da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Set firmware roaming configurations.
2477da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2478da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public boolean configureRoaming(RoamingConfig config) {
24791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        Log.d(TAG, "configureRoaming ");
2480d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.configureRoaming(mInterfaceName, config);
2481da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2482da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2483374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    /**
2484374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     * Reset firmware roaming configuration.
2485374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     */
2486374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    public boolean resetRoamingConfiguration() {
2487b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Pass in an empty RoamingConfig object which translates to zero size
2488b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // blacklist and whitelist to reset the firmware roaming configuration.
2489d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.configureRoaming(mInterfaceName, new RoamingConfig());
2490b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2491b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2492ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2493b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Tx power level scenarios that can be selected.
2494ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2495b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_NORMAL = 0;
2496b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_VOICE_CALL = 1;
2497ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2498ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2499b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Select one of the pre-configured TX power level scenarios or reset it back to normal.
2500ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * Primarily used for meeting SAR requirements during voice calls.
2501ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     *
2502b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * @param scenario Should be one {@link #TX_POWER_SCENARIO_NORMAL} or
2503b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     *        {@link #TX_POWER_SCENARIO_VOICE_CALL}.
2504ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * @return true for success; false for failure or if the HAL version does not support this API.
2505ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2506b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public boolean selectTxPowerScenario(int scenario) {
2507b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius        return mWifiVendorHal.selectTxPowerScenario(scenario);
2508ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    }
2509ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2510b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
2511b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * JNI operations
2512b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
2513b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* Register native functions */
2514b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    static {
2515b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        /* Native functions are defined in libwifi-service.so */
2516b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        System.loadLibrary("wifi-service");
2517b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        registerNatives();
2518b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2519b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2520b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native int registerNatives();
2521b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* kernel logging support */
2522b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native byte[] readKernelLogNative();
2523b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2524b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2525b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetches the latest kernel logs.
2526b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2527b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public synchronized String readKernelLog() {
2528b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        byte[] bytes = readKernelLogNative();
2529b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bytes != null) {
2530b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
2531b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            try {
2532b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
2533b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return decoded.toString();
2534b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            } catch (CharacterCodingException cce) {
2535b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return new String(bytes, StandardCharsets.ISO_8859_1);
2536b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            }
2537520fbe7db055661af039303c1081236c73b04abdRoshan Pius        } else {
2538b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return "*** failed to read kernel log ***";
2539374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        }
2540da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
2542