WifiNative.java revision ef1606e936204c56ffdae305f2f423ee3503fecd
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
19eee8cb8bcecfa3b33ae03f7753359499a274e7a9mukesh agrawalimport android.annotation.NonNull;
2068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.annotation.Nullable;
212a6d76f0899289cd3b96e3428f02076fdbc0363eMitchell Willsimport android.content.Context;
22e1dab7a2e3ab5911f812a302b4beed1f6eb5aba7Paul Jensenimport android.net.apf.ApfCapabilities;
2370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IApInterface;
2470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IClientInterface;
25143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.net.wifi.RttManager;
2668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.net.wifi.RttManager.ResponderConfig;
27e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.ScanResult;
28dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalleimport android.net.wifi.WifiConfiguration;
2918786eca942042388748b0d98979f21c9dff4a89Mitchell Willsimport android.net.wifi.WifiEnterpriseConfig;
30aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalleimport android.net.wifi.WifiLinkLayerStats;
31e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.WifiScanner;
32dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalleimport android.net.wifi.WifiSsid;
332a6d76f0899289cd3b96e3428f02076fdbc0363eMitchell Willsimport android.net.wifi.WifiWakeReasonAndCounts;
34155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.WpsInfo;
35155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pConfig;
36155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pGroup;
3703cdd624f5da6d62cb731304aa7505921566f69dDmitry Shmidtimport android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
38f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.os.SystemClock;
3918786eca942042388748b0d98979f21c9dff4a89Mitchell Willsimport android.os.SystemProperties;
40155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.text.TextUtils;
41155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.util.LocalLog;
42155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.util.Log;
43a26a8b33616c94859ba33f33403794cf636baa54Roshan Piusimport android.util.SparseArray;
44fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
4509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawalimport com.android.internal.annotations.Immutable;
46e3831b70d4a8a967fe8df5496d542a432692c434Roshan Piusimport com.android.internal.annotations.VisibleForTesting;
470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport com.android.internal.util.HexDump;
48c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadhamimport com.android.server.connectivity.KeepalivePacketData;
492afa54e3c8fa1153302a0d57b0e9b7bee35406ffMitchell Willsimport com.android.server.wifi.hotspot2.Utils;
50590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tanimport com.android.server.wifi.util.FrameParser;
515d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Willsimport com.android.server.wifi.util.InformationElementUtil;
5238a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Piusimport com.android.server.wifi.util.NativeUtil;
53c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
5418786eca942042388748b0d98979f21c9dff4a89Mitchell Willsimport libcore.util.HexEncoding;
5518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
56fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport org.json.JSONException;
57fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport org.json.JSONObject;
58fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport java.io.PrintWriter;
600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport java.io.StringWriter;
61fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.io.UnsupportedEncodingException;
62fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.net.URLDecoder;
63fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.net.URLEncoder;
645cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.ByteBuffer;
655cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.CharBuffer;
665cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.CharacterCodingException;
675cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.CharsetDecoder;
685cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.StandardCharsets;
69eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.text.SimpleDateFormat;
70155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.ArrayList;
713571366ac36c70746b9f013ec2b54482861c9292Randy Panimport java.util.BitSet;
72eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.util.Date;
73fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.util.HashMap;
74fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.util.Iterator;
75155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.List;
76155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.Locale;
77fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.util.Map;
781bf983a4211f547593a60523e43112ecdb5c8997Roshan Piusimport java.util.Objects;
799ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.Set;
80eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.util.TimeZone;
8118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
82fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
83155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/**
84155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Native calls for bring up/shut down of the supplicant daemon and for
85155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * sending requests to the supplicant daemon
86155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
87155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * waitForEvent() is called on the monitor thread for events. All other methods
88155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * must be serialized from the framework.
89155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
90155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * {@hide}
91155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
92155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepublic class WifiNative {
93b66b29a00da970ee75052e24f592c8d6c16bd0edxinhe    private static boolean DBG = false;
94155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
950fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    // Must match wifi_hal.h
960fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public static final int WIFI_SUCCESS = 0;
970fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
9818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /**
9918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * Hold this lock before calling supplicant or HAL methods
10018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * it is required to mutually exclude access to the driver
10118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
102956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public static final Object sLock = new Object();
103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
10415941215e85f924765f00779e9b5daff9ed6f118Randy Pan    private static final LocalLog sLocalLog = new LocalLog(8192);
105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
106eee8cb8bcecfa3b33ae03f7753359499a274e7a9mukesh agrawal    public @NonNull LocalLog getLocalLog() {
107956f54b391677d78379729dd14518edddf3c7660Etan Cohen        return sLocalLog;
10818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Register native functions */
111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static {
112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Native functions are defined in libwifi-service.so */
113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        System.loadLibrary("wifi-service");
114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        registerNatives();
115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static native int registerNatives();
118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
11918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /*
12018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * Singleton WifiNative instances
121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
12218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static WifiNative wlanNativeInterface =
123c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang            new WifiNative(SystemProperties.get("wifi.interface", "wlan0"), true);
12418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static WifiNative getWlanNativeInterface() {
12518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return wlanNativeInterface;
12618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
128c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang    private static WifiNative p2pNativeInterface =
129c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang            // commands for p2p0 interface don't need prefix
130c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang            new WifiNative(SystemProperties.get("wifi.direct.interface", "p2p0"), false);
13118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static WifiNative getP2pNativeInterface() {
13218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return p2pNativeInterface;
13318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
136d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    // TODO(b/34884202): Set this to true to enable HIDL once we're fully ready.
137d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    private static final boolean HIDL_ENABLE = false;
13824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    public static final boolean HIDL_SUP_ENABLE = false;
13918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final String mTAG;
14018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final String mInterfaceName;
14118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final String mInterfacePrefix;
142b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    private SupplicantStaIfaceHal mSupplicantStaIfaceHal;
14379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private SupplicantP2pIfaceHal mSupplicantP2pIfaceHal;
1448c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    private WifiVendorHal mWifiVendorHal;
14570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    private WificondControl mWificondControl;
146a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    private WifiSupplicantControl mWifiSupplicantControl;
14718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
14818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private Context mContext = null;
14918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void initContext(Context context) {
15018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (mContext == null && context != null) {
15118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            mContext = context;
15218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        }
15318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
155240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
156b4419d876beda78c29836726e43d80203b4a656cRoshan Pius     * Explicitly sets the SupplicantStaIfaceHal instance
157240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * TODO(b/34722734): move this into the constructor of WifiNative when I clean up the awful
158240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * double singleton pattern
159240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     */
160b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    public void setSupplicantStaIfaceHal(SupplicantStaIfaceHal wifiSupplicantHal) {
161b4419d876beda78c29836726e43d80203b4a656cRoshan Pius        mSupplicantStaIfaceHal = wifiSupplicantHal;
162240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
163240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1648c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    /**
16570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang     * Explicitly sets the WificondControl instance
16670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang     * TODO(b/34722734): move this into the constructor of WifiNative when I clean up the awful
16770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang     * double singleton pattern
16870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang     */
16970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public void setWificondControl(WificondControl wificondControl) {
17070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        mWificondControl = wificondControl;
17170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
17270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
17379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    /** Explicitly sets the SupplicantP2pIfaceHal instance
17479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     * TODO(b/34722734): move this into the constructor of WifiNative when I clean up the awful
17579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     * double singleton pattern
17679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     */
17779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    public void setSupplicantP2pIfaceHal(SupplicantP2pIfaceHal wifiSupplicantHal) {
17879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        mSupplicantP2pIfaceHal = wifiSupplicantHal;
17979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
18079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
18179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
182a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /** Explicitly sets the WifiSupplicantControl instance
183a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * TODO(b/34722734): move this into the constructor of WifiNative when I clean up the awful
184a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * double singleton pattern
185a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
186a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public void setWifiSupplicantControl(WifiSupplicantControl wifiSupplicantControl) {
187a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        mWifiSupplicantControl = wifiSupplicantControl;
188a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
189a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
19070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
1918c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     * Explicitly sets the WifiVendorHal instance
1928c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     * TODO(b/34722734): move this into the constructor of WifiNative when I clean up the awful
1938c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     * double singleton pattern
1948c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
1958c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    public void setWifiVendorHal(WifiVendorHal wifiVendorHal) {
1968c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius        mWifiVendorHal = wifiVendorHal;
1978c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
1988c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
199c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang    private WifiNative(String interfaceName,
200c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang                       boolean requiresPrefix) {
201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mInterfaceName = interfaceName;
202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mTAG = "WifiNative-" + interfaceName;
203e26ad459b63271548abbdeba4f8d77fcca9f88bdxinhe
204c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang        if (requiresPrefix) {
205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mInterfacePrefix = "IFNAME=" + interfaceName + " ";
206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mInterfacePrefix = "";
208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
211240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
2128c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     * Initializes the vendor HAL. This is just used to initialize the {@link HalDeviceManager}.
2138c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
2148c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    public boolean initializeVendorHal() {
215d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius        if (!HIDL_ENABLE) {
216d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius            return true;
217d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius        }
2188c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius        return mWifiVendorHal.initialize();
2198c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
2208c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
22118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getInterfaceName() {
22218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return mInterfaceName;
223e26ad459b63271548abbdeba4f8d77fcca9f88bdxinhe    }
224e26ad459b63271548abbdeba4f8d77fcca9f88bdxinhe
22518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Note this affects logging on for all interfaces
226ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    void enableVerboseLogging(int verbose) {
227ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        if (verbose > 0) {
228ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            DBG = true;
229ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        } else {
230ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            DBG = false;
231ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        }
2322e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang        if (mWificondControl != null) {
2332e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang            mWificondControl.enableVerboseLogging(verbose > 0 ? true : false);
2342e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang        }
2355cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (mSupplicantStaIfaceHal != null) {
2365cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            mSupplicantStaIfaceHal.enableVerboseLogging(verbose > 0);
2375cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
238ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    }
239ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle
24018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private void localLog(String s) {
241956f54b391677d78379729dd14518edddf3c7660Etan Cohen        if (sLocalLog != null) sLocalLog.log(mInterfaceName + ": " + s);
24218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
24470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang   /**
24570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Setup driver for client mode via wificond.
24670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return An IClientInterface as wificond client interface binder handler.
24770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Returns null on failure.
24870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
24970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public IClientInterface setupDriverForClientMode() {
25070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        IClientInterface clientInterface = mWificondControl.setupDriverForClientMode();
25170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        if (!startHal(true)) {
25270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang            // TODO(b/34859006): Handle failures.
25370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang            Log.e(TAG, "Failed to start HAL for client mode");
25470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        }
25570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return clientInterface;
25670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
25870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
25970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Setup driver for softAp mode via wificond.
26070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return An IApInterface as wificond Ap interface binder handler.
26170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Returns null on failure.
26270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
26370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public IApInterface setupDriverForSoftApMode() {
26470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        IApInterface apInterface = mWificondControl.setupDriverForSoftApMode();
26570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
26670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        if (!startHal(false)) {
26770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang            // TODO(b/34859006): Handle failures.
26870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang            Log.e(TAG, "Failed to start HAL for AP mode");
26970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        }
27070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return apInterface;
27170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
27270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
27370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
27470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Teardown all interfaces configured in wificond.
27570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return Returns true on success.
27670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
27770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public boolean tearDownInterfaces() {
27870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return mWificondControl.tearDownInterfaces();
27970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
28070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
28170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
28270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Disable wpa_supplicant via wificond.
28370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return Returns true on success.
28470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
28570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public boolean disableSupplicant() {
28670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return mWificondControl.disableSupplicant();
28770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
28870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
28970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
29070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Enable wpa_supplicant via wificond.
29170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return Returns true on success.
29270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
29370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public boolean enableSupplicant() {
29470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return mWificondControl.enableSupplicant();
29570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
29618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
297d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
298d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Request signal polling to wificond.
299d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns an SignalPollResult object.
300d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns null on failure.
301d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    */
302d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public SignalPollResult signalPoll() {
303d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        return mWificondControl.signalPoll();
304d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
305d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
306d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
307d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * Fetch TX packet counters on current connection from wificond.
308d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns an TxPacketCounters object.
309d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns null on failure.
310d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    */
311d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public TxPacketCounters getTxPacketCounters() {
312d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        return mWificondControl.getTxPacketCounters();
313d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
314d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
31518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /*
316bc582fdbca0d2099139f9790c7d0e1f9b55b0214Christopher Wiley     * Supplicant management
31718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
31818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native static boolean connectToSupplicantNative();
31924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
32024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * This method is called repeatedly until the connection to wpa_supplicant is established.
32124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     *
32224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * @return true if connection is established, false otherwise.
32324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean connectToSupplicant() {
32524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        if (HIDL_SUP_ENABLE) {
32624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            // Start initialization if not already started.
32724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            if (!mSupplicantP2pIfaceHal.isInitializationStarted()
32824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                    && !mSupplicantP2pIfaceHal.initialize()) {
32924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                return false;
33024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            }
33124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            if (!mSupplicantStaIfaceHal.isInitializationStarted()
33224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                    && !mSupplicantStaIfaceHal.initialize()) {
33324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                return false;
33424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            }
33524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            // Check if the initialization is complete.
33624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            return (mSupplicantP2pIfaceHal.isInitializationComplete()
33724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                    && mSupplicantStaIfaceHal.isInitializationComplete());
33824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        } else {
33924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            synchronized (sLock) {
34024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                localLog(mInterfacePrefix + "connectToSupplicant");
34124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                return connectToSupplicantNative();
34224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            }
343b577f391af2c484e443c19b3df1d62cc0924692aVinit Deshpande        }
344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
34618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native static void closeSupplicantConnectionNative();
347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void closeSupplicantConnection() {
34824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        if (HIDL_SUP_ENABLE) {
34924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            // Nothing to do for HIDL.
35024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        } else {
35124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            synchronized (sLock) {
35224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                localLog(mInterfacePrefix + "closeSupplicantConnection");
35324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                closeSupplicantConnectionNative();
35424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            }
355b577f391af2c484e443c19b3df1d62cc0924692aVinit Deshpande        }
356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
35818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /**
35918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * Wait for the supplicant to send an event, returning the event string.
36018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * @return the event string sent by the supplicant.
36118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
36218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native static String waitForEventNative();
363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String waitForEvent() {
364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // No synchronization necessary .. it is implemented in WifiMonitor
365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return waitForEventNative();
366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
36818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
36918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /*
37018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * Supplicant Command Primitives
37118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
37218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native boolean doBooleanCommandNative(String command);
37318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
37418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native int doIntCommandNative(String command);
37518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
37618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native String doStringCommandNative(String command);
37718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean doBooleanCommand(String command) {
379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) Log.d(mTAG, "doBoolean: " + command);
380956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
38118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            String toLog = mInterfacePrefix + command;
382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            boolean result = doBooleanCommandNative(mInterfacePrefix + command);
3837b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            localLog(toLog + " -> " + result);
3840888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            if (DBG) Log.d(mTAG, command + ": returned " + result);
385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return result;
386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
389a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham    private boolean doBooleanCommandWithoutLogging(String command) {
390a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham        if (DBG) Log.d(mTAG, "doBooleanCommandWithoutLogging: " + command);
391956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
392a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham            boolean result = doBooleanCommandNative(mInterfacePrefix + command);
393a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham            if (DBG) Log.d(mTAG, command + ": returned " + result);
394a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham            return result;
395a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham        }
396a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham    }
397a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham
398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int doIntCommand(String command) {
399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) Log.d(mTAG, "doInt: " + command);
400956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
40118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            String toLog = mInterfacePrefix + command;
402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int result = doIntCommandNative(mInterfacePrefix + command);
4037b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            localLog(toLog + " -> " + result);
404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) Log.d(mTAG, "   returned " + result);
405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return result;
406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String doStringCommand(String command) {
4100888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        if (DBG) {
4110888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            //GET_NETWORK commands flood the logs
4120888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            if (!command.startsWith("GET_NETWORK")) {
4130888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle                Log.d(mTAG, "doString: [" + command + "]");
4140888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            }
4150888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        }
416956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
41718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            String toLog = mInterfacePrefix + command;
418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String result = doStringCommandNative(mInterfacePrefix + command);
41940ff222cec1bd05879edb53abc75c6deead734cavandwalle            if (result == null) {
42040ff222cec1bd05879edb53abc75c6deead734cavandwalle                if (DBG) Log.d(mTAG, "doStringCommandNative no result");
42140ff222cec1bd05879edb53abc75c6deead734cavandwalle            } else {
4227b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                if (!command.startsWith("STATUS-")) {
4237b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    localLog(toLog + " -> " + result);
4247b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                }
42540ff222cec1bd05879edb53abc75c6deead734cavandwalle                if (DBG) Log.d(mTAG, "   returned " + result.replace("\n", " "));
42640ff222cec1bd05879edb53abc75c6deead734cavandwalle            }
427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return result;
428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String doStringCommandWithoutLogging(String command) {
4320888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        if (DBG) {
4330888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            //GET_NETWORK commands flood the logs
4340888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            if (!command.startsWith("GET_NETWORK")) {
4350888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle                Log.d(mTAG, "doString: [" + command + "]");
4360888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            }
43727355a942653264388e909a4276196ee63e57811vandwalle        }
438956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doStringCommandNative(mInterfacePrefix + command);
440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
44318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String doCustomSupplicantCommand(String command) {
44418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return doStringCommand(command);
44518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
44618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
447f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius
44818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /*
44918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * Wrappers for supplicant commands
45018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
451f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    /**
452f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius     * Set supplicant log level
453f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius     *
454f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius     * @param turnOnVerbose Whether to turn on verbose logging or not.
455f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius     */
456f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    public void setSupplicantLogLevel(boolean turnOnVerbose) {
4575cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
4585cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            int logLevel = turnOnVerbose
4595cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    ? SupplicantStaIfaceHal.LOG_LEVEL_DEBUG
4605cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    : SupplicantStaIfaceHal.LOG_LEVEL_INFO;
4615cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            mSupplicantStaIfaceHal.setLogLevel(logLevel);
4625cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
4635cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            doStringCommand("LOG_LEVEL " + (turnOnVerbose ? "DEBUG" : "INFO"));
4645cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
465ad7319939c424d42fa6a3791c47f613db8ef3cd8vandwalle    }
466ad7319939c424d42fa6a3791c47f613db8ef3cd8vandwalle
4676259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    /*
4686259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * Convert string to Hexadecimal before passing to wifi native layer
4696259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * In native function "doCommand()" have trouble in converting Unicode character string to UTF8
4706259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * conversion to hex is required because SSIDs can have space characters in them;
4716259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * and that can confuses the supplicant because it uses space charaters as delimiters
4726259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     */
4736259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public static String encodeSSID(String ssid) {
4746259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        int length = ssid.length();
4756259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        if ((length > 1) && (ssid.charAt(0) == '"')
4766259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                && (ssid.charAt(length - 1) == '"')) {
4776259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            ssid = ssid.substring(1, length - 1);
4786259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        }
4796259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        return Utils.toHex(ssid.getBytes(StandardCharsets.UTF_8));
4806259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    }
4816259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
4823d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius    /**
483ed6a985c7b63e295248fa7e8292c99b48b7a4283Mitchell Wills     * Start a scan using wpa_supplicant for the given frequencies.
4843d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius     * @param freqs list of frequencies to scan for, if null scan all supported channels.
4856259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
486ed6a985c7b63e295248fa7e8292c99b48b7a4283Mitchell Wills     */
4876259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public boolean scan(Set<Integer> freqs, Set<String> hiddenNetworkSSIDs) {
4883d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        String freqList = null;
4896259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        String hiddenNetworkSSIDList = null;
4903d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        if (freqs != null && freqs.size() != 0) {
4917e1082bec4d42fdb4fc92061c7041826218eff1cNingyuan Wang            freqList = TextUtils.join(",", freqs);
4923d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        }
4936259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        if (hiddenNetworkSSIDs != null && hiddenNetworkSSIDs.size() != 0) {
4946259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            StringBuilder ssidList = new StringBuilder();
4956259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            for (String ssid : hiddenNetworkSSIDs) {
4966259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                ssidList.append(encodeSSID(ssid)).append(" ");
4976259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            }
4986259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            hiddenNetworkSSIDList = ssidList.toString();
4999ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills        }
5006259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        return scanWithParams(freqList, hiddenNetworkSSIDList);
5019ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills    }
5029ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills
5036259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    private boolean scanWithParams(String freqList, String hiddenNetworkSSIDList) {
5043d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        StringBuilder scanCommand = new StringBuilder();
5053d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        scanCommand.append("SCAN TYPE=ONLY");
5063d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        if (freqList != null) {
5073d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius            scanCommand.append(" freq=" + freqList);
5083d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        }
5096259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        if (hiddenNetworkSSIDList != null) {
5106259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            scanCommand.append(" ssid " + hiddenNetworkSSIDList);
511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5123d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        return doBooleanCommand(scanCommand.toString());
513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Does a graceful shutdown of supplicant. Is a common stop function for both p2p and sta.
516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Note that underneath we use a harsh-sounding "terminate" supplicant command
518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * for a graceful stop and a mild-sounding "stop" interface
519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * to kill the process
520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean stopSupplicant() {
522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("TERMINATE");
523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String listNetworks() {
526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doStringCommand("LIST_NETWORKS");
527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
529e3939cb40d9ba3842be105a6e85172dc06e14758Vinit Deshpande    public String listNetworks(int last_id) {
530e3939cb40d9ba3842be105a6e85172dc06e14758Vinit Deshpande        return doStringCommand("LIST_NETWORKS LAST_ID=" + last_id);
531e3939cb40d9ba3842be105a6e85172dc06e14758Vinit Deshpande    }
532e3939cb40d9ba3842be105a6e85172dc06e14758Vinit Deshpande
533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public int addNetwork() {
534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doIntCommand("ADD_NETWORK");
535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
537fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski    public boolean setNetworkExtra(int netId, String name, Map<String, String> values) {
538e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius        String encoded = createNetworkExtra(values);
539e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius        if (encoded == null) {
540e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius            return false;
541e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius        }
54238a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius        return setNetworkVariable(netId, name, "\"" + encoded + "\"");
543e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    }
544e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius
545e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    @VisibleForTesting
546e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    public static String createNetworkExtra(Map<String, String> values) {
547fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        final String encoded;
548fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        try {
549fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            encoded = URLEncoder.encode(new JSONObject(values).toString(), "UTF-8");
550fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        } catch (NullPointerException e) {
551fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
552e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius            return null;
553fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        } catch (UnsupportedEncodingException e) {
554fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
555e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius            return null;
556fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        }
55738a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius        return encoded;
558fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski    }
559fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setNetworkVariable(int netId, String name, String value) {
561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(value)) return false;
562a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham        if (name.equals(WifiConfiguration.pskVarName)
563f20f5757ad97c9e2cf3920ff7e861358a576053bzhangshuxiao                || name.equals(WifiEnterpriseConfig.PASSWORD_KEY)
564f20f5757ad97c9e2cf3920ff7e861358a576053bzhangshuxiao                || name.equals(WifiEnterpriseConfig.IDENTITY_KEY)
565f20f5757ad97c9e2cf3920ff7e861358a576053bzhangshuxiao                || name.equals(WifiEnterpriseConfig.ANON_IDENTITY_KEY)) {
566a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham            return doBooleanCommandWithoutLogging("SET_NETWORK " + netId + " " + name + " " + value);
567a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham        } else {
568a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham            return doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value);
569a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham        }
570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
571155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
572fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski    public Map<String, String> getNetworkExtra(int netId, String name) {
573e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius        final String extraString = getNetworkVariable(netId, name);
57438a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius        if (extraString == null || !extraString.startsWith("\"") || !extraString.endsWith("\"")) {
57538a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius            return null;
57638a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius        }
57738a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius        return parseNetworkExtra(NativeUtil.removeEnclosingQuotes(extraString));
578e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    }
579e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius
58038a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius    /**
58138a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius     * Parse the network extra JSON encoded string to a map of string key, value pairs.
58238a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius     */
58338a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius    public static Map<String, String> parseNetworkExtra(String encoded) {
58438a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius        if (TextUtils.isEmpty(encoded)) {
585fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            return null;
586fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        }
587fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        try {
588fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // This method reads a JSON dictionary that was written by setNetworkExtra(). However,
589fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // on devices that upgraded from Marshmallow, it may encounter a legacy value instead -
590fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // an FQDN stored as a plain string. If such a value is encountered, the JSONObject
591fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // constructor will thrown a JSONException and the method will return null.
592fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            final JSONObject json = new JSONObject(URLDecoder.decode(encoded, "UTF-8"));
593bc582fdbca0d2099139f9790c7d0e1f9b55b0214Christopher Wiley            final Map<String, String> values = new HashMap<>();
594fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            final Iterator<?> it = json.keys();
595fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            while (it.hasNext()) {
596fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski                final String key = (String) it.next();
597fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski                final Object value = json.get(key);
598fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski                if (value instanceof String) {
599fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski                    values.put(key, (String) value);
600fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski                }
601fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            }
602fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            return values;
603fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        } catch (UnsupportedEncodingException e) {
60464697f7a5b9c1c39f8c9d9c225b8ca4c798422c2Samuel Tan            Log.e(TAG, "Unable to deserialize networkExtra: " + e.toString());
605fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            return null;
606fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        } catch (JSONException e) {
607fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // This is not necessarily an error. This exception will also occur if we encounter a
608fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // legacy FQDN stored as a plain string. We want to return null in this case as no JSON
609fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // dictionary of extras was found.
610fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            return null;
611fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        }
612fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski    }
613fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String getNetworkVariable(int netId, String name) {
615155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(name)) return null;
616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // GET_NETWORK will likely flood the logs ...
618155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doStringCommandWithoutLogging("GET_NETWORK " + netId + " " + name);
619155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
620155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
621155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean removeNetwork(int netId) {
622155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("REMOVE_NETWORK " + netId);
623155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
624155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
625f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    private void logDbg(String debug) {
626f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        long now = SystemClock.elapsedRealtimeNanos();
627f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        String ts = String.format("[%,d us] ", now/1000);
628ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle        Log.e("WifiNative: ", ts+debug+ " stack:"
629ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                + Thread.currentThread().getStackTrace()[2].getMethodName() +" - "
630ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                + Thread.currentThread().getStackTrace()[3].getMethodName() +" - "
631ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                + Thread.currentThread().getStackTrace()[4].getMethodName() +" - "
632ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                + Thread.currentThread().getStackTrace()[5].getMethodName()+" - "
633ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                + Thread.currentThread().getStackTrace()[6].getMethodName());
634f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
635f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
6369d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius
6379d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius    /**
6389d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     * Select a network in wpa_supplicant (Disables all others).
6399d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     * @param netId - Network ID of the network to be selected.
6409d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     * @return true if command succeeded, false otherwise.
6419d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     */
6420047ccf563baa288777e06c6fe95d3681fcf5ccdVinit Deshpande    public boolean selectNetwork(int netId) {
6430047ccf563baa288777e06c6fe95d3681fcf5ccdVinit Deshpande        if (DBG) logDbg("selectNetwork nid=" + Integer.toString(netId));
6440047ccf563baa288777e06c6fe95d3681fcf5ccdVinit Deshpande        return doBooleanCommand("SELECT_NETWORK " + netId);
6450047ccf563baa288777e06c6fe95d3681fcf5ccdVinit Deshpande    }
6460047ccf563baa288777e06c6fe95d3681fcf5ccdVinit Deshpande
647155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean reconnect() {
648f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (DBG) logDbg("RECONNECT ");
6495cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
6505cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.reconnect();
6515cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
6525cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("RECONNECT");
6535cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
654155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
655155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
656155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean reassociate() {
657f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (DBG) logDbg("REASSOCIATE ");
6585cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
6595cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.reassociate();
6605cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
6615cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("REASSOCIATE");
6625cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
663155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
665155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean disconnect() {
66621bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle        if (DBG) logDbg("DISCONNECT ");
6675cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
6685cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.disconnect();
6695cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
6705cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DISCONNECT");
6715cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
672155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
673155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String status() {
67599d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle        return status(false);
676155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
677155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
67899d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle    public String status(boolean noEvents) {
67999d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle        if (noEvents) {
68099d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle            return doStringCommand("STATUS-NO_EVENTS");
68199d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle        } else {
68299d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle            return doStringCommand("STATUS");
68399d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle        }
68499d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle    }
68599d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle
686155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String getMacAddress() {
6875cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
6885cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.getMacAddress();
6895cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
6905cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            //Macaddr = XX.XX.XX.XX.XX.XX
6915cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            String ret = doStringCommand("DRIVER MACADDR");
6925cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (!TextUtils.isEmpty(ret)) {
6935cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                String[] tokens = ret.split(" = ");
6945cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                if (tokens.length == 2) return tokens[1];
6955cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
6965cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return null;
697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
7018631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang    * Fetch the latest scan result from kernel via wificond.
7028631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang    * @return Returns an ArrayList of ScanDetail.
7038631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang    * Returns an empty ArrayList on failure.
7048631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang    */
7052afa54e3c8fa1153302a0d57b0e9b7bee35406ffMitchell Wills    public ArrayList<ScanDetail> getScanResults() {
7068631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang        return mWificondControl.getScanResults();
70777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
70877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
710446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * Format of result:
711446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * id=1016
712446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * bssid=00:03:7f:40:84:10
713446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * freq=2462
714446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * beacon_int=200
715446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * capabilities=0x0431
716446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * qual=0
717446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * noise=0
718446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * level=-46
719446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * tsf=0000002669008476
720446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * age=5
721446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * ie=00105143412d485332302d52322d54455354010882848b960c12182403010b0706555...
722446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * flags=[WPA2-EAP-CCMP][ESS][P2P][HS20]
723446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * ssid=QCA-HS20-R2-TEST
724446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * p2p_device_name=
72556d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle     * p2p_config_methods=0x0SET_NE
726446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_venue_name=02083d656e6757692d466920416c6c69616e63650a3239383920436f...
727446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_network_auth_type=010000
728446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_roaming_consortium=03506f9a05001bc504bd
729446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_ip_addr_type_availability=0c
730446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_nai_realm=0200300000246d61696c2e6578616d706c652e636f6d3b636973636f2...
731446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_3gpp=000600040132f465
732446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_domain_name=0b65786d61706c652e636f6d
733446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * hs20_operator_friendly_name=11656e6757692d466920416c6c69616e63650e636869...
734446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * hs20_wan_metrics=01c40900008001000000000a00
735446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * hs20_connection_capability=0100000006140001061600000650000106bb010106bb0...
736446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * hs20_osu_providers_list=0b5143412d4f53552d425353010901310015656e6757692d...
737446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     */
738446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    public String scanResult(String bssid) {
739446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng        return doStringCommand("BSS " + bssid);
740446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    }
741446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng
742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V4 packets
744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Multicast filtering rules work as follows:
747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * a power optimized mode (typically when screen goes off).
750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-ADD Num
755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and DRIVER RXFILTER-START
758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to stop the usage of these rules, we do
759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-STOP
761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-REMOVE Num
762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num is as described for RXFILTER-ADD
763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The  SETSUSPENDOPT driver command overrides the filtering rules
765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startFilteringMulticastV4Packets() {
7675cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
7685cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.stopRxFilter()
7695cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.removeRxFilter(
7705cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    SupplicantStaIfaceHal.RX_FILTER_TYPE_V4_MULTICAST)
7715cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.stopRxFilter();
7725cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
7735cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DRIVER RXFILTER-STOP")
7745cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-REMOVE 2")
7755cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-START");
7765cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V4 packets.
781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean stopFilteringMulticastV4Packets() {
7845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
7855cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.stopRxFilter()
7865cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.addRxFilter(
7875cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    SupplicantStaIfaceHal.RX_FILTER_TYPE_V4_MULTICAST)
7885cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.stopRxFilter();
7895cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
7905cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DRIVER RXFILTER-STOP")
7915cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-ADD 2")
7925cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-START");
7935cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
795155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
796155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
797155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V6 packets
798155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
799155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
800155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startFilteringMulticastV6Packets() {
8015cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8025cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.stopRxFilter()
8035cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.removeRxFilter(
8045cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    SupplicantStaIfaceHal.RX_FILTER_TYPE_V6_MULTICAST)
8055cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.stopRxFilter();
8065cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
8075cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DRIVER RXFILTER-STOP")
8085cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-REMOVE 3")
8095cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-START");
8105cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
814155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V6 packets.
815155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
816155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
817155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean stopFilteringMulticastV6Packets() {
8185cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8195cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.stopRxFilter()
8205cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.addRxFilter(
8215cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    SupplicantStaIfaceHal.RX_FILTER_TYPE_V6_MULTICAST)
8225cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.stopRxFilter();
8235cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
8245cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DRIVER RXFILTER-STOP")
8255cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-ADD 3")
8265cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-START");
8275cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
829155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
83018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED     = 0;
83118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED    = 1;
83218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static final int BLUETOOTH_COEXISTENCE_MODE_SENSE       = 2;
8337ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    /**
8347ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * Sets the bluetooth coexistence mode.
8357ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *
8367ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
8377ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
8387ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
8397ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * @return Whether the mode was successfully set.
8407ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      */
841155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setBluetoothCoexistenceMode(int mode) {
8425cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8435cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setBtCoexistenceMode((byte) mode);
8445cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
8455cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
8465cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
848155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
850155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
851155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * some of the low-level scan parameters used by the driver are changed to
852155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * reduce interference with A2DP streaming.
853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
854cc180872c51908b15ce5cbf834634ff323e036bcChristopher Wiley     * @param setCoexScanMode whether to enable or disable this mode
855155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the command succeeded, {@code false} otherwise.
856155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
857155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
8585cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8595cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setBtCoexistenceScanModeEnabled(setCoexScanMode);
860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
8615cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (setCoexScanMode) {
8625cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER BTCOEXSCAN-START");
8635cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
8645cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER BTCOEXSCAN-STOP");
8655cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
866155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
867155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
868155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
869155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setSuspendOptimizations(boolean enabled) {
8705cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8715cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setSuspendModeEnabled(enabled);
872155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
8735cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (enabled) {
8745cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER SETSUSPENDMODE 1");
8755cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
8765cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER SETSUSPENDMODE 0");
8775cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
878155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
879155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
880155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
881155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setCountryCode(String countryCode) {
8825cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8835cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setCountryCode(countryCode);
8845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
8855cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (countryCode != null) {
8865cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER COUNTRY " + countryCode.toUpperCase(Locale.ROOT));
8875cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
8885cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER COUNTRY");
8895cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
8905cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
891155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
892155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8939153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    /**
8949153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     * Start/Stop PNO scan.
8959153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     * @param enable boolean indicating whether PNO is being enabled or disabled.
8969153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     */
8979153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    public boolean setPnoScan(boolean enable) {
8989153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius        String cmd = enable ? "SET pno 1" : "SET pno 0";
8999153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius        return doBooleanCommand(cmd);
9009153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    }
901ac9ad3283508db15b65b1cbb89b841278973276bRoshan Pius
902155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void startTdls(String macAddr, boolean enable) {
9035cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9045cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (enable) {
9055cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                mSupplicantStaIfaceHal.initiateTdlsDiscover(macAddr);
9065cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                mSupplicantStaIfaceHal.initiateTdlsSetup(macAddr);
9075cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
9085cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                mSupplicantStaIfaceHal.initiateTdlsTeardown(macAddr);
90918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            }
910155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
9115cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (enable) {
9125cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                synchronized (sLock) {
9135cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    doBooleanCommand("TDLS_DISCOVER " + macAddr);
9145cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    doBooleanCommand("TDLS_SETUP " + macAddr);
9155cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                }
9165cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
9175cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                doBooleanCommand("TDLS_TEARDOWN " + macAddr);
9185cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
919155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
920155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
921155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
922155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPbc(String bssid) {
9235cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9245cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.startWpsPbc(bssid);
925155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
9265cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (TextUtils.isEmpty(bssid)) {
9275cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("WPS_PBC");
9285cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
9295cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("WPS_PBC " + bssid);
9305cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
934155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPbc(String iface, String bssid) {
935956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (TextUtils.isEmpty(bssid)) {
937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC");
938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC " + bssid);
940155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
942155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPinKeypad(String pin) {
945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(pin)) return false;
9465cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9475cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.startWpsPinKeypad(pin);
9485cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
9495cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("WPS_PIN any " + pin);
9505cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPinKeypad(String iface, String pin) {
954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(pin)) return false;
955956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommandNative("IFNAME=" + iface + " WPS_PIN any " + pin);
957155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
961155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String startWpsPinDisplay(String bssid) {
9625cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9635cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.startWpsPinDisplay(bssid);
964155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
9655cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (TextUtils.isEmpty(bssid)) {
9665cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doStringCommand("WPS_PIN any");
9675cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
9685cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doStringCommand("WPS_PIN " + bssid);
9695cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String startWpsPinDisplay(String iface, String bssid) {
974956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (TextUtils.isEmpty(bssid)) {
976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN any");
977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
978155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN " + bssid);
979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
982155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
98333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    public boolean setExternalSim(boolean external) {
9845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9855cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setExternalSim(external);
9865cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
9875cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            String value = external ? "1" : "0";
9885cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            Log.d(TAG, "Setting external_sim to " + value);
9895cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET external_sim " + value);
9905cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
99133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
99233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
993f97140d51d14ce0659d381f443c08dbd94dfea28Honore Tricot    public boolean simAuthResponse(int id, String type, String response) {
9945cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9955cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if ("GSM-AUTH".equals(type)) {
9965cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(response);
9975cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else if ("UMTS-AUTH".equals(type)) {
9985cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(response);
9995cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else if ("UMTS-AUTS".equals(type)) {
10005cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(response);
10015cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
10025cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return false;
10035cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
10045cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10055cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            // with type = GSM-AUTH, UMTS-AUTH or UMTS-AUTS
10065cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("CTRL-RSP-SIM-" + id + ":" + type + response);
10075cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
100833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
100933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
101026eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    public boolean simAuthFailedResponse(int id) {
10115cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10125cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure();
10135cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10145cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            // should be used with type GSM-AUTH
10155cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("CTRL-RSP-SIM-" + id + ":GSM-FAIL");
10165cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
101726eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
101826eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
101926eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    public boolean umtsAuthFailedResponse(int id) {
10205cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10215cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure();
10225cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10235cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            // should be used with type UMTS-AUTH
10245cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("CTRL-RSP-SIM-" + id + ":UMTS-FAIL");
10255cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
102626eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
102726eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1028ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    public boolean simIdentityResponse(int id, String response) {
10295cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10305cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(response);
10315cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10325cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("CTRL-RSP-IDENTITY-" + id + ":" + response);
10335cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1034ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    }
1035ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot
1036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Configures an access point connection */
1037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsRegistrar(String bssid, String pin) {
1038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false;
10395cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10405cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.startWpsRegistrar(bssid, pin);
10415cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10425cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("WPS_REG " + bssid + " " + pin);
10435cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1044155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean cancelWps() {
10475cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10485cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.cancelWps();
10495cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10505cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("WPS_CANCEL");
10515cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setPersistentReconnect(boolean enabled) {
1055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int value = (enabled == true) ? 1 : 0;
1056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("SET persistent_reconnect " + value);
1057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setDeviceName(String name) {
10605cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10615cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsDeviceName(name);
10625cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10635cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET device_name " + name);
10645cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setDeviceType(String type) {
10685cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10695cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsDeviceType(type);
10705cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10715cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET device_type " + type);
10725cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1074155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setConfigMethods(String cfg) {
10765cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10775cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsConfigMethods(cfg);
10785cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10795cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET config_methods " + cfg);
10805cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1081155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1082155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setManufacturer(String value) {
10845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10855cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsManufacturer(value);
10865cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10875cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET manufacturer " + value);
10885cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setModelName(String value) {
10925cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10935cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsModelName(value);
10945cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10955cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET model_name " + value);
10965cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setModelNumber(String value) {
11005cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
11015cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsModelNumber(value);
11025cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
11035cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET model_number " + value);
11045cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setSerialNumber(String value) {
11085cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
11095cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsSerialNumber(value);
11105cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
11115cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET serial_number " + value);
11125cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setP2pSsidPostfix(String postfix) {
1116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
1117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setP2pGroupIdle(String iface, int time) {
1120956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
1121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommandNative("IFNAME=" + iface + " SET p2p_group_idle " + time);
1122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setPowerSave(boolean enabled) {
11265cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
11275cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            mSupplicantStaIfaceHal.setPowerSave(enabled);
1128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
11295cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (enabled) {
11305cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                doBooleanCommand("SET ps 1");
11315cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
11325cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                doBooleanCommand("SET ps 0");
11335cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
1134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setP2pPowerSave(String iface, boolean enabled) {
1138956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
1139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (enabled) {
1140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 1");
1141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
1142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 0");
1143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setWfdEnable(boolean enable) {
1148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("SET wifi_display " + (enable ? "1" : "0"));
1149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setWfdDeviceInfo(String hex) {
1152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("WFD_SUBELEM_SET 0 " + hex);
1153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * "sta" prioritizes STA connection over P2P and "p2p" prioritizes
1157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * P2P connection over STA
1158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setConcurrencyPriority(String s) {
1160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_SET conc_pref " + s);
1161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pFind() {
1164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_FIND");
1165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pFind(int timeout) {
1168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (timeout <= 0) {
1169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return p2pFind();
1170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_FIND " + timeout);
1172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pStopFind() {
1175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande       return doBooleanCommand("P2P_STOP_FIND");
1176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pListen() {
1179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_LISTEN");
1180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pListen(int timeout) {
1183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (timeout <= 0) {
1184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return p2pListen();
1185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_LISTEN " + timeout);
1187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pExtListen(boolean enable, int period, int interval) {
1190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (enable && interval < period) {
1191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
1192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_EXT_LISTEN"
1194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    + (enable ? (" " + period + " " + interval) : ""));
1195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pSetChannel(int lc, int oc) {
1198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) Log.d(mTAG, "p2pSetChannel: lc="+lc+", oc="+oc);
1199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1200956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
120118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            if (lc >=1 && lc <= 11) {
120218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                if (!doBooleanCommand("P2P_SET listen_channel " + lc)) {
120318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    return false;
120418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                }
120518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            } else if (lc != 0) {
1206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return false;
1207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
120918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            if (oc >= 1 && oc <= 165 ) {
121018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                int freq = (oc <= 14 ? 2407 : 5000) + oc * 5;
121118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                return doBooleanCommand("P2P_SET disallow_freq 1000-"
121218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                        + (freq - 5) + "," + (freq + 5) + "-6000");
121318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            } else if (oc == 0) {
121418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                /* oc==0 disables "P2P_SET disallow_freq" (enables all freqs) */
121518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                return doBooleanCommand("P2P_SET disallow_freq \"\"");
121618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            }
1217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return false;
1219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pFlush() {
1222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_FLUSH");
1223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
122518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static final int DEFAULT_GROUP_OWNER_INTENT     = 6;
1226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
1227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
1228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
1229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (config == null) return null;
1230bc582fdbca0d2099139f9790c7d0e1f9b55b0214Christopher Wiley        List<String> args = new ArrayList<>();
1231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WpsInfo wps = config.wps;
1232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        args.add(config.deviceAddress);
1233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        switch (wps.setup) {
1235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.PBC:
1236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add("pbc");
1237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
1238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.DISPLAY:
1239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (TextUtils.isEmpty(wps.pin)) {
1240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    args.add("pin");
1241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else {
1242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    args.add(wps.pin);
1243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add("display");
1245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
1246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.KEYPAD:
1247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add(wps.pin);
1248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add("keypad");
1249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
1250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.LABEL:
1251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add(wps.pin);
1252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add("label");
1253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            default:
1254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
1255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (config.netId == WifiP2pGroup.PERSISTENT_NET_ID) {
1258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            args.add("persistent");
1259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (joinExistingGroup) {
1262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            args.add("join");
1263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
1264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //TODO: This can be adapted based on device plugged in state and
1265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //device battery state
1266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int groupOwnerIntent = config.groupOwnerIntent;
1267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
1268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                groupOwnerIntent = DEFAULT_GROUP_OWNER_INTENT;
1269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            args.add("go_intent=" + groupOwnerIntent);
1271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String command = "P2P_CONNECT ";
1274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (String s : args) command += s + " ";
1275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doStringCommand(command);
1277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pCancelConnect() {
1280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_CANCEL");
1281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pProvisionDiscovery(WifiP2pConfig config) {
1284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (config == null) return false;
1285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        switch (config.wps.setup) {
1287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.PBC:
1288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " pbc");
1289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.DISPLAY:
1290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                //We are doing display, so provision discovery is keypad
1291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " keypad");
1292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.KEYPAD:
1293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                //We are doing keypad, so provision discovery is display
1294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " display");
1295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            default:
1296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
1297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return false;
1299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pGroupAdd(boolean persistent) {
1302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (persistent) {
1303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommand("P2P_GROUP_ADD persistent");
1304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_GROUP_ADD");
1306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pGroupAdd(int netId) {
1309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_GROUP_ADD persistent=" + netId);
1310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pGroupRemove(String iface) {
1313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(iface)) return false;
1314956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
1315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommandNative("IFNAME=" + iface + " P2P_GROUP_REMOVE " + iface);
1316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pReject(String deviceAddress) {
1320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_REJECT " + deviceAddress);
1321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Invite a peer to a group */
1324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
1325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(deviceAddress)) return false;
1326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (group == null) {
1328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommand("P2P_INVITE peer=" + deviceAddress);
1329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
1330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
1331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
1332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Reinvoke a persistent connection */
1336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pReinvoke(int netId, String deviceAddress) {
1337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(deviceAddress) || netId < 0) return false;
1338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
1340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String p2pGetSsid(String deviceAddress) {
1343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return p2pGetParam(deviceAddress, "oper_ssid");
1344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String p2pGetDeviceAddress() {
134736286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        Log.d(TAG, "p2pGetDeviceAddress");
134836286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande
134927f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande        String status = null;
135027f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande
135136286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        /* Explicitly calling the API without IFNAME= prefix to take care of the devices that
135236286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        don't have p2p0 interface. Supplicant seems to be returning the correct address anyway. */
135336286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande
1354956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
135527f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande            status = doStringCommandNative("STATUS");
135627f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande        }
135727f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande
135827f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande        String result = "";
135936286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        if (status != null) {
136036286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande            String[] tokens = status.split("\n");
136136286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande            for (String token : tokens) {
136236286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                if (token.startsWith("p2p_device_address=")) {
136336286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                    String[] nameValue = token.split("=");
136436286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                    if (nameValue.length != 2)
136536286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                        break;
136636286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                    result = nameValue[1];
136736286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                }
1368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
137036286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande
137136286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        Log.d(TAG, "p2pGetDeviceAddress returning " + result);
137236286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        return result;
1373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public int getGroupCapability(String deviceAddress) {
1376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int gc = 0;
1377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(deviceAddress)) return gc;
1378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String peerInfo = p2pPeer(deviceAddress);
1379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(peerInfo)) return gc;
1380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String[] tokens = peerInfo.split("\n");
1382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (String token : tokens) {
1383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (token.startsWith("group_capab=")) {
1384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                String[] nameValue = token.split("=");
1385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (nameValue.length != 2) break;
1386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                try {
1387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return Integer.decode(nameValue[1]);
1388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } catch(NumberFormatException e) {
1389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return gc;
1390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return gc;
1394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String p2pPeer(String deviceAddress) {
1397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doStringCommand("P2P_PEER " + deviceAddress);
1398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String p2pGetParam(String deviceAddress, String key) {
1401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (deviceAddress == null) return null;
1402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String peerInfo = p2pPeer(deviceAddress);
1404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (peerInfo == null) return null;
1405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String[] tokens= peerInfo.split("\n");
1406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        key += "=";
1408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (String token : tokens) {
1409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (token.startsWith(key)) {
1410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                String[] nameValue = token.split("=");
1411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (nameValue.length != 2) break;
1412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return nameValue[1];
1413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return null;
1416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) {
1419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /*
1420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD bonjour <query hexdump> <RDATA hexdump>
1421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD upnp <version hex> <service>
1422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         *
1423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * e.g)
1424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * [Bonjour]
1425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * # IP Printing over TCP (PTR) (RDATA=MyPrinter._ipp._tcp.local.)
1426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD bonjour 045f697070c00c000c01 094d795072696e746572c027
1427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * # IP Printing over TCP (TXT) (RDATA=txtvers=1,pdl=application/postscript)
1428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD bonjour 096d797072696e746572045f697070c00c001001
1429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         *  09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074
1430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         *
1431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * [UPnP]
1432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012
1433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice
1434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp
1435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * -org:device:InternetGatewayDevice:1
1436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9322-123456789012::urn:schemas-upnp
1437155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * -org:service:ContentDirectory:2
1438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
1439956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
144018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            for (String s : servInfo.getSupplicantQueryList()) {
144118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                String command = "P2P_SERVICE_ADD";
144218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                command += (" " + s);
144318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                if (!doBooleanCommand(command)) {
144418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    return false;
144518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                }
1446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
1449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pServiceDel(WifiP2pServiceInfo servInfo) {
1452155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /*
1453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_DEL bonjour <query hexdump>
1454155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_DEL upnp <version hex> <service>
1455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
1456956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
145718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            for (String s : servInfo.getSupplicantQueryList()) {
145818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                String command = "P2P_SERVICE_DEL ";
1459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
146018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                String[] data = s.split(" ");
146118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                if (data.length < 2) {
146218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    return false;
146318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                }
146418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                if ("upnp".equals(data[0])) {
146518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    command += s;
146618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                } else if ("bonjour".equals(data[0])) {
146718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    command += data[0];
146818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    command += (" " + data[1]);
146918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                } else {
147018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    return false;
147118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                }
147218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                if (!doBooleanCommand(command)) {
147318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    return false;
147418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                }
1475155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
1478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pServiceFlush() {
1481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_SERVICE_FLUSH");
1482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1484155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String p2pServDiscReq(String addr, String query) {
1485155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String command = "P2P_SERV_DISC_REQ";
1486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        command += (" " + addr);
1487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        command += (" " + query);
1488155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doStringCommand(command);
1490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1491155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1492155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pServDiscCancelReq(String id) {
1493155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_SERV_DISC_CANCEL_REQ " + id);
1494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1495155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Set the current mode of miracast operation.
1497155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *  0 = disabled
1498155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *  1 = operating as source
1499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *  2 = operating as sink
1500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1501155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setMiracastMode(int mode) {
1502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Note: optional feature on the driver. It is ok for this to fail.
1503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        doBooleanCommand("DRIVER MIRACAST " + mode);
1504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
15053f7ef65ab71619040032aee96b5599849881d6fdAndres Morales
1506f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    /*
1507f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande     * NFC-related calls
1508f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande     */
1509f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    public String getNfcWpsConfigurationToken(int netId) {
1510f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        return doStringCommand("WPS_NFC_CONFIG_TOKEN WPS " + netId);
1511f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    }
1512f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
1513f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    public String getNfcHandoverRequest() {
1514f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        return doStringCommand("NFC_GET_HANDOVER_REQ NDEF P2P-CR");
1515f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    }
1516f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
1517f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    public String getNfcHandoverSelect() {
1518f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        return doStringCommand("NFC_GET_HANDOVER_SEL NDEF P2P-CR");
1519f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    }
1520f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
1521f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    public boolean initiatorReportNfcHandover(String selectMessage) {
1522f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        return doBooleanCommand("NFC_REPORT_HANDOVER INIT P2P 00 " + selectMessage);
1523f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    }
1524f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
1525f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    public boolean responderReportNfcHandover(String requestMessage) {
1526f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        return doBooleanCommand("NFC_REPORT_HANDOVER RESP P2P " + requestMessage + " 00");
1527f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    }
1528f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
1529a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /** WifiSupplicantControl methods. TODO: These should use HIDL soon. */
1530a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1531a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Migrate all the configured networks from wpa_supplicant.
1532a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1533a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
1534a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *                      the networks.
1535a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
1536a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return Max priority of all the configs.
1537a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1538f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    public boolean migrateNetworksFromSupplicant(Map<String, WifiConfiguration> configs,
1539f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius                                                 SparseArray<Map<String, String>> networkExtras) {
15405cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
15415cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.loadNetworks(configs, networkExtras);
15425cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
15435cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            mWifiSupplicantControl.loadNetworks(configs, networkExtras);
15445cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return true;
15455cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1546a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1547a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1548a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1549a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
1550a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * This method does the following:
1551a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 1. Triggers disconnect command to wpa_supplicant (if |shouldDisconnect| is true).
1552a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 2. Remove any existing network in wpa_supplicant.
1553a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 3. Add a new network to wpa_supplicant.
1554a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 4. Save the provided configuration to wpa_supplicant.
1555a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 5. Select the new network in wpa_supplicant.
1556a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 6. Triggers reconnect command to wpa_supplicant.
1557a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1558a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1559a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param shouldDisconnect whether to trigger a disconnection or not.
1560a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1561a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1562a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean connectToNetwork(WifiConfiguration configuration, boolean shouldDisconnect) {
15635cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
15645cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.connectToNetwork(configuration, shouldDisconnect);
15655cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
15665cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mWifiSupplicantControl.connectToNetwork(configuration, shouldDisconnect);
15675cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1568a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1569a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1570a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1571a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
1572a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * configuration provided does not match the already configured network, then this triggers
1573a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * a new connection attempt (instead of roam).
1574a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 1. First check if we're attempting to connect to the same network as we currently have
1575a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * configured.
1576a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 2. Set the new bssid for the network in wpa_supplicant.
1577a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 3. Triggers reassociate command to wpa_supplicant.
1578a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1579a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1580a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1581a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1582a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean roamToNetwork(WifiConfiguration configuration) {
15835cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
15845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.roamToNetwork(configuration);
15855cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
15865cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mWifiSupplicantControl.roamToNetwork(configuration);
15875cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1588a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1589a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1590a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1591a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Get the framework network ID corresponding to the provided supplicant network ID for the
1592a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * network configured in wpa_supplicant.
1593a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1594a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param supplicantNetworkId network ID in wpa_supplicant for the network.
1595a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return Corresponding framework network ID if found, -1 if network not found.
1596a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1597a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public int getFrameworkNetworkId(int supplicantNetworkId) {
15985cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
15995cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            // In the HIDL world, wifi monitor events contain the framework network Id.
16005cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return supplicantNetworkId;
16015cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
16025cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mWifiSupplicantControl.getFrameworkNetworkId(supplicantNetworkId);
16035cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1604a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1605a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1606a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1607a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Remove all the networks.
1608a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1609a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1610a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1611a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean removeAllNetworks() {
16125cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
16135cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.removeAllNetworks();
16145cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
16155cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (!doBooleanCommand("REMOVE_NETWORK all")) {
16165cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                Log.e(TAG, "Remove all networks in wpa_supplicant failed");
16175cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return false;
16185cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
16195cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return true;
1620a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        }
1621a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1622a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1623a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1624a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Set the BSSID for the currently configured network in wpa_supplicant.
1625a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1626a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return true if successful, false otherwise.
1627a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1628a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean setConfiguredNetworkBSSID(String bssid) {
16295cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
16305cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setCurrentNetworkBssid(bssid);
16315cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
16325cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mWifiSupplicantControl.setConfiguredNetworkBSSID(bssid);
16335cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1634a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1635a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1636a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1637a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Save the current configuration to wpa_supplicant.conf.
1638a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1639a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean saveConfig() {
1640a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        return doBooleanCommand("SAVE_CONFIG");
1641a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1642a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1643a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1644a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Read network variables from wpa_supplicant.conf.
1645a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1646a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param key The parameter to be parsed.
1647a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return Map of corresponding configKey to the value of the param requested.
1648a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1649a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public Map<String, String> readNetworkVariablesFromSupplicantFile(String key) {
1650a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        return mWifiSupplicantControl.readNetworkVariablesFromSupplicantFile(key);
1651a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1652a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1653a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1654a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Get Fast BSS Transition capability.
1655a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1656a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean getSystemSupportsFastBssTransition() {
1657a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        return mWifiSupplicantControl.getSystemSupportsFastBssTransition();
1658a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1659a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1660a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1661a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Set Fast BSS Transition capability.
1662a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1663a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public void setSystemSupportsFastBssTransition(boolean supported) {
1664a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        mWifiSupplicantControl.setSystemSupportsFastBssTransition(supported);
1665a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
16667e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
1667fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    /**
1668fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * Initiate ANQP query.
1669fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     *
1670fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param bssid BSSID of the AP to be queried
1671fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param anqpIds Set of anqp IDs.
1672fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param hs20Subtypes Set of HS20 subtypes.
1673fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @return true on success, false otherwise.
1674fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     */
1675fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    public boolean requestAnqp(String bssid, Set<Integer> anqpIds, Set<Integer> hs20Subtypes) {
1676fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        if (bssid == null || ((anqpIds == null || anqpIds.isEmpty())
1677fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                && (hs20Subtypes == null || hs20Subtypes.isEmpty()))) {
1678fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            return false;
1679fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        }
16805cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
16815cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            ArrayList<Short> anqpIdList = new ArrayList<>();
16825cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            for (Integer anqpId : anqpIds) {
16835cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                anqpIdList.add(anqpId.shortValue());
16845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
16855cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            ArrayList<Integer> hs20SubtypeList = new ArrayList<>();
16865cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            hs20SubtypeList.addAll(hs20Subtypes);
16875cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.initiateAnqpQuery(bssid, anqpIdList, hs20SubtypeList);
16885cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
16895cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            String command = buildAnqpQueryCommand(bssid, anqpIds, hs20Subtypes);
16905cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            String result = doStringCommand(command);
16915cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return result != null && result.startsWith("OK");
16925cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1693fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    }
1694fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius
1695fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    /**
1696fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * Build a wpa_supplicant ANQP query command
1697fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     *
1698fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param bssid BSSID of the AP to be queried
1699fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param anqpIds Set of anqp IDs.
1700fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param hs20Subtypes Set of HS20 subtypes.
1701fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @return A command string.
1702fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     */
1703fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    @VisibleForTesting
1704fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    public static String buildAnqpQueryCommand(String bssid, Set<Integer> anqpIds,
1705fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                                               Set<Integer> hs20Subtypes) {
1706fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius
1707fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        boolean baseANQPElements = !anqpIds.isEmpty();
1708fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        StringBuilder sb = new StringBuilder();
1709fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        if (baseANQPElements) {
1710fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            sb.append("ANQP_GET ");
1711fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        } else {
1712fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            // ANQP_GET does not work for a sole hs20:8 (OSU) query
1713fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            sb.append("HS20_ANQP_GET ");
1714fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        }
1715fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        sb.append(bssid).append(' ');
1716fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        boolean first = true;
1717fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        for (Integer id : anqpIds) {
1718fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            if (first) {
1719fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                first = false;
1720fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            } else {
1721fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                sb.append(',');
1722fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            }
1723fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            sb.append(id);
1724fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        }
1725fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        for (Integer subType : hs20Subtypes) {
1726fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            if (first) {
1727fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                first = false;
1728fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            } else {
1729fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                sb.append(',');
1730fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            }
1731fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            if (baseANQPElements) {
1732fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                sb.append("hs20:");
1733fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            }
1734fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            sb.append(subType);
1735fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        }
1736fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        return sb.toString();
1737fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    }
1738fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius
1739fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    /**
1740fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * Request a passpoint icon file |filename| from the specified AP |bssid|.
1741fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param bssid BSSID of the AP
1742fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param fileName name of the icon file
1743fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @return true if request is sent successfully, false otherwise
1744fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     */
1745fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    public boolean requestIcon(String  bssid, String fileName) {
17465cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
17475cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.initiateHs20IconQuery(bssid, fileName);
17485cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
17495cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            String result = doStringCommand("REQ_HS20_ICON " + bssid + " " + fileName);
17505cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return result != null && result.startsWith("OK");
17515cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1752fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    }
1753fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius
17547e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    /* kernel logging support */
17557e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    private static native byte[] readKernelLogNative();
17567e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
17577e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    synchronized public String readKernelLog() {
17587e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        byte[] bytes = readKernelLogNative();
17597e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        if (bytes != null) {
17607e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
17617e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            try {
17627e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
17637e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                return decoded.toString();
17647e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            } catch (CharacterCodingException cce) {
17657e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                return new String(bytes, StandardCharsets.ISO_8859_1);
17667e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            }
17677e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        } else {
17687e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            return "*** failed to read kernel log ***";
17697e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        }
17707e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    }
17717e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
17727f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    /* WIFI HAL support */
17737f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
177418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // HAL command ids
177518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static int sCmdId = 1;
177618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static int getNewCmdIdLocked() {
177718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return sCmdId++;
177818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
177918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
1780b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static final String TAG = "WifiNative-HAL";
1781f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    private static long sWifiHalHandle = 0;             /* used by JNI to save wifi_handle */
1782f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    private static long[] sWifiIfaceHandles = null;     /* used by JNI to save interface handles */
1783956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public static int sWlan0Index = -1;
1784f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    private static MonitorThread sThread;
1785f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    private static final int STOP_HAL_TIMEOUT_MS = 1000;
17867f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1787b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean startHalNative();
1788b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native void stopHalNative();
1789b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native void waitForHalEventNative();
17907f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1791b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static class MonitorThread extends Thread {
1792cc180872c51908b15ce5cbf834634ff323e036bcChristopher Wiley        @Override
17937ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde        public void run() {
1794b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande            Log.i(TAG, "Waiting for HAL events mWifiHalHandle=" + Long.toString(sWifiHalHandle));
17957ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde            waitForHalEventNative();
17967ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde        }
17977ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    }
17987ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde
1799d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    /**
1800d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     * Bring up the Vendor HAL and configure for STA mode or AP mode.
1801d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     *
1802d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     * @param isStaMode true to start HAL in STA mode, false to start in AP mode.
1803d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     */
1804d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    public boolean startHal(boolean isStaMode) {
1805d6307b404302949f6dadd14fa0860ff1aec432dcxinhe        String debugLog = "startHal stack: ";
1806d6307b404302949f6dadd14fa0860ff1aec432dcxinhe        java.lang.StackTraceElement[] elements = Thread.currentThread().getStackTrace();
1807d6307b404302949f6dadd14fa0860ff1aec432dcxinhe        for (int i = 2; i < elements.length && i <= 7; i++ ) {
1808d6307b404302949f6dadd14fa0860ff1aec432dcxinhe            debugLog = debugLog + " - " + elements[i].getMethodName();
1809d6307b404302949f6dadd14fa0860ff1aec432dcxinhe        }
1810d6307b404302949f6dadd14fa0860ff1aec432dcxinhe
1811956f54b391677d78379729dd14518edddf3c7660Etan Cohen        sLocalLog.log(debugLog);
1812d6307b404302949f6dadd14fa0860ff1aec432dcxinhe
1813956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
1814918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang            if (startHalNative()) {
1815918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                int wlan0Index = queryInterfaceIndex(mInterfaceName);
1816918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                if (wlan0Index == -1) {
1817918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                    if (DBG) sLocalLog.log("Could not find interface with name: " + mInterfaceName);
1818918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                    return false;
1819918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                }
1820918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                sWlan0Index = wlan0Index;
1821f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sThread = new MonitorThread();
1822f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sThread.start();
1823aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle                return true;
1824aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle            } else {
1825956f54b391677d78379729dd14518edddf3c7660Etan Cohen                if (DBG) sLocalLog.log("Could not start hal");
1826f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                Log.e(TAG, "Could not start hal");
1827aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle                return false;
1828aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle            }
18297ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde        }
18307ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    }
18317ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde
183218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void stopHal() {
1833956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
183471d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
1835f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                stopHalNative();
1836f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                try {
1837f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sThread.join(STOP_HAL_TIMEOUT_MS);
1838f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    Log.d(TAG, "HAL event thread stopped successfully");
1839f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } catch (InterruptedException e) {
1840f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    Log.e(TAG, "Could not stop HAL cleanly");
1841f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
1842f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sThread = null;
1843f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sWifiHalHandle = 0;
1844f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sWifiIfaceHandles = null;
1845f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sWlan0Index = -1;
1846f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            }
1847f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        }
18487ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    }
18497f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
185018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean isHalStarted() {
185171d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe        return (sWifiHalHandle != 0);
185271d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe    }
1853b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native int getInterfacesNative();
18547f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1855918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang    public int queryInterfaceIndex(String interfaceName) {
1856956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
185771d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
1858918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                int num = getInterfacesNative();
1859918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                for (int i = 0; i < num; i++) {
1860918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                    String name = getInterfaceNameNative(i);
1861918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                    if (name.equals(interfaceName)) {
1862918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                        return i;
186302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    }
1864aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle                }
1865e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
1866e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
1867918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang        return -1;
18687f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
18697f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1870b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native String getInterfaceNameNative(int index);
187118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getInterfaceName(int index) {
1872956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
187318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            return getInterfaceNameNative(index);
187418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        }
18757f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
18767f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1877062e3f39e37874fedc01f267de5f4cf7dbebe2b4Randy Pan    // TODO: Change variable names to camel style.
1878e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanCapabilities {
1879297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_cache_size;
1880e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_scan_buckets;
1881e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_ap_cache_per_scan;
1882e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_rssi_sample_size;
1883297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_reporting_threshold;
18847d6301ead19afdf3de37455e9ed133c25b4938cdVinit Deshpande        public int  max_hotlist_bssids;
1885e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_significant_wifi_change_aps;
1886d34e3a7b98d51f684100483151fceb233fd95215Roshan Pius        public int  max_bssid_history_entries;
1887d34e3a7b98d51f684100483151fceb233fd95215Roshan Pius        public int  max_number_epno_networks;
1888d34e3a7b98d51f684100483151fceb233fd95215Roshan Pius        public int  max_number_epno_networks_by_ssid;
1889d34e3a7b98d51f684100483151fceb233fd95215Roshan Pius        public int  max_number_of_white_listed_ssid;
1890e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1891e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
189218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean getScanCapabilities(ScanCapabilities capabilities) {
1893956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
1894af5b49884f189bb171c9dc6c6a4405d97e7912acVinit Deshpande            return isHalStarted() && getScanCapabilitiesNative(sWlan0Index, capabilities);
1895af5b49884f189bb171c9dc6c6a4405d97e7912acVinit Deshpande        }
1896e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1897e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1898b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean getScanCapabilitiesNative(
1899b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande            int iface, ScanCapabilities capabilities);
1900e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1901b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean startScanNative(int iface, int id, ScanSettings settings);
1902b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean stopScanNative(int iface, int id);
190383a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande    private static native WifiScanner.ScanData[] getScanResultsNative(int iface, boolean flush);
1904b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native WifiLinkLayerStats getWifiLinkLayerStatsNative(int iface);
1905d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle    private static native void setWifiLinkLayerStatsNative(int iface, int enable);
19067f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1907e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ChannelSettings {
1908712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int frequency;
1909712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int dwell_time_ms;
1910712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public boolean passive;
19117f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
19127f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1913e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class BucketSettings {
1914712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int bucket;
1915712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int band;
1916712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int period_ms;
1917712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_period_ms;
1918712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int step_count;
1919712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_events;
1920712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_channels;
1921712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public ChannelSettings[] channels;
1922e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
19237f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
19246259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    /**
19256259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * Network parameters for hidden networks to be scanned for.
19266259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     */
19276259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public static class HiddenNetwork {
19286259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public String ssid;
19296259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
19306259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        @Override
19316259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public boolean equals(Object otherObj) {
19326259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            if (this == otherObj) {
19336259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return true;
19346259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
19356259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return false;
19366259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            }
19376259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            HiddenNetwork other = (HiddenNetwork) otherObj;
19386259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return Objects.equals(ssid, other.ssid);
19396259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        }
1940ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1941ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1942ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1943ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return (ssid == null ? 0 : ssid.hashCode());
1944ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
19456259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    }
19466259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
1947e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanSettings {
1948712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int base_period_ms;
1949712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_ap_per_scan;
1950712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_percent;
1951712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_num_scans;
1952712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_buckets;
19536259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        /* Not used for bg scans. Only works for single scans. */
19546259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public HiddenNetwork[] hiddenNetworks;
1955712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public BucketSettings[] buckets;
1956e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
19577f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
195868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
19599bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Network parameters to start PNO scan.
19609bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
19619bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoNetwork {
19629bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public String ssid;
19639bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public byte flags;
1964ef3ea1092bc17673c0a85a845b053151b7c10e07Roshan Pius        public byte auth_bit_field;
19651bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius
19661bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        @Override
19671bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        public boolean equals(Object otherObj) {
19681bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            if (this == otherObj) {
19691bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return true;
19701bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
19711bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return false;
19721bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            }
19731bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            PnoNetwork other = (PnoNetwork) otherObj;
19746259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return ((Objects.equals(ssid, other.ssid)) && (flags == other.flags)
19751bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                    && (auth_bit_field == other.auth_bit_field));
19761bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        }
1977ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1978ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1979ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1980ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            int result = (ssid == null ? 0 : ssid.hashCode());
1981ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            result ^= ((int) flags * 31) + ((int) auth_bit_field << 8);
1982ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return result;
1983ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
19849bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
19859bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
19869bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
19879bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Parameters to start PNO scan. This holds the list of networks which are going to used for
19889bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * PNO scan.
19899bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
19909bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoSettings {
19919bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min5GHzRssi;
19929bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min24GHzRssi;
19939bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int initialScoreMax;
19949bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int currentConnectionBonus;
19959bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int sameNetworkBonus;
19969bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int secureBonus;
19979bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int band5GHzBonus;
1998dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        public boolean isConnected;
19999bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public PnoNetwork[] networkList;
20009bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
20019bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
20029bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
200368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Wi-Fi channel information.
200468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
200568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    public static class WifiChannelInfo {
200668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        int mPrimaryFrequency;
200768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        int mCenterFrequency0;
200868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        int mCenterFrequency1;
200968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        int mChannelWidth;
201068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        // TODO: add preamble once available in HAL.
201168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    }
201268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
2013d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
2014d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * Result of a signal poll.
2015d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     */
2016d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public static class SignalPollResult {
2017d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        // RSSI value in dBM.
2018d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        public int currentRssi;
2019d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        //Transmission bit rate in Mbps.
2020d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        public int txBitrate;
2021d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        // Association frequency in MHz.
2022d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        public int associationFrequency;
2023d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
2024d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
2025d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
2026d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * WiFi interface transimission counters.
2027d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     */
2028d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public static class TxPacketCounters {
2029d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        // Number of successfully transmitted packets.
2030d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        public int txSucceeded;
2031d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        // Number of tramsmission failures.
2032d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        public int txFailed;
2033d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
2034d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
2035b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface ScanEventHandler {
203663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
203763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called for each AP as it is found with the entire contents of the beacon/probe response.
203863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Only called when WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT is specified.
203963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
2040c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills        void onFullScanResult(ScanResult fullScanResult, int bucketsScanned);
204163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
204263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Callback on an event during a gscan scan.
204363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * See WifiNative.WIFI_SCAN_* for possible values.
204463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
204563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        void onScanStatus(int event);
204663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
204763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is paused.
204863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
204983a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande        void onScanPaused(WifiScanner.ScanData[] data);
205063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
205163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is resumed.
205263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
2053b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        void onScanRestarted();
2054e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2055e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
20569bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
20579bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Handler to notify the occurrence of various events during PNO scan.
20589bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
20599bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public interface PnoEventHandler {
20609bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        /**
20619bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * Callback to notify when one of the shortlisted networks is found during PNO scan.
20629bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * @param results List of Scan results received.
20639bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         */
20649bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        void onPnoNetworkFound(ScanResult[] results);
2065063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius
2066063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        /**
2067063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         * Callback to notify when the PNO scan schedule fails.
2068063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         */
2069063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        void onPnoScanFailed();
20709bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
20719bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
2072b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande    /* scan status, keep these values in sync with gscan.h */
207371af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
207471af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1;
207571af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2;
207671af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_FAILED = 3;
2077b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande
207818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
20792a6d76f0899289cd3b96e3428f02076fdbc0363eMitchell Wills    private static void onScanStatus(int id, int event) {
208018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        ScanEventHandler handler = sScanEventHandler;
208163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        if (handler != null) {
208263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills            handler.onScanStatus(event);
20832a6d76f0899289cd3b96e3428f02076fdbc0363eMitchell Wills        }
2084e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2085e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
208618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static  WifiSsid createWifiSsid(byte[] rawSsid) {
20875cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        String ssidHexString = String.valueOf(HexEncoding.encode(rawSsid));
20885cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20895cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        if (ssidHexString == null) {
20905cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            return null;
20915cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        }
20925cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20935cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        WifiSsid wifiSsid = WifiSsid.createFromHex(ssidHexString);
20945cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20955cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        return wifiSsid;
20965cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe    }
20975cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20985cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe    public static String ssidConvert(byte[] rawSsid) {
20995cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        String ssid;
21005cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
21015cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
21025cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        try {
21035cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            CharBuffer decoded = decoder.decode(ByteBuffer.wrap(rawSsid));
21045cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            ssid = decoded.toString();
21055cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        } catch (CharacterCodingException cce) {
21065cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            ssid = null;
21075cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        }
21085cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
21095cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        if (ssid == null) {
21105cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            ssid = new String(rawSsid, StandardCharsets.ISO_8859_1);
21115cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        }
21125cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
21135cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        return ssid;
21145cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe    }
21155cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
211618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Called from native
21175cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe    public static boolean setSsid(byte[] rawSsid, ScanResult result) {
21185cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        if (rawSsid == null || rawSsid.length == 0 || result == null) {
21195cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            return false;
21205cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        }
21215cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
21225cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        result.SSID = ssidConvert(rawSsid);
21235cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        result.wifiSsid = createWifiSsid(rawSsid);
21245cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        return true;
21255cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe    }
21265cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
21271ab129e587d334a144a0bca5323c27985397a403Randy Pan    private static void populateScanResult(ScanResult result, int beaconCap, String dbg) {
2128dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        if (dbg == null) dbg = "";
21295d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills
21305d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        InformationElementUtil.HtOperation htOperation = new InformationElementUtil.HtOperation();
21315d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        InformationElementUtil.VhtOperation vhtOperation =
21325d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills                new InformationElementUtil.VhtOperation();
21335d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        InformationElementUtil.ExtendedCapabilities extendedCaps =
21345d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills                new InformationElementUtil.ExtendedCapabilities();
21355d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills
21365d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        ScanResult.InformationElement elements[] =
21371ab129e587d334a144a0bca5323c27985397a403Randy Pan                InformationElementUtil.parseInformationElements(result.bytes);
21385d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        for (ScanResult.InformationElement ie : elements) {
21395d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            if(ie.id == ScanResult.InformationElement.EID_HT_OPERATION) {
21405d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills                htOperation.from(ie);
21415d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            } else if(ie.id == ScanResult.InformationElement.EID_VHT_OPERATION) {
21425d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills                vhtOperation.from(ie);
21435d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            } else if (ie.id == ScanResult.InformationElement.EID_EXTENDED_CAPS) {
21445d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills                extendedCaps.from(ie);
2145243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            }
2146243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        }
2147d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande
2148b86089a48fae8878b5a27533a116c97b0be6d0e7Peter Qiu        if (extendedCaps.is80211McRTTResponder()) {
2149d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande            result.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
2150d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande        } else {
2151d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande            result.clearFlag(ScanResult.FLAG_80211mc_RESPONDER);
2152d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande        }
2153d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande
2154243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        //handle RTT related information
21555d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        if (vhtOperation.isValid()) {
21565d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            result.channelWidth = vhtOperation.getChannelWidth();
21575d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            result.centerFreq0 = vhtOperation.getCenterFreq0();
21585d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            result.centerFreq1 = vhtOperation.getCenterFreq1();
2159243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        } else {
21605d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            result.channelWidth = htOperation.getChannelWidth();
21615d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            result.centerFreq0 = htOperation.getCenterFreq0(result.frequency);
2162243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            result.centerFreq1  = 0;
2163243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        }
21643571366ac36c70746b9f013ec2b54482861c9292Randy Pan
21653571366ac36c70746b9f013ec2b54482861c9292Randy Pan        // build capabilities string
21663571366ac36c70746b9f013ec2b54482861c9292Randy Pan        BitSet beaconCapBits = new BitSet(16);
21673571366ac36c70746b9f013ec2b54482861c9292Randy Pan        for (int i = 0; i < 16; i++) {
21683571366ac36c70746b9f013ec2b54482861c9292Randy Pan            if ((beaconCap & (1 << i)) != 0) {
21693571366ac36c70746b9f013ec2b54482861c9292Randy Pan                beaconCapBits.set(i);
21703571366ac36c70746b9f013ec2b54482861c9292Randy Pan            }
21713571366ac36c70746b9f013ec2b54482861c9292Randy Pan        }
21724d11585ede6636fee294ffb89e832e2f7f271c12Ningyuan Wang        InformationElementUtil.Capabilities capabilities =
21734d11585ede6636fee294ffb89e832e2f7f271c12Ningyuan Wang                new InformationElementUtil.Capabilities();
21744d11585ede6636fee294ffb89e832e2f7f271c12Ningyuan Wang        capabilities.from(elements, beaconCapBits);
21754d11585ede6636fee294ffb89e832e2f7f271c12Ningyuan Wang        result.capabilities = capabilities.generateCapabilitiesString();
21763571366ac36c70746b9f013ec2b54482861c9292Randy Pan
2177243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        if(DBG) {
21783571366ac36c70746b9f013ec2b54482861c9292Randy Pan            Log.d(TAG, dbg + "SSID: " + result.SSID + " ChannelWidth is: " + result.channelWidth
21793571366ac36c70746b9f013ec2b54482861c9292Randy Pan                    + " PrimaryFreq: " + result.frequency + " mCenterfreq0: " + result.centerFreq0
2180b86089a48fae8878b5a27533a116c97b0be6d0e7Peter Qiu                    + " mCenterfreq1: " + result.centerFreq1
2181b86089a48fae8878b5a27533a116c97b0be6d0e7Peter Qiu                    + (extendedCaps.is80211McRTTResponder() ? "Support RTT reponder: "
2182b86089a48fae8878b5a27533a116c97b0be6d0e7Peter Qiu                            : "Do not support RTT responder")
21833571366ac36c70746b9f013ec2b54482861c9292Randy Pan                    + " Capabilities: " + result.capabilities);
2184f1daf9342b66bf134d13fa0a42e929a008f1ca62Vinit Deshapnde        }
2185f1daf9342b66bf134d13fa0a42e929a008f1ca62Vinit Deshapnde
2186476bee2fef10d060c25c35858b1f7f60803d9f49Vinit Deshpande        result.informationElements = elements;
2187dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    }
2188dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
218918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
21901ab129e587d334a144a0bca5323c27985397a403Randy Pan    private static void onFullScanResult(int id, ScanResult result,
21913571366ac36c70746b9f013ec2b54482861c9292Randy Pan            int bucketsScanned, int beaconCap) {
21921ab129e587d334a144a0bca5323c27985397a403Randy Pan        if (DBG) Log.i(TAG, "Got a full scan results event, ssid = " + result.SSID);
2193dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
219418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        ScanEventHandler handler = sScanEventHandler;
219518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null) {
21961ab129e587d334a144a0bca5323c27985397a403Randy Pan            populateScanResult(result, beaconCap, " onFullScanResult ");
2197c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills            handler.onFullScanResult(result, bucketsScanned);
2198dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        }
21997f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
22007f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
2201b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static int sScanCmdId = 0;
2202b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static ScanEventHandler sScanEventHandler;
2203b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static ScanSettings sScanSettings;
22047f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
220518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean startScan(ScanSettings settings, ScanEventHandler eventHandler) {
2206956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
220771d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2208f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sScanCmdId != 0) {
2209f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    stopScan();
2210f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } else if (sScanSettings != null || sScanEventHandler != null) {
2211b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande                /* current scan is paused; no need to stop it */
2212f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
22137f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
2214f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanCmdId = getNewCmdIdLocked();
2215e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2216f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanSettings = settings;
2217f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanEventHandler = eventHandler;
2218b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
2219f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (startScanNative(sWlan0Index, sScanCmdId, settings) == false) {
2220f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sScanEventHandler = null;
2221f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sScanSettings = null;
2222f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sScanCmdId = 0;
2223f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2224f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2225f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
2226f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return true;
2227f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
2228e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde                return false;
2229e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
2230e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
22317f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
22327f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
223318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void stopScan() {
2234956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
223571d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2236ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                if (sScanCmdId != 0) {
2237ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                    stopScanNative(sWlan0Index, sScanCmdId);
2238ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                }
2239f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanSettings = null;
2240f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanEventHandler = null;
2241f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanCmdId = 0;
2242f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            }
2243b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        }
2244b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
2245b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
224618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void pauseScan() {
2247956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
224871d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2249f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sScanCmdId != 0 && sScanSettings != null && sScanEventHandler != null) {
2250f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    Log.d(TAG, "Pausing scan");
2251f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    WifiScanner.ScanData scanData[] = getScanResultsNative(sWlan0Index, true);
2252f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    stopScanNative(sWlan0Index, sScanCmdId);
2253f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sScanCmdId = 0;
2254f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sScanEventHandler.onScanPaused(scanData);
2255f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2256b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande            }
2257b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        }
2258b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
2259b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
226018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void restartScan() {
2261956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
226271d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2263f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sScanCmdId == 0 && sScanSettings != null && sScanEventHandler != null) {
22646f3626faf50499dd95aa299bb1011c27ab05776dPierre Vandwalle                    Log.d(TAG, "Restarting scan");
2265f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    ScanEventHandler handler = sScanEventHandler;
2266f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    ScanSettings settings = sScanSettings;
2267f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    if (startScan(sScanSettings, sScanEventHandler)) {
2268f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                        sScanEventHandler.onScanRestarted();
2269f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    } else {
227083a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande                    /* we are still paused; don't change state */
2271f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                        sScanEventHandler = handler;
2272f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                        sScanSettings = settings;
2273f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    }
227483a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande                }
2275b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande            }
2276e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
2277e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2278e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
227918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public WifiScanner.ScanData[] getScanResults(boolean flush) {
2280956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
22813ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande            WifiScanner.ScanData[] sd = null;
228271d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
22833ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande                sd = getScanResultsNative(sWlan0Index, flush);
22843ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande            }
22853ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande
22863ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande            if (sd != null) {
22873ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande                return sd;
2288f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
22893ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande                return new WifiScanner.ScanData[0];
2290f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            }
2291aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle        }
2292e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2293e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2294b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface HotlistEventHandler {
2295d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande        void onHotlistApFound (ScanResult[] result);
2296d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande        void onHotlistApLost  (ScanResult[] result);
2297e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2298e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2299b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static int sHotlistCmdId = 0;
2300b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static HotlistEventHandler sHotlistEventHandler;
2301e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2302b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private native static boolean setHotlistNative(int iface, int id,
2303e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            WifiScanner.HotlistSettings settings);
2304b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private native static boolean resetHotlistNative(int iface, int id);
2305e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
230618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setHotlist(WifiScanner.HotlistSettings settings,
230718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            HotlistEventHandler eventHandler) {
2308956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
230971d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2310f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sHotlistCmdId != 0) {
2311f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2312f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } else {
2313f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sHotlistCmdId = getNewCmdIdLocked();
2314f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2315f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
2316f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sHotlistEventHandler = eventHandler;
2317f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (setHotlistNative(sWlan0Index, sHotlistCmdId, settings) == false) {
2318f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sHotlistEventHandler = null;
2319f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2320f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2321e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2322f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return true;
2323f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
2324e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde                return false;
2325e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
2326e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
2327e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2328e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
232918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void resetHotlist() {
2330956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
233171d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2332f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sHotlistCmdId != 0) {
2333f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    resetHotlistNative(sWlan0Index, sHotlistCmdId);
2334f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sHotlistCmdId = 0;
2335f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sHotlistEventHandler = null;
2336f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2337e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
23387f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        }
23397f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
2340e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
234118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
234218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static void onHotlistApFound(int id, ScanResult[] results) {
234318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        HotlistEventHandler handler = sHotlistEventHandler;
234418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null) {
234518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onHotlistApFound(results);
234618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        } else {
234718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            /* this can happen because of race conditions */
234818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            Log.d(TAG, "Ignoring hotlist AP found event");
2349d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande        }
2350d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande    }
2351d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande
235218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
235318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static void onHotlistApLost(int id, ScanResult[] results) {
235418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        HotlistEventHandler handler = sHotlistEventHandler;
235518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null) {
235618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onHotlistApLost(results);
235718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        } else {
235818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            /* this can happen because of race conditions */
235918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            Log.d(TAG, "Ignoring hotlist AP lost event");
2360aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle        }
2361e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2362e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2363b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface SignificantWifiChangeEventHandler {
2364e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        void onChangesFound(ScanResult[] result);
2365e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2366e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2367b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static SignificantWifiChangeEventHandler sSignificantWifiChangeHandler;
2368b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static int sSignificantWifiChangeCmdId;
2369e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2370b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean trackSignificantWifiChangeNative(
2371e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            int iface, int id, WifiScanner.WifiChangeSettings settings);
2372b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean untrackSignificantWifiChangeNative(int iface, int id);
2373e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
237418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean trackSignificantWifiChange(
2375b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande            WifiScanner.WifiChangeSettings settings, SignificantWifiChangeEventHandler handler) {
2376956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
237771d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2378f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sSignificantWifiChangeCmdId != 0) {
2379f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2380f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } else {
2381f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sSignificantWifiChangeCmdId = getNewCmdIdLocked();
2382f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2383f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
2384f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sSignificantWifiChangeHandler = handler;
2385851075f4f345d98de885bd2f6b833944b282097eMitchell Wills                if (trackSignificantWifiChangeNative(sWlan0Index, sSignificantWifiChangeCmdId,
2386851075f4f345d98de885bd2f6b833944b282097eMitchell Wills                        settings) == false) {
2387f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sSignificantWifiChangeHandler = null;
2388f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2389f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2390e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2391f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return true;
2392f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
2393e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde                return false;
2394e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
2395e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2396e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
2397e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2398e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
239918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void untrackSignificantWifiChange() {
2400956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
240171d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2402f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sSignificantWifiChangeCmdId != 0) {
2403f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    untrackSignificantWifiChangeNative(sWlan0Index, sSignificantWifiChangeCmdId);
2404f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sSignificantWifiChangeCmdId = 0;
2405f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sSignificantWifiChangeHandler = null;
2406f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2407e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
2408e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
2409e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2410e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
241118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
241218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static void onSignificantWifiChange(int id, ScanResult[] results) {
241318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        SignificantWifiChangeEventHandler handler = sSignificantWifiChangeHandler;
241418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null) {
241518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onChangesFound(results);
241618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        } else {
2417f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            /* this can happen because of race conditions */
241818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            Log.d(TAG, "Ignoring significant wifi change");
2419aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle        }
2420e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2421e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
242218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public WifiLinkLayerStats getWifiLinkLayerStats(String iface) {
2423200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        // TODO: use correct iface name to Index translation
2424200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        if (iface == null) return null;
2425956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
242671d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2427aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle                return getWifiLinkLayerStatsNative(sWlan0Index);
2428f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
2429f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return null;
2430f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            }
2431aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle        }
24325c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales    }
24335c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
243418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void setWifiLinkLayerStats(String iface, int enable) {
2435d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle        if (iface == null) return;
2436956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
243771d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2438d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle                setWifiLinkLayerStatsNative(sWlan0Index, enable);
2439d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle            }
2440d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle        }
2441d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle    }
2442d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle
2443c35361d54d4885c3174499e4ad46d3324387a9bbVinit Deshpande    public static native int getSupportedFeatureSetNative(int iface);
244418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedFeatureSet() {
2445956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
244671d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2447f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return getSupportedFeatureSetNative(sWlan0Index);
2448f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
2449f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                Log.d(TAG, "Failing getSupportedFeatureset because HAL isn't started");
2450f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return 0;
2451f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            }
2452f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        }
2453a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    }
2454143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2455143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    /* Rtt related commands/events */
2456143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public static interface RttEventHandler {
2457143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void onRttResults(RttManager.RttResult[] result);
2458143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2459143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2460143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static RttEventHandler sRttEventHandler;
2461143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static int sRttCmdId;
2462143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
246318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
246418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static void onRttResults(int id, RttManager.RttResult[] results) {
246518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        RttEventHandler handler = sRttEventHandler;
246618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null && id == sRttCmdId) {
246702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            Log.d(TAG, "Received " + results.length + " rtt results");
246818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onRttResults(results);
2469143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            sRttCmdId = 0;
2470143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        } else {
247118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            Log.d(TAG, "RTT Received event for unknown cmd = " + id +
247218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    ", current id = " + sRttCmdId);
2473143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
2474143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2475143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2476143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static native boolean requestRangeNative(
2477143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            int iface, int id, RttManager.RttParams[] params);
2478143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static native boolean cancelRangeRequestNative(
2479143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            int iface, int id, RttManager.RttParams[] params);
2480143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
248118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean requestRtt(
2482143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttManager.RttParams[] params, RttEventHandler handler) {
2483956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
248471d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2485f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sRttCmdId != 0) {
248607412d5e025b85de146399081db4851088d86daeWei Wang                    Log.w(TAG, "Last one is still under measurement!");
2487f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2488f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } else {
2489f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sRttCmdId = getNewCmdIdLocked();
2490f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2491f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sRttEventHandler = handler;
2492f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return requestRangeNative(sWlan0Index, sRttCmdId, params);
2493143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            } else {
2494f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return false;
2495143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
2496143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
2497143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2498143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
249918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean cancelRtt(RttManager.RttParams[] params) {
2500956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
250171d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2502f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sRttCmdId == 0) {
2503f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2504f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2505143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2506f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sRttCmdId = 0;
2507f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe
2508f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (cancelRangeRequestNative(sWlan0Index, sRttCmdId, params)) {
2509f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sRttEventHandler = null;
2510f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return true;
2511f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } else {
25125cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe                    Log.e(TAG, "RTT cancel Request failed");
2513f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2514f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2515143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            } else {
2516143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                return false;
2517143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
2518143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
2519143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2520042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
252168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    private static int sRttResponderCmdId = 0;
252268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
252368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    private static native ResponderConfig enableRttResponderNative(int iface, int commandId,
252468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            int timeoutSeconds, WifiChannelInfo channelHint);
252568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
252668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder
252768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * role is successfully enabled, {@code null} otherwise.
252868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
252968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    @Nullable
253068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    public ResponderConfig enableRttResponder(int timeoutSeconds) {
253168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        synchronized (sLock) {
253268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (!isHalStarted()) return null;
253368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (sRttResponderCmdId != 0) {
253468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                if (DBG) Log.e(mTAG, "responder mode already enabled - this shouldn't happen");
253568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                return null;
253668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
253768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            int id = getNewCmdIdLocked();
253868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            ResponderConfig config = enableRttResponderNative(
253968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    sWlan0Index, id, timeoutSeconds, null);
254068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (config != null) sRttResponderCmdId = id;
254168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (DBG) Log.d(TAG, "enabling rtt " + (config != null));
254268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            return config;
254368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        }
254468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    }
254568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
254668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    private static native boolean disableRttResponderNative(int iface, int commandId);
254768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
254868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled,
254968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * {@code false} otherwise.
255068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
255168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    public boolean disableRttResponder() {
255268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        synchronized (sLock) {
255368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (!isHalStarted()) return false;
255468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (sRttResponderCmdId == 0) {
255568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                Log.e(mTAG, "responder role not enabled yet");
255668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                return true;
255768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
255868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            sRttResponderCmdId = 0;
255968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            return disableRttResponderNative(sWlan0Index, sRttResponderCmdId);
256068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        }
256168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    }
256268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
2563042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande    private static native boolean setScanningMacOuiNative(int iface, byte[] oui);
2564042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
256518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setScanningMacOui(byte[] oui) {
2566956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
256771d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2568042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande                return setScanningMacOuiNative(sWlan0Index, oui);
2569042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande            } else {
2570042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande                return false;
2571042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande            }
2572042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande        }
2573042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande    }
2574efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande
2575efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande    private static native int[] getChannelsForBandNative(
2576efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande            int iface, int band);
2577efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande
257818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int [] getChannelsForBand(int band) {
2579956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
2580ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe            if (isHalStarted()) {
2581ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe                return getChannelsForBandNative(sWlan0Index, band);
258218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            } else {
2583ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe                return null;
2584ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe            }
2585efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande        }
2586efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande    }
25870465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande
2588ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe    private static native boolean isGetChannelsForBandSupportedNative();
258918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean isGetChannelsForBandSupported(){
2590956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
2591ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe            if (isHalStarted()) {
2592ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe                return isGetChannelsForBandSupportedNative();
259318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            } else {
2594ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe                return false;
2595ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe            }
2596ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe        }
2597ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe    }
25980465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande
25990465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande    private static native boolean setDfsFlagNative(int iface, boolean dfsOn);
260018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setDfsFlag(boolean dfsOn) {
2601956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
260271d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
26030465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande                return setDfsFlagNative(sWlan0Index, dfsOn);
26040465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande            } else {
26050465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande                return false;
26060465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande            }
26070465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande        }
26080465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande    }
2609b830d76fbf5fa4077531b516066faa2fdbb92e81xinhe
261012cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe    private static native RttManager.RttCapabilities getRttCapabilitiesNative(int iface);
261118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public RttManager.RttCapabilities getRttCapabilities() {
2612956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
261371d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
261412cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe                return getRttCapabilitiesNative(sWlan0Index);
261518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            } else {
261612cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe                return null;
261712cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe            }
261812cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe        }
261912cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe    }
2620939177ff615062ec826601d536466875d8457375xinhe
2621e1dab7a2e3ab5911f812a302b4beed1f6eb5aba7Paul Jensen    private static native ApfCapabilities getApfCapabilitiesNative(int iface);
2622e1dab7a2e3ab5911f812a302b4beed1f6eb5aba7Paul Jensen    public ApfCapabilities getApfCapabilities() {
26236609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen        synchronized (sLock) {
26246609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            if (isHalStarted()) {
2625e1dab7a2e3ab5911f812a302b4beed1f6eb5aba7Paul Jensen                return getApfCapabilitiesNative(sWlan0Index);
26266609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            } else {
26276609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen                return null;
26286609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            }
26296609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen        }
26306609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
26316609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
26326609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    private static native boolean installPacketFilterNative(int iface, byte[] filter);
26336609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    public boolean installPacketFilter(byte[] filter) {
26346609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen        synchronized (sLock) {
26356609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            if (isHalStarted()) {
26366609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen                return installPacketFilterNative(sWlan0Index, filter);
26376609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            } else {
26386609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen                return false;
26396609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            }
26406609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen        }
26416609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
26426609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
2643939177ff615062ec826601d536466875d8457375xinhe    private static native boolean setCountryCodeHalNative(int iface, String CountryCode);
264418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setCountryCodeHal(String CountryCode) {
2645956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
264671d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2647939177ff615062ec826601d536466875d8457375xinhe                return setCountryCodeHalNative(sWlan0Index, CountryCode);
2648939177ff615062ec826601d536466875d8457375xinhe            } else {
2649939177ff615062ec826601d536466875d8457375xinhe                return false;
2650939177ff615062ec826601d536466875d8457375xinhe            }
2651939177ff615062ec826601d536466875d8457375xinhe        }
2652939177ff615062ec826601d536466875d8457375xinhe    }
2653939177ff615062ec826601d536466875d8457375xinhe
2654d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    /* Rtt related commands/events */
2655d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    public abstract class TdlsEventHandler {
2656d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        abstract public void onTdlsStatus(String macAddr, int status, int reason);
2657d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2658d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2659d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    private static TdlsEventHandler sTdlsEventHandler;
2660d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2661d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    private static native boolean enableDisableTdlsNative(int iface, boolean enable,
2662d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe            String macAddr);
266318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean enableDisableTdls(boolean enable, String macAdd, TdlsEventHandler tdlsCallBack) {
2664956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
2665f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            sTdlsEventHandler = tdlsCallBack;
2666f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            return enableDisableTdlsNative(sWlan0Index, enable, macAdd);
2667d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        }
2668d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2669d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2670d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    // Once TDLS per mac and event feature is implemented, this class definition should be
2671d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    // moved to the right place, like WifiManager etc
2672d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    public static class TdlsStatus {
2673d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        int channel;
2674d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        int global_operating_class;
2675d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        int state;
2676d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        int reason;
2677d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2678d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    private static native TdlsStatus getTdlsStatusNative(int iface, String macAddr);
267918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public TdlsStatus getTdlsStatus(String macAdd) {
2680956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
268171d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2682d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe                return getTdlsStatusNative(sWlan0Index, macAdd);
2683d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe            } else {
2684d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe                return null;
2685d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe            }
2686d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        }
2687d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2688d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2689d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    //ToFix: Once TDLS per mac and event feature is implemented, this class definition should be
2690d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    // moved to the right place, like WifiStateMachine etc
2691d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    public static class TdlsCapabilities {
2692d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        /* Maximum TDLS session number can be supported by the Firmware and hardware */
2693d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        int maxConcurrentTdlsSessionNumber;
2694d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        boolean isGlobalTdlsSupported;
2695d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        boolean isPerMacTdlsSupported;
2696d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        boolean isOffChannelTdlsSupported;
2697d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2698d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2699d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2700d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2701d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    private static native TdlsCapabilities getTdlsCapabilitiesNative(int iface);
270218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public TdlsCapabilities getTdlsCapabilities () {
2703956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
270471d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2705d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe                return getTdlsCapabilitiesNative(sWlan0Index);
2706d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe            } else {
2707d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe                return null;
2708d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe            }
2709d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        }
2710d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2711d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
271218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static boolean onTdlsStatus(String macAddr, int status, int reason) {
271318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        TdlsEventHandler handler = sTdlsEventHandler;
271418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler == null) {
271518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            return false;
271618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        } else {
271718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onTdlsStatus(macAddr, status, reason);
271818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            return true;
271918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        }
2720d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2721d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2722a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    //---------------------------------------------------------------------------------
2723a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2724a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    /* Wifi Logger commands/events */
27257d6301ead19afdf3de37455e9ed133c25b4938cdVinit Deshpande
2726a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    public static interface WifiLoggerEventHandler {
27270bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onRingBufferData(RingBufferStatus status, byte[] buffer);
27280bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onWifiAlert(int errorCode, byte[] buffer);
2729a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2730a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2731a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    private static WifiLoggerEventHandler sWifiLoggerEventHandler = null;
2732a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
273318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
27340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static void onRingBufferData(RingBufferStatus status, byte[] buffer) {
273518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        WifiLoggerEventHandler handler = sWifiLoggerEventHandler;
273618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null)
273718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onRingBufferData(status, buffer);
273803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
273903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
274018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
27410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static void onWifiAlert(byte[] buffer, int errorCode) {
274218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        WifiLoggerEventHandler handler = sWifiLoggerEventHandler;
274318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null)
274418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onWifiAlert(errorCode, buffer);
274503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
274603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2747b797893fc1966803d0c013faac42e6396a37a384xinhe    private static int sLogCmdId = -1;
2748b797893fc1966803d0c013faac42e6396a37a384xinhe    private static native boolean setLoggingEventHandlerNative(int iface, int id);
274918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setLoggingEventHandler(WifiLoggerEventHandler handler) {
2750956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
2751b797893fc1966803d0c013faac42e6396a37a384xinhe            if (isHalStarted()) {
2752b797893fc1966803d0c013faac42e6396a37a384xinhe                int oldId =  sLogCmdId;
2753b797893fc1966803d0c013faac42e6396a37a384xinhe                sLogCmdId = getNewCmdIdLocked();
2754b797893fc1966803d0c013faac42e6396a37a384xinhe                if (!setLoggingEventHandlerNative(sWlan0Index, sLogCmdId)) {
2755b797893fc1966803d0c013faac42e6396a37a384xinhe                    sLogCmdId = oldId;
2756b797893fc1966803d0c013faac42e6396a37a384xinhe                    return false;
2757b797893fc1966803d0c013faac42e6396a37a384xinhe                }
2758b797893fc1966803d0c013faac42e6396a37a384xinhe                sWifiLoggerEventHandler = handler;
2759b797893fc1966803d0c013faac42e6396a37a384xinhe                return true;
2760b797893fc1966803d0c013faac42e6396a37a384xinhe            } else {
2761b797893fc1966803d0c013faac42e6396a37a384xinhe                return false;
2762b797893fc1966803d0c013faac42e6396a37a384xinhe            }
276303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
276403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
276503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
276603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native boolean startLoggingRingBufferNative(int iface, int verboseLevel,
27670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            int flags, int minIntervalSec ,int minDataSize, String ringName);
276818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval,
276903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            int minDataSize, String ringName){
2770956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
277171d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
277203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return startLoggingRingBufferNative(sWlan0Index, verboseLevel, flags, maxInterval,
277303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                        minDataSize, ringName);
277403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
277503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return false;
277603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
277703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
277803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
277903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
278003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native int getSupportedLoggerFeatureSetNative(int iface);
278118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedLoggerFeatureSet() {
2782956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
278371d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
278403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return getSupportedLoggerFeatureSetNative(sWlan0Index);
278503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
2786f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return 0;
278703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
278803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
278903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
279003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2791b797893fc1966803d0c013faac42e6396a37a384xinhe    private static native boolean resetLogHandlerNative(int iface, int id);
279218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean resetLogHandler() {
2793956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
2794b797893fc1966803d0c013faac42e6396a37a384xinhe            if (isHalStarted()) {
2795b797893fc1966803d0c013faac42e6396a37a384xinhe                if (sLogCmdId == -1) {
2796b797893fc1966803d0c013faac42e6396a37a384xinhe                    Log.e(TAG,"Can not reset handler Before set any handler");
2797b797893fc1966803d0c013faac42e6396a37a384xinhe                    return false;
2798b797893fc1966803d0c013faac42e6396a37a384xinhe                }
2799b797893fc1966803d0c013faac42e6396a37a384xinhe                sWifiLoggerEventHandler = null;
2800b797893fc1966803d0c013faac42e6396a37a384xinhe                if (resetLogHandlerNative(sWlan0Index, sLogCmdId)) {
2801b797893fc1966803d0c013faac42e6396a37a384xinhe                    sLogCmdId = -1;
2802b797893fc1966803d0c013faac42e6396a37a384xinhe                    return true;
2803b797893fc1966803d0c013faac42e6396a37a384xinhe                } else {
2804b797893fc1966803d0c013faac42e6396a37a384xinhe                    return false;
2805b797893fc1966803d0c013faac42e6396a37a384xinhe                }
2806b797893fc1966803d0c013faac42e6396a37a384xinhe            } else {
2807b797893fc1966803d0c013faac42e6396a37a384xinhe                return false;
2808b797893fc1966803d0c013faac42e6396a37a384xinhe            }
2809b797893fc1966803d0c013faac42e6396a37a384xinhe        }
2810b797893fc1966803d0c013faac42e6396a37a384xinhe    }
2811b797893fc1966803d0c013faac42e6396a37a384xinhe
281203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native String getDriverVersionNative(int iface);
281318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getDriverVersion() {
2814956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
281571d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
281603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return getDriverVersionNative(sWlan0Index);
281703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
2818f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return "";
281903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
282003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
282103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
282203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
282303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
282403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native String getFirmwareVersionNative(int iface);
282518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getFirmwareVersion() {
2826956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
282771d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
282803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return getFirmwareVersionNative(sWlan0Index);
282903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
2830f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return "";
283103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
283203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
283303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
283403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
28350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static class RingBufferStatus{
28360bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        String name;
28370bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int flag;
28380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferId;
28390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferByteSize;
28400bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int verboseLevel;
28410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenBytes;
28420bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int readBytes;
28430bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenRecords;
28440bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
284553f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        // Bit masks for interpreting |flag|
284653f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_BINARY_ENTRIES = (1 << 0);
284753f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_ASCII_ENTRIES = (1 << 1);
284853f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_PER_PACKET_ENTRIES = (1 << 2);
284953f278b6fed422a18d763b07216a21e96d9445f9Michael Plass
28500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
28510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public String toString() {
28520bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
28530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel +
28540bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenBytes: " + writtenBytes + " readBytes: " + readBytes +
28550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenRecords: " + writtenRecords;
28560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
28570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
28580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
28590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static native RingBufferStatus[] getRingBufferStatusNative(int iface);
286018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public RingBufferStatus[] getRingBufferStatus() {
2861956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
286271d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
286303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return getRingBufferStatusNative(sWlan0Index);
286403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
286503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return null;
286603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
286703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
286803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
286903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
287003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native boolean getRingBufferDataNative(int iface, String ringName);
287118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean getRingBufferData(String ringName) {
2872956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
287371d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
287403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return getRingBufferDataNative(sWlan0Index, ringName);
287503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
287603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return false;
287703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
287803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
287903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
288003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
288118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static byte[] mFwMemoryDump;
288218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
288303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static void onWifiFwMemoryAvailable(byte[] buffer) {
288498dca3397c0049d3cfb9c97e2b021c5ee3a2e1bdxinhe        mFwMemoryDump = buffer;
288598dca3397c0049d3cfb9c97e2b021c5ee3a2e1bdxinhe        if (DBG) {
288698dca3397c0049d3cfb9c97e2b021c5ee3a2e1bdxinhe            Log.d(TAG, "onWifiFwMemoryAvailable is called and buffer length is: " +
288798dca3397c0049d3cfb9c97e2b021c5ee3a2e1bdxinhe                    (buffer == null ? 0 :  buffer.length));
288898dca3397c0049d3cfb9c97e2b021c5ee3a2e1bdxinhe        }
288903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
2890127f7244183786e6ccae09e81eeccdac31973e69xinhe
289103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native boolean getFwMemoryDumpNative(int iface);
289218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public byte[] getFwMemoryDump() {
2893956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
289471d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
28950bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                if(getFwMemoryDumpNative(sWlan0Index)) {
28960bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    byte[] fwMemoryDump = mFwMemoryDump;
289703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                    mFwMemoryDump = null;
28980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    return fwMemoryDump;
28990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                } else {
29000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    return null;
290103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                }
290203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
2903f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            return null;
2904a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle        }
2905a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2906dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
2907d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    private static native byte[] getDriverStateDumpNative(int iface);
2908d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    /** Fetch the driver state, for driver debugging. */
2909d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    public byte[] getDriverStateDump() {
2910d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal        synchronized (sLock) {
2911d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            if (isHalStarted()) {
2912d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                return getDriverStateDumpNative(sWlan0Index);
2913d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            } else {
2914d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                return null;
2915d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            }
2916d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal        }
2917d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    }
2918d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal
2919dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    //---------------------------------------------------------------------------------
292009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /* Packet fate API */
292109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
292209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
292309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    abstract static class FateReport {
2924eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int USEC_PER_MSEC = 1000;
2925eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // The driver timestamp is a 32-bit counter, in microseconds. This field holds the
2926eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // maximal value of a driver timestamp in milliseconds.
2927eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000);
2928eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
2929eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
293009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFate;
293109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final long mDriverTimestampUSec;
293209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFrameType;
293309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte[] mFrameBytes;
2934eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final long mEstimatedWallclockMSec;
293509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
293609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
293709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFate = fate;
293809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mDriverTimestampUSec = driverTimestampUSec;
2939eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            mEstimatedWallclockMSec =
2940eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    convertDriverTimestampUSecToWallclockMSec(mDriverTimestampUSec);
294109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameType = frameType;
294209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameBytes = frameBytes;
294309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
29440fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2945590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toTableRowString() {
2946590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2947590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2948590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
2949eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            dateFormatter.setTimeZone(TimeZone.getDefault());
2950eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2951eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    mDriverTimestampUSec,
2952eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    dateFormatter.format(new Date(mEstimatedWallclockMSec)),
2953eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    directionToString(), fateToString(), parser.mMostSpecificProtocolString,
2954eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    parser.mTypeString, parser.mResultString);
2955590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2956590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2957590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
2958590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toVerboseStringWithPiiAllowed() {
29590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            StringWriter sw = new StringWriter();
29600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            PrintWriter pw = new PrintWriter(sw);
2961590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
29620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame direction: %s\n", directionToString());
29630fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame timestamp: %d\n", mDriverTimestampUSec);
29640fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame fate: %s\n", fateToString());
29650fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame type: %s\n", frameTypeToString(mFrameType));
2966590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol: %s\n", parser.mMostSpecificProtocolString);
2967590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol type: %s\n", parser.mTypeString);
29680fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame length: %d\n", mFrameBytes.length);
29690fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("Frame bytes");
2970590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.append(HexDump.dumpHexString(mFrameBytes));  // potentially contains PII
29710fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("\n");
29720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return sw.toString();
29730fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
29740fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2975590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        /* Returns a header to match the output of toTableRowString(). */
2976590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public static String getTableHeader() {
2977590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2978590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2979eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("\n%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2980eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "Time usec", "Walltime", "Direction", "Fate", "Protocol", "Type", "Result");
2981eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2982eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "---------", "--------", "---------", "----", "--------", "----", "------");
2983590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2984590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2985590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
29860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String directionToString();
29870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
29880fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String fateToString();
29890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
29900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        private static String frameTypeToString(byte frameType) {
29910fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (frameType) {
29920fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_UNKNOWN:
29930fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "unknown";
29940fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_ETHERNET_II:
29950fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "data";
29960fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_80211_MGMT:
29970fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "802.11 management";
29980fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
29990fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(frameType);
30000fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
30010fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
3002eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
3003eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        /**
3004eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * Converts a driver timestamp to a wallclock time, based on the current
3005eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * BOOTTIME to wallclock mapping. The driver timestamp is a 32-bit counter of
3006eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * microseconds, with the same base as BOOTTIME.
3007eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         */
3008eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        private static long convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec) {
3009eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long wallclockMillisNow = System.currentTimeMillis();
3010eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long boottimeMillisNow = SystemClock.elapsedRealtime();
3011eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long driverTimestampMillis = driverTimestampUSec / USEC_PER_MSEC;
3012eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
3013eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            long boottimeTimestampMillis = boottimeMillisNow % MAX_DRIVER_TIMESTAMP_MSEC;
3014eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            if (boottimeTimestampMillis < driverTimestampMillis) {
3015eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // The 32-bit microsecond count has wrapped between the time that the driver
3016eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // recorded the packet, and the call to this function. Adjust the BOOTTIME
3017eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // timestamp, to compensate.
3018eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                //
3019eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // Note that overflow is not a concern here, since the result is less than
3020eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // 2 * MAX_DRIVER_TIMESTAMP_MSEC. (Given the modulus operation above,
3021eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // boottimeTimestampMillis must be less than MAX_DRIVER_TIMESTAMP_MSEC.) And, since
3022eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // MAX_DRIVER_TIMESTAMP_MSEC is an int, 2 * MAX_DRIVER_TIMESTAMP_MSEC must fit
3023eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // within a long.
3024eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                boottimeTimestampMillis += MAX_DRIVER_TIMESTAMP_MSEC;
3025eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            }
3026eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
3027eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long millisSincePacketTimestamp = boottimeTimestampMillis - driverTimestampMillis;
3028eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            return wallclockMillisNow - millisSincePacketTimestamp;
3029eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        }
303009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
303109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
303209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
303309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one outbound packet.
303409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
303509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
303609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class TxFateReport extends FateReport {
303709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
303809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
303909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
30400fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
30410fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
30420fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
30430fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "TX";
30440fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
30450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
30460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
30470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
30480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
30490fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_ACKED:
30500fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "acked";
30510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_SENT:
30520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "sent";
30530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_QUEUED:
30540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
30550fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID:
30560fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
30570fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS:
30580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
30590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER:
30600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
30610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED:
30620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
30630fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID:
30640fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
30650fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS:
30660fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
30670fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER:
30680fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
30690fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
30700fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
30710fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
30720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
307309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
307409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
307509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
307609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one inbound packet.
307709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
307809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
307909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class RxFateReport extends FateReport {
308009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
308109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
308209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
30830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
30840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
30850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
30860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "RX";
30870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
30880fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
30890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
30900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
30910fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
30920fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_SUCCESS:
30930fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "success";
30940fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_QUEUED:
30950fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
30960fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER:
30970fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (filter)";
30980fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID:
30990fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
31000fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS:
31010fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
31020fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER:
31030fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
31040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED:
31050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
31060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER:
31070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (filter)";
31080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID:
31090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
31100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS:
31110fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
31120fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER:
31130fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
31140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
31150fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
31160fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
31170fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
311809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
311909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
312009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    private static native int startPktFateMonitoringNative(int iface);
31210fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
31220fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Ask the HAL to enable packet fate monitoring. Fails unless HAL is started.
31230fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
31240fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean startPktFateMonitoring() {
31250fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        synchronized (sLock) {
31260fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            if (isHalStarted()) {
31270fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                return startPktFateMonitoringNative(sWlan0Index) == WIFI_SUCCESS;
31280fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            } else {
31290fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                return false;
31300fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
31310fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
31320fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
31330fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
313409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    private static native int getTxPktFatesNative(int iface, TxFateReport[] reportBufs);
31350fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
31360fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent TX packet fates from the HAL. Fails unless HAL is started.
31370fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
31380fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean getTxPktFates(TxFateReport[] reportBufs) {
31390fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        synchronized (sLock) {
31400fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            if (isHalStarted()) {
31410fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                int res = getTxPktFatesNative(sWlan0Index, reportBufs);
31420fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                if (res != WIFI_SUCCESS) {
31430fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    Log.e(TAG, "getTxPktFatesNative returned " + res);
31440fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return false;
31450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                } else {
31460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return true;
31470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                }
31480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            } else {
31490fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                return false;
31500fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
31510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
31520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
31530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
315409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    private static native int getRxPktFatesNative(int iface, RxFateReport[] reportBufs);
31550fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
31560fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent RX packet fates from the HAL. Fails unless HAL is started.
31570fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
31580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean getRxPktFates(RxFateReport[] reportBufs) {
31590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        synchronized (sLock) {
31600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            if (isHalStarted()) {
31610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                int res = getRxPktFatesNative(sWlan0Index, reportBufs);
31620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                if (res != WIFI_SUCCESS) {
31630fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    Log.e(TAG, "getRxPktFatesNative returned " + res);
31640fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return false;
31650fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                } else {
31660fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return true;
31670fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                }
31680fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            } else {
31690fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                return false;
31700fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
31710fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
31720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
317309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
317409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    //---------------------------------------------------------------------------------
31755c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius    /* Configure ePNO/PNO */
31769bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    private static PnoEventHandler sPnoEventHandler;
31779bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    private static int sPnoCmdId = 0;
3178dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
31799bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    private static native boolean setPnoListNative(int iface, int id, PnoSettings settings);
318018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
31815c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius    /**
31829bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Set the PNO settings & the network list in HAL to start PNO.
31839bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @param settings PNO settings and network list.
31849bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @param eventHandler Handler to receive notifications back during PNO scan.
31859bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @return true if success, false otherwise
31865c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius     */
31879bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public boolean setPnoList(PnoSettings settings, PnoEventHandler eventHandler) {
31889bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        Log.e(TAG, "setPnoList cmd " + sPnoCmdId);
3189dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
31909bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        synchronized (sLock) {
31919bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius            if (isHalStarted()) {
31929bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                sPnoCmdId = getNewCmdIdLocked();
31939bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                sPnoEventHandler = eventHandler;
31949bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                if (setPnoListNative(sWlan0Index, sPnoCmdId, settings)) {
31959bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                    return true;
31969bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                }
3197dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle            }
31989bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius            sPnoEventHandler = null;
31999bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius            return false;
3200dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        }
3201dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    }
3202dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
32039bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
32049bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Set the PNO network list in HAL to start PNO.
32059bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @param list PNO network list.
32069bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @param eventHandler Handler to receive notifications back during PNO scan.
32079bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @return true if success, false otherwise
32089bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
32099bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public boolean setPnoList(PnoNetwork[] list, PnoEventHandler eventHandler) {
32109bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        PnoSettings settings = new PnoSettings();
32119bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        settings.networkList = list;
32129bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        return setPnoList(settings, eventHandler);
3213dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    }
3214dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
32159bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    private static native boolean resetPnoListNative(int iface, int id);
3216dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
32179bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
32189bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Reset the PNO settings in HAL to stop PNO.
32199bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @return true if success, false otherwise
32209bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
32219bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public boolean resetPnoList() {
32229bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        Log.e(TAG, "resetPnoList cmd " + sPnoCmdId);
3223dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
3224956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
322571d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
3226f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sPnoCmdId = getNewCmdIdLocked();
32279bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                sPnoEventHandler = null;
32289bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                if (resetPnoListNative(sWlan0Index, sPnoCmdId)) {
3229f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return true;
3230f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
3231dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle            }
3232f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            return false;
3233dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        }
3234dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    }
3235dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
323618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
32373571366ac36c70746b9f013ec2b54482861c9292Randy Pan    private static void onPnoNetworkFound(int id, ScanResult[] results, int[] beaconCaps) {
3238dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        if (results == null) {
3239dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle            Log.e(TAG, "onPnoNetworkFound null results");
3240dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle            return;
3241dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
3242dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        }
3243dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        Log.d(TAG, "WifiNative.onPnoNetworkFound result " + results.length);
3244dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
32459bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        PnoEventHandler handler = sPnoEventHandler;
324618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (sPnoCmdId != 0 && handler != null) {
324718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            for (int i=0; i<results.length; i++) {
324818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                Log.e(TAG, "onPnoNetworkFound SSID " + results[i].SSID
324918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                        + " " + results[i].level + " " + results[i].frequency);
3250dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
32511ab129e587d334a144a0bca5323c27985397a403Randy Pan                populateScanResult(results[i], beaconCaps[i], "onPnoNetworkFound ");
325218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                results[i].wifiSsid = WifiSsid.createFromAsciiEncoded(results[i].SSID);
3253dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle            }
325418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
325518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onPnoNetworkFound(results);
325618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        } else {
325718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            /* this can happen because of race conditions */
325818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            Log.d(TAG, "Ignoring Pno Network found event");
3259dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        }
3260d4c25fd76644d5490700ae69fada4669de5193a1Pierre Vandwalle    }
3261d4c25fd76644d5490700ae69fada4669de5193a1Pierre Vandwalle
3262c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    private native static int startSendingOffloadedPacketNative(int iface, int idx,
3263c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham                                    byte[] srcMac, byte[] dstMac, byte[] pktData, int period);
3264c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
326518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int
3266c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    startSendingOffloadedPacket(int slot, KeepalivePacketData keepAlivePacket, int period) {
3267c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham        Log.d(TAG, "startSendingOffloadedPacket slot=" + slot + " period=" + period);
32683bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham
32693bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        String[] macAddrStr = getMacAddress().split(":");
32703bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        byte[] srcMac = new byte[6];
32713bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        for(int i = 0; i < 6; i++) {
32723bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham            Integer hexVal = Integer.parseInt(macAddrStr[i], 16);
32733bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham            srcMac[i] = hexVal.byteValue();
32743bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        }
3275956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
3276c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            if (isHalStarted()) {
3277c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham                return startSendingOffloadedPacketNative(sWlan0Index, slot, srcMac,
327818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                        keepAlivePacket.dstMac, keepAlivePacket.data, period);
3279c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            } else {
3280c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham                return -1;
3281c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            }
3282c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham        }
3283c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
3284c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
3285c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    private native static int stopSendingOffloadedPacketNative(int iface, int idx);
3286c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
328718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int
3288c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    stopSendingOffloadedPacket(int slot) {
3289c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham        Log.d(TAG, "stopSendingOffloadedPacket " + slot);
3290956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
3291c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            if (isHalStarted()) {
3292c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham                return stopSendingOffloadedPacketNative(sWlan0Index, slot);
3293c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            } else {
3294c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham                return -1;
3295c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            }
3296c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham        }
3297c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
3298aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
3299aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    public static interface WifiRssiEventHandler {
3300aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        void onRssiThresholdBreached(byte curRssi);
3301aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
3302aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
3303aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    private static WifiRssiEventHandler sWifiRssiEventHandler;
3304aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
330518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
330618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static void onRssiThresholdBreached(int id, byte curRssi) {
330718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        WifiRssiEventHandler handler = sWifiRssiEventHandler;
330818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null) {
330918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onRssiThresholdBreached(curRssi);
331018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        }
3311aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
3312aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
3313aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    private native static int startRssiMonitoringNative(int iface, int id,
3314aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                                        byte maxRssi, byte minRssi);
3315aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
3316aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    private static int sRssiMonitorCmdId = 0;
3317aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
331818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int startRssiMonitoring(byte maxRssi, byte minRssi,
3319aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                                                WifiRssiEventHandler rssiEventHandler) {
3320aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        Log.d(TAG, "startRssiMonitoring: maxRssi=" + maxRssi + " minRssi=" + minRssi);
3321956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
332218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            sWifiRssiEventHandler = rssiEventHandler;
3323aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            if (isHalStarted()) {
3324ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                if (sRssiMonitorCmdId != 0) {
3325ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                    stopRssiMonitoring();
3326ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                }
3327ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills
3328aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                sRssiMonitorCmdId = getNewCmdIdLocked();
3329aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                Log.d(TAG, "sRssiMonitorCmdId = " + sRssiMonitorCmdId);
3330ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                int ret = startRssiMonitoringNative(sWlan0Index, sRssiMonitorCmdId,
3331ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                        maxRssi, minRssi);
3332ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                if (ret != 0) { // if not success
3333ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                    sRssiMonitorCmdId = 0;
3334ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                }
3335ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                return ret;
3336aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            } else {
3337aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                return -1;
3338aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            }
3339aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        }
3340aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
3341aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
3342aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    private native static int stopRssiMonitoringNative(int iface, int idx);
3343aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
334418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int stopRssiMonitoring() {
3345aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        Log.d(TAG, "stopRssiMonitoring, cmdId " + sRssiMonitorCmdId);
3346956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
3347aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            if (isHalStarted()) {
3348ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                int ret = 0;
3349ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                if (sRssiMonitorCmdId != 0) {
3350ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                    ret = stopRssiMonitoringNative(sWlan0Index, sRssiMonitorCmdId);
3351ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                }
3352ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                sRssiMonitorCmdId = 0;
3353ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                return ret;
3354aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            } else {
3355aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                return -1;
3356aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            }
3357aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        }
3358aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
33595ea42964ba17901a8d724736b450ace6ed48880fPrerepa Viswanadham
33605ea42964ba17901a8d724736b450ace6ed48880fPrerepa Viswanadham    private static native WifiWakeReasonAndCounts getWlanWakeReasonCountNative(int iface);
33616bf6986d359556010638dfae332b585162f06520Roshan Pius
33626bf6986d359556010638dfae332b585162f06520Roshan Pius    /**
33636bf6986d359556010638dfae332b585162f06520Roshan Pius     * Fetch the host wakeup reasons stats from wlan driver.
33646bf6986d359556010638dfae332b585162f06520Roshan Pius     * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver.
33656bf6986d359556010638dfae332b585162f06520Roshan Pius     */
33666bf6986d359556010638dfae332b585162f06520Roshan Pius    public WifiWakeReasonAndCounts getWlanWakeReasonCount() {
33676bf6986d359556010638dfae332b585162f06520Roshan Pius        Log.d(TAG, "getWlanWakeReasonCount " + sWlan0Index);
33686bf6986d359556010638dfae332b585162f06520Roshan Pius        synchronized (sLock) {
33696bf6986d359556010638dfae332b585162f06520Roshan Pius            if (isHalStarted()) {
33706bf6986d359556010638dfae332b585162f06520Roshan Pius                return getWlanWakeReasonCountNative(sWlan0Index);
33716bf6986d359556010638dfae332b585162f06520Roshan Pius            } else {
33726bf6986d359556010638dfae332b585162f06520Roshan Pius                return null;
33736bf6986d359556010638dfae332b585162f06520Roshan Pius            }
33746bf6986d359556010638dfae332b585162f06520Roshan Pius        }
33756bf6986d359556010638dfae332b585162f06520Roshan Pius    }
33763dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline
33773dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    private static native int configureNeighborDiscoveryOffload(int iface, boolean enabled);
33783dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline
33793dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    public boolean configureNeighborDiscoveryOffload(boolean enabled) {
33803dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline        final String logMsg =  "configureNeighborDiscoveryOffload(" + enabled + ")";
33813dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline        Log.d(mTAG, logMsg);
33823dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline        synchronized (sLock) {
33833dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline            if (isHalStarted()) {
33843dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline                final int ret = configureNeighborDiscoveryOffload(sWlan0Index, enabled);
33853dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline                if (ret != 0) {
33863dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline                    Log.d(mTAG, logMsg + " returned: " + ret);
33873dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline                }
33883dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline                return (ret == 0);
33893dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline            }
33903dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline        }
33913dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline        return false;
33923dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    }
3393da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3394da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    // Firmware roaming control.
3395da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3396da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3397da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class to retrieve firmware roaming capability parameters.
3398da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3399da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingCapabilities {
3400da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxBlacklistSize;
3401da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxWhitelistSize;
3402da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3403da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3404da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3405da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Query the firmware roaming capabilities.
3406da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3407da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public boolean getRoamingCapabilities(RoamingCapabilities capabilities) {
3408da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        Log.d(TAG, "getRoamingCapabilities ");
3409da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        try {
3410da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            if (mWifiVendorHal != null) {
3411da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan                return mWifiVendorHal.getRoamingCapabilities(capabilities);
3412da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            }
3413da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        } catch (UnsupportedOperationException e) {
3414da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        }
3415da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3416da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        return false;
3417da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3418da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3419da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3420da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Macros for controlling firmware roaming.
3421da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3422da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int DISABLE_FIRMWARE_ROAMING = 0;
3423da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int ENABLE_FIRMWARE_ROAMING = 1;
3424da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3425da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3426da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Enable/disable firmware roaming.
3427da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3428da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public int enableFirmwareRoaming(int state) {
3429da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        Log.d(TAG, "enableFirmwareRoaming: state =" + state);
3430da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        try {
3431da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            if (mWifiVendorHal != null) {
3432da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan                return mWifiVendorHal.enableFirmwareRoaming(state);
3433da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            }
3434da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        } catch (UnsupportedOperationException e) {
3435da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        }
3436da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3437da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        return -1;
3438da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3439da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3440da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3441da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class for specifying the roaming configurations.
3442da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3443da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingConfig {
3444da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> blacklistBssids;
3445da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> whitelistSsids;
3446da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3447da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3448da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3449da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Set firmware roaming configurations.
3450da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3451da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public boolean configureRoaming(RoamingConfig config) {
3452da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        Log.d(TAG, "configureRoaming ");
3453da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        try {
3454da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            if (mWifiVendorHal != null) {
3455da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan                return mWifiVendorHal.configureRoaming(config);
3456da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            }
3457da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        } catch (UnsupportedOperationException e) {
3458da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        }
3459da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3460da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        return false;
3461da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3462da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3463374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    /**
3464374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     * Reset firmware roaming configuration.
3465374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     */
3466374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    public boolean resetRoamingConfiguration() {
3467374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        Log.d(TAG, "resetRoamingConfiguration ");
3468374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        try {
3469374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan            if (mWifiVendorHal != null) {
3470374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan                // Pass in an empty RoamingConfig object which translates to zero size
3471374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan                // blacklist and whitelist to reset the firmware roaming configuration.
3472374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan                RoamingConfig config = new RoamingConfig();
3473374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan                return mWifiVendorHal.configureRoaming(config);
3474374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan            }
3475374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        } catch (UnsupportedOperationException e) {
3476374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        }
3477374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan
3478374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        return false;
3479374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    }
3480374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan
3481da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3482da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    StackTraceElement[] mTrace;
3483da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    void legacyHalWarning() {
3484da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        Thread cur = Thread.currentThread();
3485da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        mTrace = cur.getStackTrace();
3486da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        StackTraceElement s = mTrace[3];
3487da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        Log.e(TAG, "LEGACY HAL th " + cur.getId()
3488da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan                + " line " + s.getLineNumber() + " " + s.getMethodName());
3489da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
3491