WifiNative.java revision 5cf97c9b13cc06554c8901e63d55ba051b7e7881
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;
52c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
5318786eca942042388748b0d98979f21c9dff4a89Mitchell Willsimport libcore.util.HexEncoding;
5418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
55fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport org.json.JSONException;
56fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport org.json.JSONObject;
57fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport java.io.PrintWriter;
590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport java.io.StringWriter;
60fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.io.UnsupportedEncodingException;
61fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.net.URLDecoder;
62fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.net.URLEncoder;
635cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.ByteBuffer;
645cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.CharBuffer;
655cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.CharacterCodingException;
665cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.CharsetDecoder;
675cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.StandardCharsets;
68eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.text.SimpleDateFormat;
69155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.ArrayList;
703571366ac36c70746b9f013ec2b54482861c9292Randy Panimport java.util.BitSet;
71eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.util.Date;
72fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.util.HashMap;
73fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.util.Iterator;
74155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.List;
75155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.Locale;
76fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.util.Map;
771bf983a4211f547593a60523e43112ecdb5c8997Roshan Piusimport java.util.Objects;
789ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.Set;
79eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.util.TimeZone;
8018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
81fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
82155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/**
83155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Native calls for bring up/shut down of the supplicant daemon and for
84155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * sending requests to the supplicant daemon
85155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
86155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * waitForEvent() is called on the monitor thread for events. All other methods
87155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * must be serialized from the framework.
88155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
89155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * {@hide}
90155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
91155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepublic class WifiNative {
92b66b29a00da970ee75052e24f592c8d6c16bd0edxinhe    private static boolean DBG = false;
93155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
940fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    // Must match wifi_hal.h
950fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public static final int WIFI_SUCCESS = 0;
960fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
9718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /**
9818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * Hold this lock before calling supplicant or HAL methods
9918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * it is required to mutually exclude access to the driver
10018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
101956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public static final Object sLock = new Object();
102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
10315941215e85f924765f00779e9b5daff9ed6f118Randy Pan    private static final LocalLog sLocalLog = new LocalLog(8192);
104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
105eee8cb8bcecfa3b33ae03f7753359499a274e7a9mukesh agrawal    public @NonNull LocalLog getLocalLog() {
106956f54b391677d78379729dd14518edddf3c7660Etan Cohen        return sLocalLog;
10718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Register native functions */
110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    static {
111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Native functions are defined in libwifi-service.so */
112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        System.loadLibrary("wifi-service");
113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        registerNatives();
114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static native int registerNatives();
117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
11818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /*
11918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * Singleton WifiNative instances
120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
12118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static WifiNative wlanNativeInterface =
122c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang            new WifiNative(SystemProperties.get("wifi.interface", "wlan0"), true);
12318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static WifiNative getWlanNativeInterface() {
12418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return wlanNativeInterface;
12518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
127c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang    private static WifiNative p2pNativeInterface =
128c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang            // commands for p2p0 interface don't need prefix
129c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang            new WifiNative(SystemProperties.get("wifi.direct.interface", "p2p0"), false);
13018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static WifiNative getP2pNativeInterface() {
13118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return p2pNativeInterface;
13218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
135d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    // TODO(b/34884202): Set this to true to enable HIDL once we're fully ready.
136d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    private static final boolean HIDL_ENABLE = false;
13724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    public static final boolean HIDL_SUP_ENABLE = false;
13818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final String mTAG;
13918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final String mInterfaceName;
14018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final String mInterfacePrefix;
141b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    private SupplicantStaIfaceHal mSupplicantStaIfaceHal;
14279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private SupplicantP2pIfaceHal mSupplicantP2pIfaceHal;
1438c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    private WifiVendorHal mWifiVendorHal;
14470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    private WificondControl mWificondControl;
145a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    private WifiSupplicantControl mWifiSupplicantControl;
14618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
14718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private Context mContext = null;
14818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void initContext(Context context) {
14918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (mContext == null && context != null) {
15018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            mContext = context;
15118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        }
15218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
154240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
155b4419d876beda78c29836726e43d80203b4a656cRoshan Pius     * Explicitly sets the SupplicantStaIfaceHal instance
156240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * TODO(b/34722734): move this into the constructor of WifiNative when I clean up the awful
157240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * double singleton pattern
158240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     */
159b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    public void setSupplicantStaIfaceHal(SupplicantStaIfaceHal wifiSupplicantHal) {
160b4419d876beda78c29836726e43d80203b4a656cRoshan Pius        mSupplicantStaIfaceHal = wifiSupplicantHal;
161240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
162240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1638c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    /**
16470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang     * Explicitly sets the WificondControl instance
16570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang     * TODO(b/34722734): move this into the constructor of WifiNative when I clean up the awful
16670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang     * double singleton pattern
16770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang     */
16870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public void setWificondControl(WificondControl wificondControl) {
16970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        mWificondControl = wificondControl;
17070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
17170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
17279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    /** Explicitly sets the SupplicantP2pIfaceHal instance
17379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     * TODO(b/34722734): move this into the constructor of WifiNative when I clean up the awful
17479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     * double singleton pattern
17579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     */
17679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    public void setSupplicantP2pIfaceHal(SupplicantP2pIfaceHal wifiSupplicantHal) {
17779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        mSupplicantP2pIfaceHal = wifiSupplicantHal;
17879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
17979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
18079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
181a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /** Explicitly sets the WifiSupplicantControl instance
182a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * TODO(b/34722734): move this into the constructor of WifiNative when I clean up the awful
183a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * double singleton pattern
184a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
185a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public void setWifiSupplicantControl(WifiSupplicantControl wifiSupplicantControl) {
186a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        mWifiSupplicantControl = wifiSupplicantControl;
187a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
188a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
18970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
1908c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     * Explicitly sets the WifiVendorHal instance
1918c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     * TODO(b/34722734): move this into the constructor of WifiNative when I clean up the awful
1928c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     * double singleton pattern
1938c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
1948c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    public void setWifiVendorHal(WifiVendorHal wifiVendorHal) {
1958c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius        mWifiVendorHal = wifiVendorHal;
1968c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
1978c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
198c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang    private WifiNative(String interfaceName,
199c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang                       boolean requiresPrefix) {
200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mInterfaceName = interfaceName;
201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mTAG = "WifiNative-" + interfaceName;
202e26ad459b63271548abbdeba4f8d77fcca9f88bdxinhe
203c6ccad1ec19b0a53266962237774422b156ea726Ningyuan Wang        if (requiresPrefix) {
204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mInterfacePrefix = "IFNAME=" + interfaceName + " ";
205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mInterfacePrefix = "";
207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
210240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
2118c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     * Initializes the vendor HAL. This is just used to initialize the {@link HalDeviceManager}.
2128c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
2138c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    public boolean initializeVendorHal() {
214d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius        if (!HIDL_ENABLE) {
215d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius            return true;
216d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius        }
2178c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius        return mWifiVendorHal.initialize();
2188c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
2198c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
22018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getInterfaceName() {
22118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return mInterfaceName;
222e26ad459b63271548abbdeba4f8d77fcca9f88bdxinhe    }
223e26ad459b63271548abbdeba4f8d77fcca9f88bdxinhe
22418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Note this affects logging on for all interfaces
225ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    void enableVerboseLogging(int verbose) {
226ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        if (verbose > 0) {
227ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            DBG = true;
228ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        } else {
229ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle            DBG = false;
230ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle        }
2312e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang        if (mWificondControl != null) {
2322e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang            mWificondControl.enableVerboseLogging(verbose > 0 ? true : false);
2332e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang        }
2345cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (mSupplicantStaIfaceHal != null) {
2355cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            mSupplicantStaIfaceHal.enableVerboseLogging(verbose > 0);
2365cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
237ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    }
238ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle
23918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private void localLog(String s) {
240956f54b391677d78379729dd14518edddf3c7660Etan Cohen        if (sLocalLog != null) sLocalLog.log(mInterfaceName + ": " + s);
24118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
24370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang   /**
24470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Setup driver for client mode via wificond.
24570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return An IClientInterface as wificond client interface binder handler.
24670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Returns null on failure.
24770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
24870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public IClientInterface setupDriverForClientMode() {
24970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        IClientInterface clientInterface = mWificondControl.setupDriverForClientMode();
25070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        if (!startHal(true)) {
25170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang            // TODO(b/34859006): Handle failures.
25270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang            Log.e(TAG, "Failed to start HAL for client mode");
25370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        }
25470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return clientInterface;
25570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
25770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
25870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Setup driver for softAp mode via wificond.
25970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return An IApInterface as wificond Ap interface binder handler.
26070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Returns null on failure.
26170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
26270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public IApInterface setupDriverForSoftApMode() {
26370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        IApInterface apInterface = mWificondControl.setupDriverForSoftApMode();
26470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
26570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        if (!startHal(false)) {
26670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang            // TODO(b/34859006): Handle failures.
26770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang            Log.e(TAG, "Failed to start HAL for AP mode");
26870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        }
26970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return apInterface;
27070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
27170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
27270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
27370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Teardown all interfaces configured in wificond.
27470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return Returns true on success.
27570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
27670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public boolean tearDownInterfaces() {
27770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return mWificondControl.tearDownInterfaces();
27870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
27970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
28070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
28170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Disable wpa_supplicant via wificond.
28270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return Returns true on success.
28370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
28470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public boolean disableSupplicant() {
28570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return mWificondControl.disableSupplicant();
28670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
28770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
28870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
28970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Enable wpa_supplicant via wificond.
29070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return Returns true on success.
29170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
29270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public boolean enableSupplicant() {
29370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return mWificondControl.enableSupplicant();
29470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
29518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
296d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
297d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Request signal polling to wificond.
298d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns an SignalPollResult object.
299d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns null on failure.
300d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    */
301d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public SignalPollResult signalPoll() {
302d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        return mWificondControl.signalPoll();
303d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
304d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
305d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
306d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * Fetch TX packet counters on current connection from wificond.
307d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns an TxPacketCounters object.
308d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns null on failure.
309d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    */
310d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public TxPacketCounters getTxPacketCounters() {
311d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        return mWificondControl.getTxPacketCounters();
312d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
313d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
31418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /*
315bc582fdbca0d2099139f9790c7d0e1f9b55b0214Christopher Wiley     * Supplicant management
31618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
31718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native static boolean connectToSupplicantNative();
31824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
31924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * This method is called repeatedly until the connection to wpa_supplicant is established.
32024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     *
32124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * @return true if connection is established, false otherwise.
32224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean connectToSupplicant() {
32424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        if (HIDL_SUP_ENABLE) {
32524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            // Start initialization if not already started.
32624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            if (!mSupplicantP2pIfaceHal.isInitializationStarted()
32724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                    && !mSupplicantP2pIfaceHal.initialize()) {
32824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                return false;
32924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            }
33024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            if (!mSupplicantStaIfaceHal.isInitializationStarted()
33124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                    && !mSupplicantStaIfaceHal.initialize()) {
33224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                return false;
33324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            }
33424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            // Check if the initialization is complete.
33524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            return (mSupplicantP2pIfaceHal.isInitializationComplete()
33624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                    && mSupplicantStaIfaceHal.isInitializationComplete());
33724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        } else {
33824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            synchronized (sLock) {
33924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                localLog(mInterfacePrefix + "connectToSupplicant");
34024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                return connectToSupplicantNative();
34124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            }
342b577f391af2c484e443c19b3df1d62cc0924692aVinit Deshpande        }
343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
34518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native static void closeSupplicantConnectionNative();
346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void closeSupplicantConnection() {
34724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        if (HIDL_SUP_ENABLE) {
34824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            // Nothing to do for HIDL.
34924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        } else {
35024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            synchronized (sLock) {
35124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                localLog(mInterfacePrefix + "closeSupplicantConnection");
35224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius                closeSupplicantConnectionNative();
35324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius            }
354b577f391af2c484e443c19b3df1d62cc0924692aVinit Deshpande        }
355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
35718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /**
35818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * Wait for the supplicant to send an event, returning the event string.
35918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * @return the event string sent by the supplicant.
36018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
36118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native static String waitForEventNative();
362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String waitForEvent() {
363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // No synchronization necessary .. it is implemented in WifiMonitor
364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return waitForEventNative();
365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
36718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
36818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /*
36918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * Supplicant Command Primitives
37018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
37118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native boolean doBooleanCommandNative(String command);
37218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
37318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native int doIntCommandNative(String command);
37418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
37518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private native String doStringCommandNative(String command);
37618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean doBooleanCommand(String command) {
378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) Log.d(mTAG, "doBoolean: " + command);
379956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
38018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            String toLog = mInterfacePrefix + command;
381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            boolean result = doBooleanCommandNative(mInterfacePrefix + command);
3827b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            localLog(toLog + " -> " + result);
3830888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            if (DBG) Log.d(mTAG, command + ": returned " + result);
384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return result;
385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
388a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham    private boolean doBooleanCommandWithoutLogging(String command) {
389a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham        if (DBG) Log.d(mTAG, "doBooleanCommandWithoutLogging: " + command);
390956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
391a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham            boolean result = doBooleanCommandNative(mInterfacePrefix + command);
392a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham            if (DBG) Log.d(mTAG, command + ": returned " + result);
393a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham            return result;
394a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham        }
395a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham    }
396a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham
397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int doIntCommand(String command) {
398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) Log.d(mTAG, "doInt: " + command);
399956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
40018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            String toLog = mInterfacePrefix + command;
401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int result = doIntCommandNative(mInterfacePrefix + command);
4027b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle            localLog(toLog + " -> " + result);
403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) Log.d(mTAG, "   returned " + result);
404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return result;
405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String doStringCommand(String command) {
4090888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        if (DBG) {
4100888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            //GET_NETWORK commands flood the logs
4110888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            if (!command.startsWith("GET_NETWORK")) {
4120888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle                Log.d(mTAG, "doString: [" + command + "]");
4130888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            }
4140888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        }
415956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
41618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            String toLog = mInterfacePrefix + command;
417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String result = doStringCommandNative(mInterfacePrefix + command);
41840ff222cec1bd05879edb53abc75c6deead734cavandwalle            if (result == null) {
41940ff222cec1bd05879edb53abc75c6deead734cavandwalle                if (DBG) Log.d(mTAG, "doStringCommandNative no result");
42040ff222cec1bd05879edb53abc75c6deead734cavandwalle            } else {
4217b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                if (!command.startsWith("STATUS-")) {
4227b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                    localLog(toLog + " -> " + result);
4237b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle                }
42440ff222cec1bd05879edb53abc75c6deead734cavandwalle                if (DBG) Log.d(mTAG, "   returned " + result.replace("\n", " "));
42540ff222cec1bd05879edb53abc75c6deead734cavandwalle            }
426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return result;
427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String doStringCommandWithoutLogging(String command) {
4310888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle        if (DBG) {
4320888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            //GET_NETWORK commands flood the logs
4330888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            if (!command.startsWith("GET_NETWORK")) {
4340888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle                Log.d(mTAG, "doString: [" + command + "]");
4350888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle            }
43627355a942653264388e909a4276196ee63e57811vandwalle        }
437956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doStringCommandNative(mInterfacePrefix + command);
439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
44218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String doCustomSupplicantCommand(String command) {
44318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return doStringCommand(command);
44418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
44518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
446f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius
44718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /*
44818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     * Wrappers for supplicant commands
44918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
450f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    /**
451f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius     * Set supplicant log level
452f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius     *
453f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius     * @param turnOnVerbose Whether to turn on verbose logging or not.
454f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius     */
455f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    public void setSupplicantLogLevel(boolean turnOnVerbose) {
4565cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
4575cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            int logLevel = turnOnVerbose
4585cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    ? SupplicantStaIfaceHal.LOG_LEVEL_DEBUG
4595cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    : SupplicantStaIfaceHal.LOG_LEVEL_INFO;
4605cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            mSupplicantStaIfaceHal.setLogLevel(logLevel);
4615cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
4625cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            doStringCommand("LOG_LEVEL " + (turnOnVerbose ? "DEBUG" : "INFO"));
4635cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
464ad7319939c424d42fa6a3791c47f613db8ef3cd8vandwalle    }
465ad7319939c424d42fa6a3791c47f613db8ef3cd8vandwalle
4666259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    /*
4676259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * Convert string to Hexadecimal before passing to wifi native layer
4686259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * In native function "doCommand()" have trouble in converting Unicode character string to UTF8
4696259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * conversion to hex is required because SSIDs can have space characters in them;
4706259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * and that can confuses the supplicant because it uses space charaters as delimiters
4716259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     */
4726259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public static String encodeSSID(String ssid) {
4736259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        int length = ssid.length();
4746259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        if ((length > 1) && (ssid.charAt(0) == '"')
4756259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                && (ssid.charAt(length - 1) == '"')) {
4766259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            ssid = ssid.substring(1, length - 1);
4776259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        }
4786259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        return Utils.toHex(ssid.getBytes(StandardCharsets.UTF_8));
4796259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    }
4806259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
4813d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius    /**
482ed6a985c7b63e295248fa7e8292c99b48b7a4283Mitchell Wills     * Start a scan using wpa_supplicant for the given frequencies.
4833d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius     * @param freqs list of frequencies to scan for, if null scan all supported channels.
4846259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
485ed6a985c7b63e295248fa7e8292c99b48b7a4283Mitchell Wills     */
4866259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public boolean scan(Set<Integer> freqs, Set<String> hiddenNetworkSSIDs) {
4873d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        String freqList = null;
4886259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        String hiddenNetworkSSIDList = null;
4893d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        if (freqs != null && freqs.size() != 0) {
4907e1082bec4d42fdb4fc92061c7041826218eff1cNingyuan Wang            freqList = TextUtils.join(",", freqs);
4913d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        }
4926259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        if (hiddenNetworkSSIDs != null && hiddenNetworkSSIDs.size() != 0) {
4936259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            StringBuilder ssidList = new StringBuilder();
4946259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            for (String ssid : hiddenNetworkSSIDs) {
4956259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                ssidList.append(encodeSSID(ssid)).append(" ");
4966259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            }
4976259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            hiddenNetworkSSIDList = ssidList.toString();
4989ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills        }
4996259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        return scanWithParams(freqList, hiddenNetworkSSIDList);
5009ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills    }
5019ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills
5026259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    private boolean scanWithParams(String freqList, String hiddenNetworkSSIDList) {
5033d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        StringBuilder scanCommand = new StringBuilder();
5043d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        scanCommand.append("SCAN TYPE=ONLY");
5053d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        if (freqList != null) {
5063d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius            scanCommand.append(" freq=" + freqList);
5073d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        }
5086259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        if (hiddenNetworkSSIDList != null) {
5096259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            scanCommand.append(" ssid " + hiddenNetworkSSIDList);
510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
5113d995b8a3a508e957e3dac2e508956020cd9abfeRoshan Pius        return doBooleanCommand(scanCommand.toString());
512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Does a graceful shutdown of supplicant. Is a common stop function for both p2p and sta.
515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Note that underneath we use a harsh-sounding "terminate" supplicant command
517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * for a graceful stop and a mild-sounding "stop" interface
518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * to kill the process
519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean stopSupplicant() {
521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("TERMINATE");
522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String listNetworks() {
525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doStringCommand("LIST_NETWORKS");
526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
528e3939cb40d9ba3842be105a6e85172dc06e14758Vinit Deshpande    public String listNetworks(int last_id) {
529e3939cb40d9ba3842be105a6e85172dc06e14758Vinit Deshpande        return doStringCommand("LIST_NETWORKS LAST_ID=" + last_id);
530e3939cb40d9ba3842be105a6e85172dc06e14758Vinit Deshpande    }
531e3939cb40d9ba3842be105a6e85172dc06e14758Vinit Deshpande
532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public int addNetwork() {
533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doIntCommand("ADD_NETWORK");
534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
536fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski    public boolean setNetworkExtra(int netId, String name, Map<String, String> values) {
537e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius        String encoded = createNetworkExtra(values);
538e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius        if (encoded == null) {
539e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius            return false;
540e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius        }
54166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return setNetworkVariable(netId, name, encoded);
542e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    }
543e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius
544e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    @VisibleForTesting
545e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    public static String createNetworkExtra(Map<String, String> values) {
546fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        final String encoded;
547fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        try {
548fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            encoded = URLEncoder.encode(new JSONObject(values).toString(), "UTF-8");
549fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        } catch (NullPointerException e) {
550fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
551e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius            return null;
552fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        } catch (UnsupportedEncodingException e) {
553fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
554e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius            return null;
555fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        }
55666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return "\"" + encoded + "\"";
557fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski    }
558fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setNetworkVariable(int netId, String name, String value) {
560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(value)) return false;
561a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham        if (name.equals(WifiConfiguration.pskVarName)
562f20f5757ad97c9e2cf3920ff7e861358a576053bzhangshuxiao                || name.equals(WifiEnterpriseConfig.PASSWORD_KEY)
563f20f5757ad97c9e2cf3920ff7e861358a576053bzhangshuxiao                || name.equals(WifiEnterpriseConfig.IDENTITY_KEY)
564f20f5757ad97c9e2cf3920ff7e861358a576053bzhangshuxiao                || name.equals(WifiEnterpriseConfig.ANON_IDENTITY_KEY)) {
565a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham            return doBooleanCommandWithoutLogging("SET_NETWORK " + netId + " " + name + " " + value);
566a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham        } else {
567a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham            return doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value);
568a6777abfc90496801e9942f57fbfa091ba85ae82Prerepa Viswanadham        }
569155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
571fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski    public Map<String, String> getNetworkExtra(int netId, String name) {
572e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius        final String extraString = getNetworkVariable(netId, name);
573e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius        return parseNetworkExtra(extraString);
574e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    }
575e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius
576e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    public static Map<String, String> parseNetworkExtra(String extraSting) {
577e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius        if (extraSting == null || !extraSting.startsWith("\"") || !extraSting.endsWith("\"")) {
578fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            return null;
579fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        }
580fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        try {
581e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius            final String encoded = extraSting.substring(1, extraSting.length() - 1);
582fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // This method reads a JSON dictionary that was written by setNetworkExtra(). However,
583fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // on devices that upgraded from Marshmallow, it may encounter a legacy value instead -
584fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // an FQDN stored as a plain string. If such a value is encountered, the JSONObject
585fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // constructor will thrown a JSONException and the method will return null.
586fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            final JSONObject json = new JSONObject(URLDecoder.decode(encoded, "UTF-8"));
587bc582fdbca0d2099139f9790c7d0e1f9b55b0214Christopher Wiley            final Map<String, String> values = new HashMap<>();
588fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            final Iterator<?> it = json.keys();
589fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            while (it.hasNext()) {
590fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski                final String key = (String) it.next();
591fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski                final Object value = json.get(key);
592fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski                if (value instanceof String) {
593fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski                    values.put(key, (String) value);
594fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski                }
595fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            }
596fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            return values;
597fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        } catch (UnsupportedEncodingException e) {
59864697f7a5b9c1c39f8c9d9c225b8ca4c798422c2Samuel Tan            Log.e(TAG, "Unable to deserialize networkExtra: " + e.toString());
599fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            return null;
600fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        } catch (JSONException e) {
601fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // This is not necessarily an error. This exception will also occur if we encounter a
602fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // legacy FQDN stored as a plain string. We want to return null in this case as no JSON
603fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            // dictionary of extras was found.
604fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski            return null;
605fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski        }
606fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski    }
607fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
608155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String getNetworkVariable(int netId, String name) {
609155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(name)) return null;
610155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
611155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // GET_NETWORK will likely flood the logs ...
612155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doStringCommandWithoutLogging("GET_NETWORK " + netId + " " + name);
613155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
615155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean removeNetwork(int netId) {
616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("REMOVE_NETWORK " + netId);
617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
618155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
619f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    private void logDbg(String debug) {
620f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        long now = SystemClock.elapsedRealtimeNanos();
621f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        String ts = String.format("[%,d us] ", now/1000);
622ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle        Log.e("WifiNative: ", ts+debug+ " stack:"
623ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                + Thread.currentThread().getStackTrace()[2].getMethodName() +" - "
624ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                + Thread.currentThread().getStackTrace()[3].getMethodName() +" - "
625ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                + Thread.currentThread().getStackTrace()[4].getMethodName() +" - "
626ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                + Thread.currentThread().getStackTrace()[5].getMethodName()+" - "
627ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle                + Thread.currentThread().getStackTrace()[6].getMethodName());
628f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle
629f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
6309d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius
6319d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius    /**
6329d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     * Select a network in wpa_supplicant (Disables all others).
6339d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     * @param netId - Network ID of the network to be selected.
6349d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     * @return true if command succeeded, false otherwise.
6359d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     */
6360047ccf563baa288777e06c6fe95d3681fcf5ccdVinit Deshpande    public boolean selectNetwork(int netId) {
6370047ccf563baa288777e06c6fe95d3681fcf5ccdVinit Deshpande        if (DBG) logDbg("selectNetwork nid=" + Integer.toString(netId));
6380047ccf563baa288777e06c6fe95d3681fcf5ccdVinit Deshpande        return doBooleanCommand("SELECT_NETWORK " + netId);
6390047ccf563baa288777e06c6fe95d3681fcf5ccdVinit Deshpande    }
6400047ccf563baa288777e06c6fe95d3681fcf5ccdVinit Deshpande
641155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean reconnect() {
642f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (DBG) logDbg("RECONNECT ");
6435cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
6445cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.reconnect();
6455cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
6465cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("RECONNECT");
6475cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
648155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
650155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean reassociate() {
651f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle        if (DBG) logDbg("REASSOCIATE ");
6525cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
6535cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.reassociate();
6545cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
6555cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("REASSOCIATE");
6565cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
657155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
658155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean disconnect() {
66021bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle        if (DBG) logDbg("DISCONNECT ");
6615cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
6625cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.disconnect();
6635cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
6645cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DISCONNECT");
6655cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
668155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String status() {
66999d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle        return status(false);
670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
67299d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle    public String status(boolean noEvents) {
67399d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle        if (noEvents) {
67499d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle            return doStringCommand("STATUS-NO_EVENTS");
67599d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle        } else {
67699d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle            return doStringCommand("STATUS");
67799d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle        }
67899d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle    }
67999d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle
680155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String getMacAddress() {
6815cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
6825cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.getMacAddress();
6835cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
6845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            //Macaddr = XX.XX.XX.XX.XX.XX
6855cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            String ret = doStringCommand("DRIVER MACADDR");
6865cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (!TextUtils.isEmpty(ret)) {
6875cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                String[] tokens = ret.split(" = ");
6885cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                if (tokens.length == 2) return tokens[1];
6895cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
6905cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return null;
691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
6958631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang    * Fetch the latest scan result from kernel via wificond.
6968631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang    * @return Returns an ArrayList of ScanDetail.
6978631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang    * Returns an empty ArrayList on failure.
6988631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang    */
6992afa54e3c8fa1153302a0d57b0e9b7bee35406ffMitchell Wills    public ArrayList<ScanDetail> getScanResults() {
7008631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang        return mWificondControl.getScanResults();
70177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
70277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
704446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * Format of result:
705446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * id=1016
706446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * bssid=00:03:7f:40:84:10
707446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * freq=2462
708446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * beacon_int=200
709446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * capabilities=0x0431
710446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * qual=0
711446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * noise=0
712446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * level=-46
713446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * tsf=0000002669008476
714446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * age=5
715446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * ie=00105143412d485332302d52322d54455354010882848b960c12182403010b0706555...
716446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * flags=[WPA2-EAP-CCMP][ESS][P2P][HS20]
717446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * ssid=QCA-HS20-R2-TEST
718446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * p2p_device_name=
71956d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle     * p2p_config_methods=0x0SET_NE
720446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_venue_name=02083d656e6757692d466920416c6c69616e63650a3239383920436f...
721446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_network_auth_type=010000
722446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_roaming_consortium=03506f9a05001bc504bd
723446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_ip_addr_type_availability=0c
724446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_nai_realm=0200300000246d61696c2e6578616d706c652e636f6d3b636973636f2...
725446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_3gpp=000600040132f465
726446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * anqp_domain_name=0b65786d61706c652e636f6d
727446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * hs20_operator_friendly_name=11656e6757692d466920416c6c69616e63650e636869...
728446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * hs20_wan_metrics=01c40900008001000000000a00
729446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * hs20_connection_capability=0100000006140001061600000650000106bb010106bb0...
730446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     * hs20_osu_providers_list=0b5143412d4f53552d425353010901310015656e6757692d...
731446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng     */
732446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    public String scanResult(String bssid) {
733446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng        return doStringCommand("BSS " + bssid);
734446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    }
735446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng
736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V4 packets
738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Multicast filtering rules work as follows:
741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * a power optimized mode (typically when screen goes off).
744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-ADD Num
749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and DRIVER RXFILTER-START
752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to stop the usage of these rules, we do
753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-STOP
755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-REMOVE Num
756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num is as described for RXFILTER-ADD
757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The  SETSUSPENDOPT driver command overrides the filtering rules
759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startFilteringMulticastV4Packets() {
7615cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
7625cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.stopRxFilter()
7635cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.removeRxFilter(
7645cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    SupplicantStaIfaceHal.RX_FILTER_TYPE_V4_MULTICAST)
7655cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.stopRxFilter();
7665cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
7675cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DRIVER RXFILTER-STOP")
7685cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-REMOVE 2")
7695cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-START");
7705cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V4 packets.
775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean stopFilteringMulticastV4Packets() {
7785cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
7795cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.stopRxFilter()
7805cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.addRxFilter(
7815cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    SupplicantStaIfaceHal.RX_FILTER_TYPE_V4_MULTICAST)
7825cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.stopRxFilter();
7835cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
7845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DRIVER RXFILTER-STOP")
7855cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-ADD 2")
7865cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-START");
7875cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
788155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
790155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
791155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V6 packets
792155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
793155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startFilteringMulticastV6Packets() {
7955cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
7965cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.stopRxFilter()
7975cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.removeRxFilter(
7985cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    SupplicantStaIfaceHal.RX_FILTER_TYPE_V6_MULTICAST)
7995cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.stopRxFilter();
8005cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
8015cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DRIVER RXFILTER-STOP")
8025cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-REMOVE 3")
8035cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-START");
8045cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
805155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
806155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
807155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V6 packets.
809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean stopFilteringMulticastV6Packets() {
8125cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8135cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.stopRxFilter()
8145cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.addRxFilter(
8155cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    SupplicantStaIfaceHal.RX_FILTER_TYPE_V6_MULTICAST)
8165cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && mSupplicantStaIfaceHal.stopRxFilter();
8175cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
8185cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DRIVER RXFILTER-STOP")
8195cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-ADD 3")
8205cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    && doBooleanCommand("DRIVER RXFILTER-START");
8215cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
82418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED     = 0;
82518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED    = 1;
82618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static final int BLUETOOTH_COEXISTENCE_MODE_SENSE       = 2;
8277ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    /**
8287ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * Sets the bluetooth coexistence mode.
8297ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *
8307ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
8317ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
8327ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
8337ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * @return Whether the mode was successfully set.
8347ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      */
835155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setBluetoothCoexistenceMode(int mode) {
8365cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8375cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setBtCoexistenceMode((byte) mode);
8385cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
8395cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
8405cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
841155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
842155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
843155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
844155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
845155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * some of the low-level scan parameters used by the driver are changed to
846155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * reduce interference with A2DP streaming.
847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
848cc180872c51908b15ce5cbf834634ff323e036bcChristopher Wiley     * @param setCoexScanMode whether to enable or disable this mode
849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the command succeeded, {@code false} otherwise.
850155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
851155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
8525cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8535cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setBtCoexistenceScanModeEnabled(setCoexScanMode);
854155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
8555cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (setCoexScanMode) {
8565cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER BTCOEXSCAN-START");
8575cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
8585cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER BTCOEXSCAN-STOP");
8595cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
861155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
862155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
863155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setSuspendOptimizations(boolean enabled) {
8645cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8655cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setSuspendModeEnabled(enabled);
866155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
8675cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (enabled) {
8685cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER SETSUSPENDMODE 1");
8695cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
8705cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER SETSUSPENDMODE 0");
8715cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
872155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
873155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
874155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
875155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setCountryCode(String countryCode) {
8765cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8775cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setCountryCode(countryCode);
8785cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
8795cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (countryCode != null) {
8805cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER COUNTRY " + countryCode.toUpperCase(Locale.ROOT));
8815cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
8825cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("DRIVER COUNTRY");
8835cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
8845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
885155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
886155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
8879153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    /**
8889153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     * Start/Stop PNO scan.
8899153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     * @param enable boolean indicating whether PNO is being enabled or disabled.
8909153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     */
8919153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    public boolean setPnoScan(boolean enable) {
8929153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius        String cmd = enable ? "SET pno 1" : "SET pno 0";
8939153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius        return doBooleanCommand(cmd);
8949153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    }
895ac9ad3283508db15b65b1cbb89b841278973276bRoshan Pius
896155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void startTdls(String macAddr, boolean enable) {
8975cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
8985cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (enable) {
8995cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                mSupplicantStaIfaceHal.initiateTdlsDiscover(macAddr);
9005cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                mSupplicantStaIfaceHal.initiateTdlsSetup(macAddr);
9015cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
9025cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                mSupplicantStaIfaceHal.initiateTdlsTeardown(macAddr);
90318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            }
904155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
9055cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (enable) {
9065cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                synchronized (sLock) {
9075cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    doBooleanCommand("TDLS_DISCOVER " + macAddr);
9085cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                    doBooleanCommand("TDLS_SETUP " + macAddr);
9095cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                }
9105cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
9115cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                doBooleanCommand("TDLS_TEARDOWN " + macAddr);
9125cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
913155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
914155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
915155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
916155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPbc(String bssid) {
9175cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9185cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.startWpsPbc(bssid);
919155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
9205cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (TextUtils.isEmpty(bssid)) {
9215cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("WPS_PBC");
9225cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
9235cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doBooleanCommand("WPS_PBC " + bssid);
9245cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
925155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
926155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
927155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
928155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPbc(String iface, String bssid) {
929956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (TextUtils.isEmpty(bssid)) {
931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC");
932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC " + bssid);
934155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
935155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPinKeypad(String pin) {
939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(pin)) return false;
9405cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9415cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.startWpsPinKeypad(pin);
9425cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
9435cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("WPS_PIN any " + pin);
9445cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
947155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPinKeypad(String iface, String pin) {
948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(pin)) return false;
949956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommandNative("IFNAME=" + iface + " WPS_PIN any " + pin);
951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String startWpsPinDisplay(String bssid) {
9565cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9575cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.startWpsPinDisplay(bssid);
958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
9595cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (TextUtils.isEmpty(bssid)) {
9605cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doStringCommand("WPS_PIN any");
9615cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
9625cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return doStringCommand("WPS_PIN " + bssid);
9635cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
964155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
965155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
967155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String startWpsPinDisplay(String iface, String bssid) {
968956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (TextUtils.isEmpty(bssid)) {
970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN any");
971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN " + bssid);
973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
97733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    public boolean setExternalSim(boolean external) {
9785cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9795cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setExternalSim(external);
9805cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
9815cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            String value = external ? "1" : "0";
9825cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            Log.d(TAG, "Setting external_sim to " + value);
9835cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET external_sim " + value);
9845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
98533b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
98633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
987f97140d51d14ce0659d381f443c08dbd94dfea28Honore Tricot    public boolean simAuthResponse(int id, String type, String response) {
9885cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
9895cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if ("GSM-AUTH".equals(type)) {
9905cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(response);
9915cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else if ("UMTS-AUTH".equals(type)) {
9925cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(response);
9935cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else if ("UMTS-AUTS".equals(type)) {
9945cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(response);
9955cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
9965cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return false;
9975cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
9985cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
9995cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            // with type = GSM-AUTH, UMTS-AUTH or UMTS-AUTS
10005cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("CTRL-RSP-SIM-" + id + ":" + type + response);
10015cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
100233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
100333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
100426eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    public boolean simAuthFailedResponse(int id) {
10055cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10065cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure();
10075cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10085cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            // should be used with type GSM-AUTH
10095cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("CTRL-RSP-SIM-" + id + ":GSM-FAIL");
10105cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
101126eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
101226eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
101326eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    public boolean umtsAuthFailedResponse(int id) {
10145cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10155cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure();
10165cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10175cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            // should be used with type UMTS-AUTH
10185cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("CTRL-RSP-SIM-" + id + ":UMTS-FAIL");
10195cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
102026eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
102126eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1022ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    public boolean simIdentityResponse(int id, String response) {
10235cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10245cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(response);
10255cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10265cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("CTRL-RSP-IDENTITY-" + id + ":" + response);
10275cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1028ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    }
1029ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot
1030155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Configures an access point connection */
1031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsRegistrar(String bssid, String pin) {
1032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false;
10335cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10345cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.startWpsRegistrar(bssid, pin);
10355cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10365cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("WPS_REG " + bssid + " " + pin);
10375cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean cancelWps() {
10415cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10425cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.cancelWps();
10435cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10445cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("WPS_CANCEL");
10455cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setPersistentReconnect(boolean enabled) {
1049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int value = (enabled == true) ? 1 : 0;
1050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("SET persistent_reconnect " + value);
1051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setDeviceName(String name) {
10545cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10555cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsDeviceName(name);
10565cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10575cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET device_name " + name);
10585cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1060155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setDeviceType(String type) {
10625cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10635cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsDeviceType(type);
10645cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10655cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET device_type " + type);
10665cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setConfigMethods(String cfg) {
10705cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10715cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsConfigMethods(cfg);
10725cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10735cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET config_methods " + cfg);
10745cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setManufacturer(String value) {
10785cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10795cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsManufacturer(value);
10805cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10815cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET manufacturer " + value);
10825cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1084155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1085155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setModelName(String value) {
10865cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10875cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsModelName(value);
10885cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10895cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET model_name " + value);
10905cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setModelNumber(String value) {
10945cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
10955cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsModelNumber(value);
10965cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
10975cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET model_number " + value);
10985cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setSerialNumber(String value) {
11025cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
11035cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setWpsSerialNumber(value);
11045cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
11055cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return doBooleanCommand("SET serial_number " + value);
11065cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setP2pSsidPostfix(String postfix) {
1110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
1111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setP2pGroupIdle(String iface, int time) {
1114956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
1115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommandNative("IFNAME=" + iface + " SET p2p_group_idle " + time);
1116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setPowerSave(boolean enabled) {
11205cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
11215cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            mSupplicantStaIfaceHal.setPowerSave(enabled);
1122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
11235cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (enabled) {
11245cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                doBooleanCommand("SET ps 1");
11255cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            } else {
11265cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                doBooleanCommand("SET ps 0");
11275cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
1128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setP2pPowerSave(String iface, boolean enabled) {
1132956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
1133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (enabled) {
1134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 1");
1135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
1136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 0");
1137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setWfdEnable(boolean enable) {
1142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("SET wifi_display " + (enable ? "1" : "0"));
1143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setWfdDeviceInfo(String hex) {
1146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("WFD_SUBELEM_SET 0 " + hex);
1147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * "sta" prioritizes STA connection over P2P and "p2p" prioritizes
1151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * P2P connection over STA
1152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setConcurrencyPriority(String s) {
1154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_SET conc_pref " + s);
1155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pFind() {
1158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_FIND");
1159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pFind(int timeout) {
1162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (timeout <= 0) {
1163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return p2pFind();
1164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_FIND " + timeout);
1166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pStopFind() {
1169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande       return doBooleanCommand("P2P_STOP_FIND");
1170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pListen() {
1173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_LISTEN");
1174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pListen(int timeout) {
1177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (timeout <= 0) {
1178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return p2pListen();
1179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_LISTEN " + timeout);
1181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pExtListen(boolean enable, int period, int interval) {
1184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (enable && interval < period) {
1185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
1186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_EXT_LISTEN"
1188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    + (enable ? (" " + period + " " + interval) : ""));
1189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pSetChannel(int lc, int oc) {
1192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) Log.d(mTAG, "p2pSetChannel: lc="+lc+", oc="+oc);
1193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1194956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
119518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            if (lc >=1 && lc <= 11) {
119618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                if (!doBooleanCommand("P2P_SET listen_channel " + lc)) {
119718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    return false;
119818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                }
119918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            } else if (lc != 0) {
1200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return false;
1201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
120318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            if (oc >= 1 && oc <= 165 ) {
120418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                int freq = (oc <= 14 ? 2407 : 5000) + oc * 5;
120518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                return doBooleanCommand("P2P_SET disallow_freq 1000-"
120618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                        + (freq - 5) + "," + (freq + 5) + "-6000");
120718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            } else if (oc == 0) {
120818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                /* oc==0 disables "P2P_SET disallow_freq" (enables all freqs) */
120918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                return doBooleanCommand("P2P_SET disallow_freq \"\"");
121018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            }
1211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return false;
1213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pFlush() {
1216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_FLUSH");
1217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
121918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static final int DEFAULT_GROUP_OWNER_INTENT     = 6;
1220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
1221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
1222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
1223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (config == null) return null;
1224bc582fdbca0d2099139f9790c7d0e1f9b55b0214Christopher Wiley        List<String> args = new ArrayList<>();
1225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WpsInfo wps = config.wps;
1226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        args.add(config.deviceAddress);
1227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        switch (wps.setup) {
1229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.PBC:
1230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add("pbc");
1231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
1232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.DISPLAY:
1233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (TextUtils.isEmpty(wps.pin)) {
1234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    args.add("pin");
1235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else {
1236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    args.add(wps.pin);
1237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add("display");
1239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
1240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.KEYPAD:
1241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add(wps.pin);
1242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add("keypad");
1243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
1244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.LABEL:
1245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add(wps.pin);
1246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                args.add("label");
1247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            default:
1248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
1249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (config.netId == WifiP2pGroup.PERSISTENT_NET_ID) {
1252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            args.add("persistent");
1253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (joinExistingGroup) {
1256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            args.add("join");
1257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
1258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //TODO: This can be adapted based on device plugged in state and
1259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //device battery state
1260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int groupOwnerIntent = config.groupOwnerIntent;
1261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
1262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                groupOwnerIntent = DEFAULT_GROUP_OWNER_INTENT;
1263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            args.add("go_intent=" + groupOwnerIntent);
1265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String command = "P2P_CONNECT ";
1268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (String s : args) command += s + " ";
1269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doStringCommand(command);
1271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pCancelConnect() {
1274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_CANCEL");
1275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pProvisionDiscovery(WifiP2pConfig config) {
1278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (config == null) return false;
1279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        switch (config.wps.setup) {
1281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.PBC:
1282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " pbc");
1283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.DISPLAY:
1284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                //We are doing display, so provision discovery is keypad
1285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " keypad");
1286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.KEYPAD:
1287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                //We are doing keypad, so provision discovery is display
1288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " display");
1289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            default:
1290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
1291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return false;
1293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pGroupAdd(boolean persistent) {
1296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (persistent) {
1297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommand("P2P_GROUP_ADD persistent");
1298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_GROUP_ADD");
1300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pGroupAdd(int netId) {
1303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_GROUP_ADD persistent=" + netId);
1304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pGroupRemove(String iface) {
1307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(iface)) return false;
1308956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
1309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommandNative("IFNAME=" + iface + " P2P_GROUP_REMOVE " + iface);
1310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pReject(String deviceAddress) {
1314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_REJECT " + deviceAddress);
1315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Invite a peer to a group */
1318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
1319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(deviceAddress)) return false;
1320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (group == null) {
1322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommand("P2P_INVITE peer=" + deviceAddress);
1323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
1324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
1325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
1326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Reinvoke a persistent connection */
1330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pReinvoke(int netId, String deviceAddress) {
1331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(deviceAddress) || netId < 0) return false;
1332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
1334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String p2pGetSsid(String deviceAddress) {
1337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return p2pGetParam(deviceAddress, "oper_ssid");
1338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String p2pGetDeviceAddress() {
134136286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        Log.d(TAG, "p2pGetDeviceAddress");
134236286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande
134327f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande        String status = null;
134427f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande
134536286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        /* Explicitly calling the API without IFNAME= prefix to take care of the devices that
134636286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        don't have p2p0 interface. Supplicant seems to be returning the correct address anyway. */
134736286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande
1348956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
134927f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande            status = doStringCommandNative("STATUS");
135027f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande        }
135127f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande
135227f4b0c6ea9533e91863da48cefc80f8b5a88d1eVinit Deshpande        String result = "";
135336286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        if (status != null) {
135436286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande            String[] tokens = status.split("\n");
135536286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande            for (String token : tokens) {
135636286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                if (token.startsWith("p2p_device_address=")) {
135736286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                    String[] nameValue = token.split("=");
135836286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                    if (nameValue.length != 2)
135936286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                        break;
136036286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                    result = nameValue[1];
136136286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande                }
1362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
136436286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande
136536286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        Log.d(TAG, "p2pGetDeviceAddress returning " + result);
136636286b23c4e30f042ed753a670c2b462ebf13a48Vinit Deshpande        return result;
1367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public int getGroupCapability(String deviceAddress) {
1370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int gc = 0;
1371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(deviceAddress)) return gc;
1372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String peerInfo = p2pPeer(deviceAddress);
1373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(peerInfo)) return gc;
1374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String[] tokens = peerInfo.split("\n");
1376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (String token : tokens) {
1377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (token.startsWith("group_capab=")) {
1378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                String[] nameValue = token.split("=");
1379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (nameValue.length != 2) break;
1380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                try {
1381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return Integer.decode(nameValue[1]);
1382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } catch(NumberFormatException e) {
1383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return gc;
1384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return gc;
1388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String p2pPeer(String deviceAddress) {
1391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doStringCommand("P2P_PEER " + deviceAddress);
1392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String p2pGetParam(String deviceAddress, String key) {
1395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (deviceAddress == null) return null;
1396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String peerInfo = p2pPeer(deviceAddress);
1398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (peerInfo == null) return null;
1399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String[] tokens= peerInfo.split("\n");
1400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        key += "=";
1402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (String token : tokens) {
1403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (token.startsWith(key)) {
1404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                String[] nameValue = token.split("=");
1405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (nameValue.length != 2) break;
1406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return nameValue[1];
1407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return null;
1410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) {
1413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /*
1414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD bonjour <query hexdump> <RDATA hexdump>
1415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD upnp <version hex> <service>
1416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         *
1417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * e.g)
1418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * [Bonjour]
1419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * # IP Printing over TCP (PTR) (RDATA=MyPrinter._ipp._tcp.local.)
1420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD bonjour 045f697070c00c000c01 094d795072696e746572c027
1421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * # IP Printing over TCP (TXT) (RDATA=txtvers=1,pdl=application/postscript)
1422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD bonjour 096d797072696e746572045f697070c00c001001
1423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         *  09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074
1424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         *
1425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * [UPnP]
1426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012
1427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice
1428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp
1429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * -org:device:InternetGatewayDevice:1
1430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9322-123456789012::urn:schemas-upnp
1431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * -org:service:ContentDirectory:2
1432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
1433956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
143418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            for (String s : servInfo.getSupplicantQueryList()) {
143518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                String command = "P2P_SERVICE_ADD";
143618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                command += (" " + s);
143718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                if (!doBooleanCommand(command)) {
143818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    return false;
143918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                }
1440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
1443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pServiceDel(WifiP2pServiceInfo servInfo) {
1446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /*
1447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_DEL bonjour <query hexdump>
1448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * P2P_SERVICE_DEL upnp <version hex> <service>
1449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
1450956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
145118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            for (String s : servInfo.getSupplicantQueryList()) {
145218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                String command = "P2P_SERVICE_DEL ";
1453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
145418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                String[] data = s.split(" ");
145518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                if (data.length < 2) {
145618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    return false;
145718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                }
145818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                if ("upnp".equals(data[0])) {
145918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    command += s;
146018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                } else if ("bonjour".equals(data[0])) {
146118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    command += data[0];
146218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    command += (" " + data[1]);
146318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                } else {
146418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    return false;
146518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                }
146618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                if (!doBooleanCommand(command)) {
146718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    return false;
146818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                }
1469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1471155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
1472155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1473155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1474155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pServiceFlush() {
1475155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_SERVICE_FLUSH");
1476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String p2pServDiscReq(String addr, String query) {
1479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String command = "P2P_SERV_DISC_REQ";
1480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        command += (" " + addr);
1481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        command += (" " + query);
1482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doStringCommand(command);
1484155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1485155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean p2pServDiscCancelReq(String id) {
1487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return doBooleanCommand("P2P_SERV_DISC_CANCEL_REQ " + id);
1488155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Set the current mode of miracast operation.
1491155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *  0 = disabled
1492155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *  1 = operating as source
1493155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *  2 = operating as sink
1494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1495155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setMiracastMode(int mode) {
1496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Note: optional feature on the driver. It is ok for this to fail.
1497155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        doBooleanCommand("DRIVER MIRACAST " + mode);
1498155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
14993f7ef65ab71619040032aee96b5599849881d6fdAndres Morales
1500f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    /*
1501f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande     * NFC-related calls
1502f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande     */
1503f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    public String getNfcWpsConfigurationToken(int netId) {
1504f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        return doStringCommand("WPS_NFC_CONFIG_TOKEN WPS " + netId);
1505f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    }
1506f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
1507f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    public String getNfcHandoverRequest() {
1508f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        return doStringCommand("NFC_GET_HANDOVER_REQ NDEF P2P-CR");
1509f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    }
1510f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
1511f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    public String getNfcHandoverSelect() {
1512f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        return doStringCommand("NFC_GET_HANDOVER_SEL NDEF P2P-CR");
1513f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    }
1514f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
1515f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    public boolean initiatorReportNfcHandover(String selectMessage) {
1516f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        return doBooleanCommand("NFC_REPORT_HANDOVER INIT P2P 00 " + selectMessage);
1517f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    }
1518f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
1519f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    public boolean responderReportNfcHandover(String requestMessage) {
1520f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        return doBooleanCommand("NFC_REPORT_HANDOVER RESP P2P " + requestMessage + " 00");
1521f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    }
1522f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
1523a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /** WifiSupplicantControl methods. TODO: These should use HIDL soon. */
1524a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1525a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Migrate all the configured networks from wpa_supplicant.
1526a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1527a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
1528a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *                      the networks.
1529a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
1530a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return Max priority of all the configs.
1531a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1532f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    public boolean migrateNetworksFromSupplicant(Map<String, WifiConfiguration> configs,
1533f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius                                                 SparseArray<Map<String, String>> networkExtras) {
15345cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
15355cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.loadNetworks(configs, networkExtras);
15365cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
15375cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            mWifiSupplicantControl.loadNetworks(configs, networkExtras);
15385cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return true;
15395cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1540a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1541a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1542a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1543a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
1544a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * This method does the following:
1545a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 1. Triggers disconnect command to wpa_supplicant (if |shouldDisconnect| is true).
1546a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 2. Remove any existing network in wpa_supplicant.
1547a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 3. Add a new network to wpa_supplicant.
1548a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 4. Save the provided configuration to wpa_supplicant.
1549a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 5. Select the new network in wpa_supplicant.
1550a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 6. Triggers reconnect command to wpa_supplicant.
1551a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1552a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1553a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param shouldDisconnect whether to trigger a disconnection or not.
1554a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1555a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1556a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean connectToNetwork(WifiConfiguration configuration, boolean shouldDisconnect) {
15575cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
15585cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.connectToNetwork(configuration, shouldDisconnect);
15595cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
15605cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mWifiSupplicantControl.connectToNetwork(configuration, shouldDisconnect);
15615cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1562a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1563a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1564a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1565a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
1566a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * configuration provided does not match the already configured network, then this triggers
1567a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * a new connection attempt (instead of roam).
1568a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 1. First check if we're attempting to connect to the same network as we currently have
1569a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * configured.
1570a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 2. Set the new bssid for the network in wpa_supplicant.
1571a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * 3. Triggers reassociate command to wpa_supplicant.
1572a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1573a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1574a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1575a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1576a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean roamToNetwork(WifiConfiguration configuration) {
15775cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
15785cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.roamToNetwork(configuration);
15795cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
15805cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mWifiSupplicantControl.roamToNetwork(configuration);
15815cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1582a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1583a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1584a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1585a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Get the framework network ID corresponding to the provided supplicant network ID for the
1586a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * network configured in wpa_supplicant.
1587a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1588a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param supplicantNetworkId network ID in wpa_supplicant for the network.
1589a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return Corresponding framework network ID if found, -1 if network not found.
1590a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1591a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public int getFrameworkNetworkId(int supplicantNetworkId) {
15925cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
15935cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            // In the HIDL world, wifi monitor events contain the framework network Id.
15945cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return supplicantNetworkId;
15955cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
15965cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mWifiSupplicantControl.getFrameworkNetworkId(supplicantNetworkId);
15975cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1598a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1599a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1600a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1601a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Remove all the networks.
1602a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1603a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1604a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1605a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean removeAllNetworks() {
16065cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
16075cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.removeAllNetworks();
16085cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
16095cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            if (!doBooleanCommand("REMOVE_NETWORK all")) {
16105cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                Log.e(TAG, "Remove all networks in wpa_supplicant failed");
16115cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                return false;
16125cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
16135cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return true;
1614a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        }
1615a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1616a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1617a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1618a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Set the BSSID for the currently configured network in wpa_supplicant.
1619a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1620a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return true if successful, false otherwise.
1621a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1622a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean setConfiguredNetworkBSSID(String bssid) {
16235cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
16245cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.setCurrentNetworkBssid(bssid);
16255cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
16265cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mWifiSupplicantControl.setConfiguredNetworkBSSID(bssid);
16275cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1628a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1629a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1630a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1631a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Save the current configuration to wpa_supplicant.conf.
1632a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1633a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean saveConfig() {
1634a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        return doBooleanCommand("SAVE_CONFIG");
1635a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1636a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1637a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1638a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Read network variables from wpa_supplicant.conf.
1639a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     *
1640a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @param key The parameter to be parsed.
1641a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * @return Map of corresponding configKey to the value of the param requested.
1642a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1643a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public Map<String, String> readNetworkVariablesFromSupplicantFile(String key) {
1644a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        return mWifiSupplicantControl.readNetworkVariablesFromSupplicantFile(key);
1645a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1646a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1647a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1648a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Get Fast BSS Transition capability.
1649a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1650a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public boolean getSystemSupportsFastBssTransition() {
1651a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        return mWifiSupplicantControl.getSystemSupportsFastBssTransition();
1652a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
1653a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius
1654a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    /**
1655a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     * Set Fast BSS Transition capability.
1656a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius     */
1657a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    public void setSystemSupportsFastBssTransition(boolean supported) {
1658a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius        mWifiSupplicantControl.setSystemSupportsFastBssTransition(supported);
1659a26a8b33616c94859ba33f33403794cf636baa54Roshan Pius    }
16607e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
1661fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    /**
1662fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * Initiate ANQP query.
1663fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     *
1664fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param bssid BSSID of the AP to be queried
1665fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param anqpIds Set of anqp IDs.
1666fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param hs20Subtypes Set of HS20 subtypes.
1667fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @return true on success, false otherwise.
1668fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     */
1669fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    public boolean requestAnqp(String bssid, Set<Integer> anqpIds, Set<Integer> hs20Subtypes) {
1670fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        if (bssid == null || ((anqpIds == null || anqpIds.isEmpty())
1671fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                && (hs20Subtypes == null || hs20Subtypes.isEmpty()))) {
1672fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            return false;
1673fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        }
16745cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
16755cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            ArrayList<Short> anqpIdList = new ArrayList<>();
16765cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            for (Integer anqpId : anqpIds) {
16775cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius                anqpIdList.add(anqpId.shortValue());
16785cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            }
16795cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            ArrayList<Integer> hs20SubtypeList = new ArrayList<>();
16805cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            hs20SubtypeList.addAll(hs20Subtypes);
16815cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.initiateAnqpQuery(bssid, anqpIdList, hs20SubtypeList);
16825cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
16835cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            String command = buildAnqpQueryCommand(bssid, anqpIds, hs20Subtypes);
16845cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            String result = doStringCommand(command);
16855cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return result != null && result.startsWith("OK");
16865cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1687fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    }
1688fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius
1689fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    /**
1690fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * Build a wpa_supplicant ANQP query command
1691fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     *
1692fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param bssid BSSID of the AP to be queried
1693fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param anqpIds Set of anqp IDs.
1694fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param hs20Subtypes Set of HS20 subtypes.
1695fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @return A command string.
1696fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     */
1697fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    @VisibleForTesting
1698fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    public static String buildAnqpQueryCommand(String bssid, Set<Integer> anqpIds,
1699fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                                               Set<Integer> hs20Subtypes) {
1700fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius
1701fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        boolean baseANQPElements = !anqpIds.isEmpty();
1702fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        StringBuilder sb = new StringBuilder();
1703fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        if (baseANQPElements) {
1704fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            sb.append("ANQP_GET ");
1705fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        } else {
1706fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            // ANQP_GET does not work for a sole hs20:8 (OSU) query
1707fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            sb.append("HS20_ANQP_GET ");
1708fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        }
1709fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        sb.append(bssid).append(' ');
1710fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        boolean first = true;
1711fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        for (Integer id : anqpIds) {
1712fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            if (first) {
1713fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                first = false;
1714fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            } else {
1715fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                sb.append(',');
1716fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            }
1717fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            sb.append(id);
1718fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        }
1719fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        for (Integer subType : hs20Subtypes) {
1720fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            if (first) {
1721fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                first = false;
1722fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            } else {
1723fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                sb.append(',');
1724fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            }
1725fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            if (baseANQPElements) {
1726fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius                sb.append("hs20:");
1727fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            }
1728fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius            sb.append(subType);
1729fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        }
1730fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius        return sb.toString();
1731fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    }
1732fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius
1733fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    /**
1734fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * Request a passpoint icon file |filename| from the specified AP |bssid|.
1735fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param bssid BSSID of the AP
1736fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @param fileName name of the icon file
1737fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     * @return true if request is sent successfully, false otherwise
1738fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius     */
1739fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    public boolean requestIcon(String  bssid, String fileName) {
17405cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        if (HIDL_SUP_ENABLE) {
17415cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return mSupplicantStaIfaceHal.initiateHs20IconQuery(bssid, fileName);
17425cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
17435cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            String result = doStringCommand("REQ_HS20_ICON " + bssid + " " + fileName);
17445cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius            return result != null && result.startsWith("OK");
17455cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
1746fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius    }
1747fc83b303a3382329c28d631b1e0fb2bb35969f85Roshan Pius
17487e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    /* kernel logging support */
17497e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    private static native byte[] readKernelLogNative();
17507e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
17517e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    synchronized public String readKernelLog() {
17527e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        byte[] bytes = readKernelLogNative();
17537e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        if (bytes != null) {
17547e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
17557e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            try {
17567e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
17577e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                return decoded.toString();
17587e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            } catch (CharacterCodingException cce) {
17597e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                return new String(bytes, StandardCharsets.ISO_8859_1);
17607e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            }
17617e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        } else {
17627e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            return "*** failed to read kernel log ***";
17637e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        }
17647e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    }
17657e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
17667f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    /* WIFI HAL support */
17677f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
176818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // HAL command ids
176918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static int sCmdId = 1;
177018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static int getNewCmdIdLocked() {
177118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return sCmdId++;
177218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
177318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
1774b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static final String TAG = "WifiNative-HAL";
1775f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    private static long sWifiHalHandle = 0;             /* used by JNI to save wifi_handle */
1776f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    private static long[] sWifiIfaceHandles = null;     /* used by JNI to save interface handles */
1777956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public static int sWlan0Index = -1;
1778f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    private static MonitorThread sThread;
1779f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande    private static final int STOP_HAL_TIMEOUT_MS = 1000;
17807f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1781b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean startHalNative();
1782b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native void stopHalNative();
1783b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native void waitForHalEventNative();
17847f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1785b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static class MonitorThread extends Thread {
1786cc180872c51908b15ce5cbf834634ff323e036bcChristopher Wiley        @Override
17877ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde        public void run() {
1788b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande            Log.i(TAG, "Waiting for HAL events mWifiHalHandle=" + Long.toString(sWifiHalHandle));
17897ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde            waitForHalEventNative();
17907ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde        }
17917ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    }
17927ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde
1793d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    /**
1794d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     * Bring up the Vendor HAL and configure for STA mode or AP mode.
1795d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     *
1796d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     * @param isStaMode true to start HAL in STA mode, false to start in AP mode.
1797d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     */
1798d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    public boolean startHal(boolean isStaMode) {
1799d6307b404302949f6dadd14fa0860ff1aec432dcxinhe        String debugLog = "startHal stack: ";
1800d6307b404302949f6dadd14fa0860ff1aec432dcxinhe        java.lang.StackTraceElement[] elements = Thread.currentThread().getStackTrace();
1801d6307b404302949f6dadd14fa0860ff1aec432dcxinhe        for (int i = 2; i < elements.length && i <= 7; i++ ) {
1802d6307b404302949f6dadd14fa0860ff1aec432dcxinhe            debugLog = debugLog + " - " + elements[i].getMethodName();
1803d6307b404302949f6dadd14fa0860ff1aec432dcxinhe        }
1804d6307b404302949f6dadd14fa0860ff1aec432dcxinhe
1805956f54b391677d78379729dd14518edddf3c7660Etan Cohen        sLocalLog.log(debugLog);
1806d6307b404302949f6dadd14fa0860ff1aec432dcxinhe
1807956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
1808918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang            if (startHalNative()) {
1809918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                int wlan0Index = queryInterfaceIndex(mInterfaceName);
1810918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                if (wlan0Index == -1) {
1811918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                    if (DBG) sLocalLog.log("Could not find interface with name: " + mInterfaceName);
1812918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                    return false;
1813918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                }
1814918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                sWlan0Index = wlan0Index;
1815f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sThread = new MonitorThread();
1816f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sThread.start();
1817aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle                return true;
1818aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle            } else {
1819956f54b391677d78379729dd14518edddf3c7660Etan Cohen                if (DBG) sLocalLog.log("Could not start hal");
1820f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                Log.e(TAG, "Could not start hal");
1821aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle                return false;
1822aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle            }
18237ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde        }
18247ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    }
18257ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde
182618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void stopHal() {
1827956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
182871d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
1829f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                stopHalNative();
1830f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                try {
1831f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sThread.join(STOP_HAL_TIMEOUT_MS);
1832f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    Log.d(TAG, "HAL event thread stopped successfully");
1833f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } catch (InterruptedException e) {
1834f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    Log.e(TAG, "Could not stop HAL cleanly");
1835f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
1836f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sThread = null;
1837f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sWifiHalHandle = 0;
1838f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sWifiIfaceHandles = null;
1839f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sWlan0Index = -1;
1840f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            }
1841f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        }
18427ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    }
18437f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
184418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean isHalStarted() {
184571d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe        return (sWifiHalHandle != 0);
184671d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe    }
1847b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native int getInterfacesNative();
18487f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1849918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang    public int queryInterfaceIndex(String interfaceName) {
1850956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
185171d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
1852918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                int num = getInterfacesNative();
1853918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                for (int i = 0; i < num; i++) {
1854918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                    String name = getInterfaceNameNative(i);
1855918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                    if (name.equals(interfaceName)) {
1856918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang                        return i;
185702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    }
1858aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle                }
1859e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
1860e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
1861918b4bdc2ae16438c5213320daeff1d551f4aed8Ningyuan Wang        return -1;
18627f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
18637f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1864b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native String getInterfaceNameNative(int index);
186518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getInterfaceName(int index) {
1866956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
186718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            return getInterfaceNameNative(index);
186818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        }
18697f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
18707f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1871062e3f39e37874fedc01f267de5f4cf7dbebe2b4Randy Pan    // TODO: Change variable names to camel style.
1872e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanCapabilities {
1873297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_cache_size;
1874e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_scan_buckets;
1875e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_ap_cache_per_scan;
1876e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_rssi_sample_size;
1877297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_reporting_threshold;
18787d6301ead19afdf3de37455e9ed133c25b4938cdVinit Deshpande        public int  max_hotlist_bssids;
1879e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_significant_wifi_change_aps;
1880d34e3a7b98d51f684100483151fceb233fd95215Roshan Pius        public int  max_bssid_history_entries;
1881d34e3a7b98d51f684100483151fceb233fd95215Roshan Pius        public int  max_number_epno_networks;
1882d34e3a7b98d51f684100483151fceb233fd95215Roshan Pius        public int  max_number_epno_networks_by_ssid;
1883d34e3a7b98d51f684100483151fceb233fd95215Roshan Pius        public int  max_number_of_white_listed_ssid;
1884e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1885e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
188618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean getScanCapabilities(ScanCapabilities capabilities) {
1887956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
1888af5b49884f189bb171c9dc6c6a4405d97e7912acVinit Deshpande            return isHalStarted() && getScanCapabilitiesNative(sWlan0Index, capabilities);
1889af5b49884f189bb171c9dc6c6a4405d97e7912acVinit Deshpande        }
1890e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1891e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1892b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean getScanCapabilitiesNative(
1893b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande            int iface, ScanCapabilities capabilities);
1894e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1895b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean startScanNative(int iface, int id, ScanSettings settings);
1896b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean stopScanNative(int iface, int id);
189783a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande    private static native WifiScanner.ScanData[] getScanResultsNative(int iface, boolean flush);
1898b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native WifiLinkLayerStats getWifiLinkLayerStatsNative(int iface);
1899d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle    private static native void setWifiLinkLayerStatsNative(int iface, int enable);
19007f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1901e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ChannelSettings {
1902712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int frequency;
1903712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int dwell_time_ms;
1904712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public boolean passive;
19057f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
19067f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1907e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class BucketSettings {
1908712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int bucket;
1909712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int band;
1910712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int period_ms;
1911712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_period_ms;
1912712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int step_count;
1913712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_events;
1914712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_channels;
1915712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public ChannelSettings[] channels;
1916e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
19177f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
19186259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    /**
19196259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * Network parameters for hidden networks to be scanned for.
19206259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     */
19216259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public static class HiddenNetwork {
19226259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public String ssid;
19236259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
19246259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        @Override
19256259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public boolean equals(Object otherObj) {
19266259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            if (this == otherObj) {
19276259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return true;
19286259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
19296259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return false;
19306259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            }
19316259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            HiddenNetwork other = (HiddenNetwork) otherObj;
19326259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return Objects.equals(ssid, other.ssid);
19336259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        }
19346259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    }
19356259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
1936e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanSettings {
1937712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int base_period_ms;
1938712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_ap_per_scan;
1939712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_percent;
1940712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_num_scans;
1941712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_buckets;
19426259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        /* Not used for bg scans. Only works for single scans. */
19436259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public HiddenNetwork[] hiddenNetworks;
1944712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public BucketSettings[] buckets;
1945e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
19467f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
194768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
19489bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Network parameters to start PNO scan.
19499bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
19509bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoNetwork {
19519bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public String ssid;
19529bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public byte flags;
1953ef3ea1092bc17673c0a85a845b053151b7c10e07Roshan Pius        public byte auth_bit_field;
19541bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius
19551bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        @Override
19561bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        public boolean equals(Object otherObj) {
19571bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            if (this == otherObj) {
19581bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return true;
19591bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
19601bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return false;
19611bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            }
19621bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            PnoNetwork other = (PnoNetwork) otherObj;
19636259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return ((Objects.equals(ssid, other.ssid)) && (flags == other.flags)
19641bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                    && (auth_bit_field == other.auth_bit_field));
19651bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        }
19669bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
19679bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
19689bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
19699bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Parameters to start PNO scan. This holds the list of networks which are going to used for
19709bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * PNO scan.
19719bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
19729bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoSettings {
19739bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min5GHzRssi;
19749bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min24GHzRssi;
19759bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int initialScoreMax;
19769bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int currentConnectionBonus;
19779bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int sameNetworkBonus;
19789bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int secureBonus;
19799bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int band5GHzBonus;
1980dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        public boolean isConnected;
19819bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public PnoNetwork[] networkList;
19829bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
19839bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
19849bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
198568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Wi-Fi channel information.
198668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
198768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    public static class WifiChannelInfo {
198868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        int mPrimaryFrequency;
198968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        int mCenterFrequency0;
199068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        int mCenterFrequency1;
199168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        int mChannelWidth;
199268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        // TODO: add preamble once available in HAL.
199368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    }
199468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
1995d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
1996d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * Result of a signal poll.
1997d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     */
1998d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public static class SignalPollResult {
1999d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        // RSSI value in dBM.
2000d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        public int currentRssi;
2001d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        //Transmission bit rate in Mbps.
2002d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        public int txBitrate;
2003d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        // Association frequency in MHz.
2004d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        public int associationFrequency;
2005d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
2006d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
2007d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
2008d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * WiFi interface transimission counters.
2009d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     */
2010d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public static class TxPacketCounters {
2011d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        // Number of successfully transmitted packets.
2012d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        public int txSucceeded;
2013d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        // Number of tramsmission failures.
2014d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang        public int txFailed;
2015d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
2016d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
2017b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface ScanEventHandler {
201863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
201963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called for each AP as it is found with the entire contents of the beacon/probe response.
202063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Only called when WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT is specified.
202163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
2022c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills        void onFullScanResult(ScanResult fullScanResult, int bucketsScanned);
202363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
202463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Callback on an event during a gscan scan.
202563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * See WifiNative.WIFI_SCAN_* for possible values.
202663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
202763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        void onScanStatus(int event);
202863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
202963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is paused.
203063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
203183a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande        void onScanPaused(WifiScanner.ScanData[] data);
203263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
203363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is resumed.
203463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
2035b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        void onScanRestarted();
2036e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2037e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
20389bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
20399bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Handler to notify the occurrence of various events during PNO scan.
20409bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
20419bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public interface PnoEventHandler {
20429bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        /**
20439bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * Callback to notify when one of the shortlisted networks is found during PNO scan.
20449bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * @param results List of Scan results received.
20459bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         */
20469bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        void onPnoNetworkFound(ScanResult[] results);
2047063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius
2048063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        /**
2049063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         * Callback to notify when the PNO scan schedule fails.
2050063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         */
2051063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        void onPnoScanFailed();
20529bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
20539bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
2054b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande    /* scan status, keep these values in sync with gscan.h */
205571af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
205671af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1;
205771af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2;
205871af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_FAILED = 3;
2059b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande
206018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
20612a6d76f0899289cd3b96e3428f02076fdbc0363eMitchell Wills    private static void onScanStatus(int id, int event) {
206218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        ScanEventHandler handler = sScanEventHandler;
206363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        if (handler != null) {
206463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills            handler.onScanStatus(event);
20652a6d76f0899289cd3b96e3428f02076fdbc0363eMitchell Wills        }
2066e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2067e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
206818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public static  WifiSsid createWifiSsid(byte[] rawSsid) {
20695cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        String ssidHexString = String.valueOf(HexEncoding.encode(rawSsid));
20705cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20715cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        if (ssidHexString == null) {
20725cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            return null;
20735cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        }
20745cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20755cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        WifiSsid wifiSsid = WifiSsid.createFromHex(ssidHexString);
20765cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20775cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        return wifiSsid;
20785cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe    }
20795cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20805cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe    public static String ssidConvert(byte[] rawSsid) {
20815cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        String ssid;
20825cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20835cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
20845cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        try {
20855cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            CharBuffer decoded = decoder.decode(ByteBuffer.wrap(rawSsid));
20865cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            ssid = decoded.toString();
20875cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        } catch (CharacterCodingException cce) {
20885cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            ssid = null;
20895cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        }
20905cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20915cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        if (ssid == null) {
20925cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            ssid = new String(rawSsid, StandardCharsets.ISO_8859_1);
20935cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        }
20945cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
20955cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        return ssid;
20965cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe    }
20975cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
209818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Called from native
20995cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe    public static boolean setSsid(byte[] rawSsid, ScanResult result) {
21005cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        if (rawSsid == null || rawSsid.length == 0 || result == null) {
21015cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe            return false;
21025cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        }
21035cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
21045cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        result.SSID = ssidConvert(rawSsid);
21055cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        result.wifiSsid = createWifiSsid(rawSsid);
21065cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe        return true;
21075cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe    }
21085cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe
21091ab129e587d334a144a0bca5323c27985397a403Randy Pan    private static void populateScanResult(ScanResult result, int beaconCap, String dbg) {
2110dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        if (dbg == null) dbg = "";
21115d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills
21125d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        InformationElementUtil.HtOperation htOperation = new InformationElementUtil.HtOperation();
21135d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        InformationElementUtil.VhtOperation vhtOperation =
21145d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills                new InformationElementUtil.VhtOperation();
21155d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        InformationElementUtil.ExtendedCapabilities extendedCaps =
21165d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills                new InformationElementUtil.ExtendedCapabilities();
21175d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills
21185d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        ScanResult.InformationElement elements[] =
21191ab129e587d334a144a0bca5323c27985397a403Randy Pan                InformationElementUtil.parseInformationElements(result.bytes);
21205d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        for (ScanResult.InformationElement ie : elements) {
21215d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            if(ie.id == ScanResult.InformationElement.EID_HT_OPERATION) {
21225d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills                htOperation.from(ie);
21235d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            } else if(ie.id == ScanResult.InformationElement.EID_VHT_OPERATION) {
21245d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills                vhtOperation.from(ie);
21255d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            } else if (ie.id == ScanResult.InformationElement.EID_EXTENDED_CAPS) {
21265d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills                extendedCaps.from(ie);
2127243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            }
2128243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        }
2129d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande
2130b86089a48fae8878b5a27533a116c97b0be6d0e7Peter Qiu        if (extendedCaps.is80211McRTTResponder()) {
2131d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande            result.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
2132d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande        } else {
2133d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande            result.clearFlag(ScanResult.FLAG_80211mc_RESPONDER);
2134d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande        }
2135d9f37b2f3df18e96246db93ec4c2a5159b5d3915Vinit Deshpande
2136243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        //handle RTT related information
21375d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills        if (vhtOperation.isValid()) {
21385d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            result.channelWidth = vhtOperation.getChannelWidth();
21395d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            result.centerFreq0 = vhtOperation.getCenterFreq0();
21405d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            result.centerFreq1 = vhtOperation.getCenterFreq1();
2141243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        } else {
21425d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            result.channelWidth = htOperation.getChannelWidth();
21435d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills            result.centerFreq0 = htOperation.getCenterFreq0(result.frequency);
2144243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            result.centerFreq1  = 0;
2145243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        }
21463571366ac36c70746b9f013ec2b54482861c9292Randy Pan
21473571366ac36c70746b9f013ec2b54482861c9292Randy Pan        // build capabilities string
21483571366ac36c70746b9f013ec2b54482861c9292Randy Pan        BitSet beaconCapBits = new BitSet(16);
21493571366ac36c70746b9f013ec2b54482861c9292Randy Pan        for (int i = 0; i < 16; i++) {
21503571366ac36c70746b9f013ec2b54482861c9292Randy Pan            if ((beaconCap & (1 << i)) != 0) {
21513571366ac36c70746b9f013ec2b54482861c9292Randy Pan                beaconCapBits.set(i);
21523571366ac36c70746b9f013ec2b54482861c9292Randy Pan            }
21533571366ac36c70746b9f013ec2b54482861c9292Randy Pan        }
21544d11585ede6636fee294ffb89e832e2f7f271c12Ningyuan Wang        InformationElementUtil.Capabilities capabilities =
21554d11585ede6636fee294ffb89e832e2f7f271c12Ningyuan Wang                new InformationElementUtil.Capabilities();
21564d11585ede6636fee294ffb89e832e2f7f271c12Ningyuan Wang        capabilities.from(elements, beaconCapBits);
21574d11585ede6636fee294ffb89e832e2f7f271c12Ningyuan Wang        result.capabilities = capabilities.generateCapabilitiesString();
21583571366ac36c70746b9f013ec2b54482861c9292Randy Pan
2159243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        if(DBG) {
21603571366ac36c70746b9f013ec2b54482861c9292Randy Pan            Log.d(TAG, dbg + "SSID: " + result.SSID + " ChannelWidth is: " + result.channelWidth
21613571366ac36c70746b9f013ec2b54482861c9292Randy Pan                    + " PrimaryFreq: " + result.frequency + " mCenterfreq0: " + result.centerFreq0
2162b86089a48fae8878b5a27533a116c97b0be6d0e7Peter Qiu                    + " mCenterfreq1: " + result.centerFreq1
2163b86089a48fae8878b5a27533a116c97b0be6d0e7Peter Qiu                    + (extendedCaps.is80211McRTTResponder() ? "Support RTT reponder: "
2164b86089a48fae8878b5a27533a116c97b0be6d0e7Peter Qiu                            : "Do not support RTT responder")
21653571366ac36c70746b9f013ec2b54482861c9292Randy Pan                    + " Capabilities: " + result.capabilities);
2166f1daf9342b66bf134d13fa0a42e929a008f1ca62Vinit Deshapnde        }
2167f1daf9342b66bf134d13fa0a42e929a008f1ca62Vinit Deshapnde
2168476bee2fef10d060c25c35858b1f7f60803d9f49Vinit Deshpande        result.informationElements = elements;
2169dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    }
2170dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
217118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
21721ab129e587d334a144a0bca5323c27985397a403Randy Pan    private static void onFullScanResult(int id, ScanResult result,
21733571366ac36c70746b9f013ec2b54482861c9292Randy Pan            int bucketsScanned, int beaconCap) {
21741ab129e587d334a144a0bca5323c27985397a403Randy Pan        if (DBG) Log.i(TAG, "Got a full scan results event, ssid = " + result.SSID);
2175dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
217618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        ScanEventHandler handler = sScanEventHandler;
217718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null) {
21781ab129e587d334a144a0bca5323c27985397a403Randy Pan            populateScanResult(result, beaconCap, " onFullScanResult ");
2179c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills            handler.onFullScanResult(result, bucketsScanned);
2180dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        }
21817f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
21827f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
2183b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static int sScanCmdId = 0;
2184b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static ScanEventHandler sScanEventHandler;
2185b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static ScanSettings sScanSettings;
21867f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
218718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean startScan(ScanSettings settings, ScanEventHandler eventHandler) {
2188956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
218971d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2190f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sScanCmdId != 0) {
2191f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    stopScan();
2192f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } else if (sScanSettings != null || sScanEventHandler != null) {
2193b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande                /* current scan is paused; no need to stop it */
2194f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
21957f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
2196f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanCmdId = getNewCmdIdLocked();
2197e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2198f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanSettings = settings;
2199f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanEventHandler = eventHandler;
2200b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
2201f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (startScanNative(sWlan0Index, sScanCmdId, settings) == false) {
2202f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sScanEventHandler = null;
2203f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sScanSettings = null;
2204f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sScanCmdId = 0;
2205f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2206f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2207f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
2208f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return true;
2209f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
2210e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde                return false;
2211e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
2212e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
22137f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
22147f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
221518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void stopScan() {
2216956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
221771d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2218ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                if (sScanCmdId != 0) {
2219ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                    stopScanNative(sWlan0Index, sScanCmdId);
2220ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                }
2221f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanSettings = null;
2222f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanEventHandler = null;
2223f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sScanCmdId = 0;
2224f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            }
2225b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        }
2226b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
2227b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
222818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void pauseScan() {
2229956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
223071d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2231f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sScanCmdId != 0 && sScanSettings != null && sScanEventHandler != null) {
2232f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    Log.d(TAG, "Pausing scan");
2233f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    WifiScanner.ScanData scanData[] = getScanResultsNative(sWlan0Index, true);
2234f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    stopScanNative(sWlan0Index, sScanCmdId);
2235f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sScanCmdId = 0;
2236f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sScanEventHandler.onScanPaused(scanData);
2237f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2238b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande            }
2239b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        }
2240b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
2241b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
224218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void restartScan() {
2243956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
224471d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2245f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sScanCmdId == 0 && sScanSettings != null && sScanEventHandler != null) {
22466f3626faf50499dd95aa299bb1011c27ab05776dPierre Vandwalle                    Log.d(TAG, "Restarting scan");
2247f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    ScanEventHandler handler = sScanEventHandler;
2248f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    ScanSettings settings = sScanSettings;
2249f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    if (startScan(sScanSettings, sScanEventHandler)) {
2250f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                        sScanEventHandler.onScanRestarted();
2251f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    } else {
225283a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande                    /* we are still paused; don't change state */
2253f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                        sScanEventHandler = handler;
2254f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                        sScanSettings = settings;
2255f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    }
225683a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande                }
2257b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande            }
2258e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
2259e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2260e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
226118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public WifiScanner.ScanData[] getScanResults(boolean flush) {
2262956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
22633ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande            WifiScanner.ScanData[] sd = null;
226471d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
22653ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande                sd = getScanResultsNative(sWlan0Index, flush);
22663ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande            }
22673ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande
22683ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande            if (sd != null) {
22693ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande                return sd;
2270f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
22713ff269ca67e73f66ac22049fc318b2f86eafb253Vinit Deshpande                return new WifiScanner.ScanData[0];
2272f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            }
2273aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle        }
2274e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2275e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2276b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface HotlistEventHandler {
2277d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande        void onHotlistApFound (ScanResult[] result);
2278d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande        void onHotlistApLost  (ScanResult[] result);
2279e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2280e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2281b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static int sHotlistCmdId = 0;
2282b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static HotlistEventHandler sHotlistEventHandler;
2283e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2284b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private native static boolean setHotlistNative(int iface, int id,
2285e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            WifiScanner.HotlistSettings settings);
2286b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private native static boolean resetHotlistNative(int iface, int id);
2287e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
228818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setHotlist(WifiScanner.HotlistSettings settings,
228918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            HotlistEventHandler eventHandler) {
2290956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
229171d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2292f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sHotlistCmdId != 0) {
2293f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2294f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } else {
2295f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sHotlistCmdId = getNewCmdIdLocked();
2296f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2297f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
2298f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sHotlistEventHandler = eventHandler;
2299f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (setHotlistNative(sWlan0Index, sHotlistCmdId, settings) == false) {
2300f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sHotlistEventHandler = null;
2301f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2302f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2303e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2304f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return true;
2305f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
2306e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde                return false;
2307e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
2308e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
2309e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2310e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
231118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void resetHotlist() {
2312956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
231371d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2314f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sHotlistCmdId != 0) {
2315f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    resetHotlistNative(sWlan0Index, sHotlistCmdId);
2316f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sHotlistCmdId = 0;
2317f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sHotlistEventHandler = null;
2318f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2319e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
23207f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        }
23217f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
2322e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
232318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
232418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static void onHotlistApFound(int id, ScanResult[] results) {
232518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        HotlistEventHandler handler = sHotlistEventHandler;
232618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null) {
232718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onHotlistApFound(results);
232818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        } else {
232918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            /* this can happen because of race conditions */
233018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            Log.d(TAG, "Ignoring hotlist AP found event");
2331d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande        }
2332d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande    }
2333d4762401ec14be6bdd2d27aff2478ddbf8d6ce2aVinit Deshpande
233418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
233518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static void onHotlistApLost(int id, ScanResult[] results) {
233618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        HotlistEventHandler handler = sHotlistEventHandler;
233718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null) {
233818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onHotlistApLost(results);
233918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        } else {
234018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            /* this can happen because of race conditions */
234118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            Log.d(TAG, "Ignoring hotlist AP lost event");
2342aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle        }
2343e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2344e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2345b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface SignificantWifiChangeEventHandler {
2346e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        void onChangesFound(ScanResult[] result);
2347e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2348e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2349b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static SignificantWifiChangeEventHandler sSignificantWifiChangeHandler;
2350b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static int sSignificantWifiChangeCmdId;
2351e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2352b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean trackSignificantWifiChangeNative(
2353e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            int iface, int id, WifiScanner.WifiChangeSettings settings);
2354b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    private static native boolean untrackSignificantWifiChangeNative(int iface, int id);
2355e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
235618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean trackSignificantWifiChange(
2357b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande            WifiScanner.WifiChangeSettings settings, SignificantWifiChangeEventHandler handler) {
2358956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
235971d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2360f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sSignificantWifiChangeCmdId != 0) {
2361f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2362f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } else {
2363f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sSignificantWifiChangeCmdId = getNewCmdIdLocked();
2364f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2365f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande
2366f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sSignificantWifiChangeHandler = handler;
2367851075f4f345d98de885bd2f6b833944b282097eMitchell Wills                if (trackSignificantWifiChangeNative(sWlan0Index, sSignificantWifiChangeCmdId,
2368851075f4f345d98de885bd2f6b833944b282097eMitchell Wills                        settings) == false) {
2369f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sSignificantWifiChangeHandler = null;
2370f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2371f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2372e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2373f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return true;
2374f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
2375e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde                return false;
2376e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
2377e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2378e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
2379e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2380e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
238118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void untrackSignificantWifiChange() {
2382956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
238371d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2384f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sSignificantWifiChangeCmdId != 0) {
2385f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    untrackSignificantWifiChangeNative(sWlan0Index, sSignificantWifiChangeCmdId);
2386f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sSignificantWifiChangeCmdId = 0;
2387f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sSignificantWifiChangeHandler = null;
2388f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2389e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde            }
2390e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        }
2391e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2392e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
239318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
239418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static void onSignificantWifiChange(int id, ScanResult[] results) {
239518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        SignificantWifiChangeEventHandler handler = sSignificantWifiChangeHandler;
239618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null) {
239718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onChangesFound(results);
239818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        } else {
2399f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            /* this can happen because of race conditions */
240018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            Log.d(TAG, "Ignoring significant wifi change");
2401aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle        }
2402e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2403e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
240418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public WifiLinkLayerStats getWifiLinkLayerStats(String iface) {
2405200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        // TODO: use correct iface name to Index translation
2406200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        if (iface == null) return null;
2407956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
240871d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2409aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle                return getWifiLinkLayerStatsNative(sWlan0Index);
2410f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
2411f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return null;
2412f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            }
2413aabe7a9f2f32915fd1f25416a6d2034a844005d6vandwalle        }
24145c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales    }
24155c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
241618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public void setWifiLinkLayerStats(String iface, int enable) {
2417d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle        if (iface == null) return;
2418956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
241971d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2420d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle                setWifiLinkLayerStatsNative(sWlan0Index, enable);
2421d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle            }
2422d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle        }
2423d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle    }
2424d745a52dc4f929d4a4030f205ed173bdf60eaf10Pierre Vandwalle
2425c35361d54d4885c3174499e4ad46d3324387a9bbVinit Deshpande    public static native int getSupportedFeatureSetNative(int iface);
242618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedFeatureSet() {
2427956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
242871d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2429f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return getSupportedFeatureSetNative(sWlan0Index);
2430f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            } else {
2431f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                Log.d(TAG, "Failing getSupportedFeatureset because HAL isn't started");
2432f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return 0;
2433f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            }
2434f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande        }
2435a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    }
2436143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2437143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    /* Rtt related commands/events */
2438143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public static interface RttEventHandler {
2439143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void onRttResults(RttManager.RttResult[] result);
2440143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2441143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2442143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static RttEventHandler sRttEventHandler;
2443143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static int sRttCmdId;
2444143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
244518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
244618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static void onRttResults(int id, RttManager.RttResult[] results) {
244718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        RttEventHandler handler = sRttEventHandler;
244818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null && id == sRttCmdId) {
244902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            Log.d(TAG, "Received " + results.length + " rtt results");
245018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onRttResults(results);
2451143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            sRttCmdId = 0;
2452143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        } else {
245318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            Log.d(TAG, "RTT Received event for unknown cmd = " + id +
245418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    ", current id = " + sRttCmdId);
2455143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
2456143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2457143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2458143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static native boolean requestRangeNative(
2459143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            int iface, int id, RttManager.RttParams[] params);
2460143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static native boolean cancelRangeRequestNative(
2461143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            int iface, int id, RttManager.RttParams[] params);
2462143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
246318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean requestRtt(
2464143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttManager.RttParams[] params, RttEventHandler handler) {
2465956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
246671d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2467f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sRttCmdId != 0) {
246807412d5e025b85de146399081db4851088d86daeWei Wang                    Log.w(TAG, "Last one is still under measurement!");
2469f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2470f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } else {
2471f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sRttCmdId = getNewCmdIdLocked();
2472f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2473f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sRttEventHandler = handler;
2474f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return requestRangeNative(sWlan0Index, sRttCmdId, params);
2475143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            } else {
2476f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return false;
2477143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
2478143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
2479143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2480143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
248118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean cancelRtt(RttManager.RttParams[] params) {
2482956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
248371d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2484f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (sRttCmdId == 0) {
2485f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2486f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2487143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2488f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sRttCmdId = 0;
2489f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe
2490f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                if (cancelRangeRequestNative(sWlan0Index, sRttCmdId, params)) {
2491f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    sRttEventHandler = null;
2492f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return true;
2493f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                } else {
24945cfd8d8b9f241dcad874125a1b5538ee0d6860fexinhe                    Log.e(TAG, "RTT cancel Request failed");
2495f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return false;
2496f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
2497143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            } else {
2498143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                return false;
2499143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
2500143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
2501143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2502042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
250368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    private static int sRttResponderCmdId = 0;
250468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
250568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    private static native ResponderConfig enableRttResponderNative(int iface, int commandId,
250668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            int timeoutSeconds, WifiChannelInfo channelHint);
250768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
250868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder
250968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * role is successfully enabled, {@code null} otherwise.
251068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
251168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    @Nullable
251268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    public ResponderConfig enableRttResponder(int timeoutSeconds) {
251368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        synchronized (sLock) {
251468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (!isHalStarted()) return null;
251568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (sRttResponderCmdId != 0) {
251668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                if (DBG) Log.e(mTAG, "responder mode already enabled - this shouldn't happen");
251768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                return null;
251868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
251968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            int id = getNewCmdIdLocked();
252068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            ResponderConfig config = enableRttResponderNative(
252168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    sWlan0Index, id, timeoutSeconds, null);
252268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (config != null) sRttResponderCmdId = id;
252368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (DBG) Log.d(TAG, "enabling rtt " + (config != null));
252468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            return config;
252568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        }
252668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    }
252768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
252868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    private static native boolean disableRttResponderNative(int iface, int commandId);
252968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
253068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled,
253168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * {@code false} otherwise.
253268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
253368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    public boolean disableRttResponder() {
253468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        synchronized (sLock) {
253568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (!isHalStarted()) return false;
253668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            if (sRttResponderCmdId == 0) {
253768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                Log.e(mTAG, "responder role not enabled yet");
253868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                return true;
253968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
254068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            sRttResponderCmdId = 0;
254168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            return disableRttResponderNative(sWlan0Index, sRttResponderCmdId);
254268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        }
254368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    }
254468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
2545042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande    private static native boolean setScanningMacOuiNative(int iface, byte[] oui);
2546042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
254718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setScanningMacOui(byte[] oui) {
2548956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
254971d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2550042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande                return setScanningMacOuiNative(sWlan0Index, oui);
2551042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande            } else {
2552042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande                return false;
2553042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande            }
2554042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande        }
2555042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande    }
2556efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande
2557efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande    private static native int[] getChannelsForBandNative(
2558efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande            int iface, int band);
2559efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande
256018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int [] getChannelsForBand(int band) {
2561956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
2562ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe            if (isHalStarted()) {
2563ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe                return getChannelsForBandNative(sWlan0Index, band);
256418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            } else {
2565ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe                return null;
2566ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe            }
2567efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande        }
2568efa77c1826499b0a3e57998bd6b3073b107e45d7Vinit Deshpande    }
25690465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande
2570ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe    private static native boolean isGetChannelsForBandSupportedNative();
257118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean isGetChannelsForBandSupported(){
2572956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
2573ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe            if (isHalStarted()) {
2574ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe                return isGetChannelsForBandSupportedNative();
257518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            } else {
2576ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe                return false;
2577ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe            }
2578ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe        }
2579ee0a0132ebb0d7e9baf42e778ea9c094966ffb14xinhe    }
25800465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande
25810465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande    private static native boolean setDfsFlagNative(int iface, boolean dfsOn);
258218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setDfsFlag(boolean dfsOn) {
2583956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
258471d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
25850465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande                return setDfsFlagNative(sWlan0Index, dfsOn);
25860465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande            } else {
25870465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande                return false;
25880465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande            }
25890465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande        }
25900465ff513cdccf7e883a505e14c5b78758e7e458Vinit Deshpande    }
2591b830d76fbf5fa4077531b516066faa2fdbb92e81xinhe
259212cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe    private static native RttManager.RttCapabilities getRttCapabilitiesNative(int iface);
259318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public RttManager.RttCapabilities getRttCapabilities() {
2594956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
259571d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
259612cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe                return getRttCapabilitiesNative(sWlan0Index);
259718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            } else {
259812cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe                return null;
259912cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe            }
260012cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe        }
260112cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe    }
2602939177ff615062ec826601d536466875d8457375xinhe
2603e1dab7a2e3ab5911f812a302b4beed1f6eb5aba7Paul Jensen    private static native ApfCapabilities getApfCapabilitiesNative(int iface);
2604e1dab7a2e3ab5911f812a302b4beed1f6eb5aba7Paul Jensen    public ApfCapabilities getApfCapabilities() {
26056609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen        synchronized (sLock) {
26066609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            if (isHalStarted()) {
2607e1dab7a2e3ab5911f812a302b4beed1f6eb5aba7Paul Jensen                return getApfCapabilitiesNative(sWlan0Index);
26086609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            } else {
26096609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen                return null;
26106609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            }
26116609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen        }
26126609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
26136609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
26146609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    private static native boolean installPacketFilterNative(int iface, byte[] filter);
26156609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    public boolean installPacketFilter(byte[] filter) {
26166609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen        synchronized (sLock) {
26176609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            if (isHalStarted()) {
26186609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen                return installPacketFilterNative(sWlan0Index, filter);
26196609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            } else {
26206609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen                return false;
26216609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen            }
26226609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen        }
26236609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
26246609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
2625939177ff615062ec826601d536466875d8457375xinhe    private static native boolean setCountryCodeHalNative(int iface, String CountryCode);
262618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setCountryCodeHal(String CountryCode) {
2627956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
262871d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2629939177ff615062ec826601d536466875d8457375xinhe                return setCountryCodeHalNative(sWlan0Index, CountryCode);
2630939177ff615062ec826601d536466875d8457375xinhe            } else {
2631939177ff615062ec826601d536466875d8457375xinhe                return false;
2632939177ff615062ec826601d536466875d8457375xinhe            }
2633939177ff615062ec826601d536466875d8457375xinhe        }
2634939177ff615062ec826601d536466875d8457375xinhe    }
2635939177ff615062ec826601d536466875d8457375xinhe
2636d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    /* Rtt related commands/events */
2637d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    public abstract class TdlsEventHandler {
2638d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        abstract public void onTdlsStatus(String macAddr, int status, int reason);
2639d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2640d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2641d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    private static TdlsEventHandler sTdlsEventHandler;
2642d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2643d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    private static native boolean enableDisableTdlsNative(int iface, boolean enable,
2644d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe            String macAddr);
264518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean enableDisableTdls(boolean enable, String macAdd, TdlsEventHandler tdlsCallBack) {
2646956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
2647f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            sTdlsEventHandler = tdlsCallBack;
2648f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            return enableDisableTdlsNative(sWlan0Index, enable, macAdd);
2649d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        }
2650d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2651d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2652d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    // Once TDLS per mac and event feature is implemented, this class definition should be
2653d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    // moved to the right place, like WifiManager etc
2654d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    public static class TdlsStatus {
2655d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        int channel;
2656d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        int global_operating_class;
2657d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        int state;
2658d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        int reason;
2659d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2660d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    private static native TdlsStatus getTdlsStatusNative(int iface, String macAddr);
266118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public TdlsStatus getTdlsStatus(String macAdd) {
2662956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
266371d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2664d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe                return getTdlsStatusNative(sWlan0Index, macAdd);
2665d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe            } else {
2666d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe                return null;
2667d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe            }
2668d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        }
2669d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2670d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2671d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    //ToFix: Once TDLS per mac and event feature is implemented, this class definition should be
2672d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    // moved to the right place, like WifiStateMachine etc
2673d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    public static class TdlsCapabilities {
2674d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        /* Maximum TDLS session number can be supported by the Firmware and hardware */
2675d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        int maxConcurrentTdlsSessionNumber;
2676d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        boolean isGlobalTdlsSupported;
2677d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        boolean isPerMacTdlsSupported;
2678d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        boolean isOffChannelTdlsSupported;
2679d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2680d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2681d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2682d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2683d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    private static native TdlsCapabilities getTdlsCapabilitiesNative(int iface);
268418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public TdlsCapabilities getTdlsCapabilities () {
2685956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
268671d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
2687d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe                return getTdlsCapabilitiesNative(sWlan0Index);
2688d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe            } else {
2689d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe                return null;
2690d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe            }
2691d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe        }
2692d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2693d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
269418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static boolean onTdlsStatus(String macAddr, int status, int reason) {
269518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        TdlsEventHandler handler = sTdlsEventHandler;
269618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler == null) {
269718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            return false;
269818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        } else {
269918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onTdlsStatus(macAddr, status, reason);
270018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            return true;
270118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        }
2702d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2703d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2704a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    //---------------------------------------------------------------------------------
2705a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2706a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    /* Wifi Logger commands/events */
27077d6301ead19afdf3de37455e9ed133c25b4938cdVinit Deshpande
2708a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    public static interface WifiLoggerEventHandler {
27090bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onRingBufferData(RingBufferStatus status, byte[] buffer);
27100bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onWifiAlert(int errorCode, byte[] buffer);
2711a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2712a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2713a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    private static WifiLoggerEventHandler sWifiLoggerEventHandler = null;
2714a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
271518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
27160bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static void onRingBufferData(RingBufferStatus status, byte[] buffer) {
271718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        WifiLoggerEventHandler handler = sWifiLoggerEventHandler;
271818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null)
271918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onRingBufferData(status, buffer);
272003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
272103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
272218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
27230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static void onWifiAlert(byte[] buffer, int errorCode) {
272418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        WifiLoggerEventHandler handler = sWifiLoggerEventHandler;
272518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null)
272618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onWifiAlert(errorCode, buffer);
272703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
272803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2729b797893fc1966803d0c013faac42e6396a37a384xinhe    private static int sLogCmdId = -1;
2730b797893fc1966803d0c013faac42e6396a37a384xinhe    private static native boolean setLoggingEventHandlerNative(int iface, int id);
273118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setLoggingEventHandler(WifiLoggerEventHandler handler) {
2732956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
2733b797893fc1966803d0c013faac42e6396a37a384xinhe            if (isHalStarted()) {
2734b797893fc1966803d0c013faac42e6396a37a384xinhe                int oldId =  sLogCmdId;
2735b797893fc1966803d0c013faac42e6396a37a384xinhe                sLogCmdId = getNewCmdIdLocked();
2736b797893fc1966803d0c013faac42e6396a37a384xinhe                if (!setLoggingEventHandlerNative(sWlan0Index, sLogCmdId)) {
2737b797893fc1966803d0c013faac42e6396a37a384xinhe                    sLogCmdId = oldId;
2738b797893fc1966803d0c013faac42e6396a37a384xinhe                    return false;
2739b797893fc1966803d0c013faac42e6396a37a384xinhe                }
2740b797893fc1966803d0c013faac42e6396a37a384xinhe                sWifiLoggerEventHandler = handler;
2741b797893fc1966803d0c013faac42e6396a37a384xinhe                return true;
2742b797893fc1966803d0c013faac42e6396a37a384xinhe            } else {
2743b797893fc1966803d0c013faac42e6396a37a384xinhe                return false;
2744b797893fc1966803d0c013faac42e6396a37a384xinhe            }
274503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
274603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
274703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
274803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native boolean startLoggingRingBufferNative(int iface, int verboseLevel,
27490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            int flags, int minIntervalSec ,int minDataSize, String ringName);
275018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval,
275103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            int minDataSize, String ringName){
2752956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
275371d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
275403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return startLoggingRingBufferNative(sWlan0Index, verboseLevel, flags, maxInterval,
275503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                        minDataSize, ringName);
275603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
275703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return false;
275803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
275903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
276003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
276103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
276203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native int getSupportedLoggerFeatureSetNative(int iface);
276318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedLoggerFeatureSet() {
2764956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
276571d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
276603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return getSupportedLoggerFeatureSetNative(sWlan0Index);
276703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
2768f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return 0;
276903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
277003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
277103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
277203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2773b797893fc1966803d0c013faac42e6396a37a384xinhe    private static native boolean resetLogHandlerNative(int iface, int id);
277418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean resetLogHandler() {
2775956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
2776b797893fc1966803d0c013faac42e6396a37a384xinhe            if (isHalStarted()) {
2777b797893fc1966803d0c013faac42e6396a37a384xinhe                if (sLogCmdId == -1) {
2778b797893fc1966803d0c013faac42e6396a37a384xinhe                    Log.e(TAG,"Can not reset handler Before set any handler");
2779b797893fc1966803d0c013faac42e6396a37a384xinhe                    return false;
2780b797893fc1966803d0c013faac42e6396a37a384xinhe                }
2781b797893fc1966803d0c013faac42e6396a37a384xinhe                sWifiLoggerEventHandler = null;
2782b797893fc1966803d0c013faac42e6396a37a384xinhe                if (resetLogHandlerNative(sWlan0Index, sLogCmdId)) {
2783b797893fc1966803d0c013faac42e6396a37a384xinhe                    sLogCmdId = -1;
2784b797893fc1966803d0c013faac42e6396a37a384xinhe                    return true;
2785b797893fc1966803d0c013faac42e6396a37a384xinhe                } else {
2786b797893fc1966803d0c013faac42e6396a37a384xinhe                    return false;
2787b797893fc1966803d0c013faac42e6396a37a384xinhe                }
2788b797893fc1966803d0c013faac42e6396a37a384xinhe            } else {
2789b797893fc1966803d0c013faac42e6396a37a384xinhe                return false;
2790b797893fc1966803d0c013faac42e6396a37a384xinhe            }
2791b797893fc1966803d0c013faac42e6396a37a384xinhe        }
2792b797893fc1966803d0c013faac42e6396a37a384xinhe    }
2793b797893fc1966803d0c013faac42e6396a37a384xinhe
279403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native String getDriverVersionNative(int iface);
279518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getDriverVersion() {
2796956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
279771d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
279803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return getDriverVersionNative(sWlan0Index);
279903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
2800f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return "";
280103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
280203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
280303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
280403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
280503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
280603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native String getFirmwareVersionNative(int iface);
280718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getFirmwareVersion() {
2808956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
280971d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
281003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return getFirmwareVersionNative(sWlan0Index);
281103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
2812f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                return "";
281303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
281403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
281503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
281603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
28170bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static class RingBufferStatus{
28180bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        String name;
28190bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int flag;
28200bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferId;
28210bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferByteSize;
28220bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int verboseLevel;
28230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenBytes;
28240bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int readBytes;
28250bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenRecords;
28260bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
282753f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        // Bit masks for interpreting |flag|
282853f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_BINARY_ENTRIES = (1 << 0);
282953f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_ASCII_ENTRIES = (1 << 1);
283053f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_PER_PACKET_ENTRIES = (1 << 2);
283153f278b6fed422a18d763b07216a21e96d9445f9Michael Plass
28320bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
28330bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public String toString() {
28340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
28350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel +
28360bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenBytes: " + writtenBytes + " readBytes: " + readBytes +
28370bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenRecords: " + writtenRecords;
28380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
28390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
28400bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
28410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static native RingBufferStatus[] getRingBufferStatusNative(int iface);
284218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public RingBufferStatus[] getRingBufferStatus() {
2843956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
284471d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
284503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return getRingBufferStatusNative(sWlan0Index);
284603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
284703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return null;
284803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
284903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
285003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
285103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
285203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native boolean getRingBufferDataNative(int iface, String ringName);
285318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean getRingBufferData(String ringName) {
2854956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
285571d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
285603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return getRingBufferDataNative(sWlan0Index, ringName);
285703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            } else {
285803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return false;
285903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
286003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
286103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
286203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
286318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static byte[] mFwMemoryDump;
286418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
286503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static void onWifiFwMemoryAvailable(byte[] buffer) {
286698dca3397c0049d3cfb9c97e2b021c5ee3a2e1bdxinhe        mFwMemoryDump = buffer;
286798dca3397c0049d3cfb9c97e2b021c5ee3a2e1bdxinhe        if (DBG) {
286898dca3397c0049d3cfb9c97e2b021c5ee3a2e1bdxinhe            Log.d(TAG, "onWifiFwMemoryAvailable is called and buffer length is: " +
286998dca3397c0049d3cfb9c97e2b021c5ee3a2e1bdxinhe                    (buffer == null ? 0 :  buffer.length));
287098dca3397c0049d3cfb9c97e2b021c5ee3a2e1bdxinhe        }
287103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
2872127f7244183786e6ccae09e81eeccdac31973e69xinhe
287303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    private static native boolean getFwMemoryDumpNative(int iface);
287418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public byte[] getFwMemoryDump() {
2875956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
287671d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
28770bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                if(getFwMemoryDumpNative(sWlan0Index)) {
28780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    byte[] fwMemoryDump = mFwMemoryDump;
287903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                    mFwMemoryDump = null;
28800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    return fwMemoryDump;
28810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                } else {
28820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    return null;
288303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                }
288403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
2885f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            return null;
2886a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle        }
2887a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2888dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
2889d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    private static native byte[] getDriverStateDumpNative(int iface);
2890d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    /** Fetch the driver state, for driver debugging. */
2891d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    public byte[] getDriverStateDump() {
2892d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal        synchronized (sLock) {
2893d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            if (isHalStarted()) {
2894d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                return getDriverStateDumpNative(sWlan0Index);
2895d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            } else {
2896d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                return null;
2897d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            }
2898d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal        }
2899d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    }
2900d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal
2901dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    //---------------------------------------------------------------------------------
290209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /* Packet fate API */
290309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
290409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
290509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    abstract static class FateReport {
2906eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int USEC_PER_MSEC = 1000;
2907eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // The driver timestamp is a 32-bit counter, in microseconds. This field holds the
2908eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // maximal value of a driver timestamp in milliseconds.
2909eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000);
2910eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
2911eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
291209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFate;
291309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final long mDriverTimestampUSec;
291409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFrameType;
291509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte[] mFrameBytes;
2916eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final long mEstimatedWallclockMSec;
291709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
291809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
291909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFate = fate;
292009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mDriverTimestampUSec = driverTimestampUSec;
2921eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            mEstimatedWallclockMSec =
2922eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    convertDriverTimestampUSecToWallclockMSec(mDriverTimestampUSec);
292309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameType = frameType;
292409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameBytes = frameBytes;
292509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
29260fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2927590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toTableRowString() {
2928590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2929590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2930590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
2931eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            dateFormatter.setTimeZone(TimeZone.getDefault());
2932eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2933eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    mDriverTimestampUSec,
2934eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    dateFormatter.format(new Date(mEstimatedWallclockMSec)),
2935eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    directionToString(), fateToString(), parser.mMostSpecificProtocolString,
2936eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    parser.mTypeString, parser.mResultString);
2937590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2938590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2939590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
2940590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toVerboseStringWithPiiAllowed() {
29410fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            StringWriter sw = new StringWriter();
29420fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            PrintWriter pw = new PrintWriter(sw);
2943590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
29440fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame direction: %s\n", directionToString());
29450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame timestamp: %d\n", mDriverTimestampUSec);
29460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame fate: %s\n", fateToString());
29470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame type: %s\n", frameTypeToString(mFrameType));
2948590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol: %s\n", parser.mMostSpecificProtocolString);
2949590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol type: %s\n", parser.mTypeString);
29500fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame length: %d\n", mFrameBytes.length);
29510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("Frame bytes");
2952590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.append(HexDump.dumpHexString(mFrameBytes));  // potentially contains PII
29530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("\n");
29540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return sw.toString();
29550fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
29560fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2957590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        /* Returns a header to match the output of toTableRowString(). */
2958590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public static String getTableHeader() {
2959590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2960590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2961eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("\n%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2962eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "Time usec", "Walltime", "Direction", "Fate", "Protocol", "Type", "Result");
2963eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2964eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "---------", "--------", "---------", "----", "--------", "----", "------");
2965590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2966590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2967590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
29680fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String directionToString();
29690fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
29700fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String fateToString();
29710fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
29720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        private static String frameTypeToString(byte frameType) {
29730fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (frameType) {
29740fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_UNKNOWN:
29750fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "unknown";
29760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_ETHERNET_II:
29770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "data";
29780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_80211_MGMT:
29790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "802.11 management";
29800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
29810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(frameType);
29820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
29830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
2984eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2985eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        /**
2986eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * Converts a driver timestamp to a wallclock time, based on the current
2987eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * BOOTTIME to wallclock mapping. The driver timestamp is a 32-bit counter of
2988eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * microseconds, with the same base as BOOTTIME.
2989eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         */
2990eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        private static long convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec) {
2991eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long wallclockMillisNow = System.currentTimeMillis();
2992eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long boottimeMillisNow = SystemClock.elapsedRealtime();
2993eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long driverTimestampMillis = driverTimestampUSec / USEC_PER_MSEC;
2994eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2995eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            long boottimeTimestampMillis = boottimeMillisNow % MAX_DRIVER_TIMESTAMP_MSEC;
2996eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            if (boottimeTimestampMillis < driverTimestampMillis) {
2997eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // The 32-bit microsecond count has wrapped between the time that the driver
2998eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // recorded the packet, and the call to this function. Adjust the BOOTTIME
2999eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // timestamp, to compensate.
3000eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                //
3001eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // Note that overflow is not a concern here, since the result is less than
3002eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // 2 * MAX_DRIVER_TIMESTAMP_MSEC. (Given the modulus operation above,
3003eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // boottimeTimestampMillis must be less than MAX_DRIVER_TIMESTAMP_MSEC.) And, since
3004eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // MAX_DRIVER_TIMESTAMP_MSEC is an int, 2 * MAX_DRIVER_TIMESTAMP_MSEC must fit
3005eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // within a long.
3006eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                boottimeTimestampMillis += MAX_DRIVER_TIMESTAMP_MSEC;
3007eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            }
3008eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
3009eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long millisSincePacketTimestamp = boottimeTimestampMillis - driverTimestampMillis;
3010eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            return wallclockMillisNow - millisSincePacketTimestamp;
3011eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        }
301209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
301309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
301409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
301509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one outbound packet.
301609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
301709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
301809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class TxFateReport extends FateReport {
301909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
302009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
302109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
30220fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
30230fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
30240fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
30250fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "TX";
30260fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
30270fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
30280fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
30290fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
30300fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
30310fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_ACKED:
30320fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "acked";
30330fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_SENT:
30340fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "sent";
30350fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_QUEUED:
30360fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
30370fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID:
30380fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
30390fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS:
30400fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
30410fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER:
30420fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
30430fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED:
30440fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
30450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID:
30460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
30470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS:
30480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
30490fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER:
30500fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
30510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
30520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
30530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
30540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
305509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
305609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
305709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
305809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one inbound packet.
305909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
306009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
306109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class RxFateReport extends FateReport {
306209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
306309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
306409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
30650fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
30660fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
30670fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
30680fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "RX";
30690fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
30700fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
30710fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
30720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
30730fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
30740fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_SUCCESS:
30750fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "success";
30760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_QUEUED:
30770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
30780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER:
30790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (filter)";
30800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID:
30810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
30820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS:
30830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
30840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER:
30850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
30860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED:
30870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
30880fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER:
30890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (filter)";
30900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID:
30910fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
30920fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS:
30930fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
30940fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER:
30950fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
30960fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
30970fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
30980fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
30990fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
310009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
310109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
310209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    private static native int startPktFateMonitoringNative(int iface);
31030fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
31040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Ask the HAL to enable packet fate monitoring. Fails unless HAL is started.
31050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
31060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean startPktFateMonitoring() {
31070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        synchronized (sLock) {
31080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            if (isHalStarted()) {
31090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                return startPktFateMonitoringNative(sWlan0Index) == WIFI_SUCCESS;
31100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            } else {
31110fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                return false;
31120fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
31130fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
31140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
31150fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
311609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    private static native int getTxPktFatesNative(int iface, TxFateReport[] reportBufs);
31170fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
31180fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent TX packet fates from the HAL. Fails unless HAL is started.
31190fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
31200fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean getTxPktFates(TxFateReport[] reportBufs) {
31210fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        synchronized (sLock) {
31220fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            if (isHalStarted()) {
31230fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                int res = getTxPktFatesNative(sWlan0Index, reportBufs);
31240fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                if (res != WIFI_SUCCESS) {
31250fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    Log.e(TAG, "getTxPktFatesNative returned " + res);
31260fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return false;
31270fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                } else {
31280fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return true;
31290fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                }
31300fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            } else {
31310fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                return false;
31320fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
31330fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
31340fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
31350fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
313609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    private static native int getRxPktFatesNative(int iface, RxFateReport[] reportBufs);
31370fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
31380fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent RX packet fates from the HAL. Fails unless HAL is started.
31390fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
31400fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean getRxPktFates(RxFateReport[] reportBufs) {
31410fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        synchronized (sLock) {
31420fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            if (isHalStarted()) {
31430fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                int res = getRxPktFatesNative(sWlan0Index, reportBufs);
31440fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                if (res != WIFI_SUCCESS) {
31450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    Log.e(TAG, "getRxPktFatesNative returned " + res);
31460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return false;
31470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                } else {
31480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return true;
31490fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                }
31500fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            } else {
31510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                return false;
31520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
31530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
31540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
315509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
315609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    //---------------------------------------------------------------------------------
31575c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius    /* Configure ePNO/PNO */
31589bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    private static PnoEventHandler sPnoEventHandler;
31599bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    private static int sPnoCmdId = 0;
3160dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
31619bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    private static native boolean setPnoListNative(int iface, int id, PnoSettings settings);
316218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
31635c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius    /**
31649bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Set the PNO settings & the network list in HAL to start PNO.
31659bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @param settings PNO settings and network list.
31669bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @param eventHandler Handler to receive notifications back during PNO scan.
31679bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @return true if success, false otherwise
31685c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius     */
31699bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public boolean setPnoList(PnoSettings settings, PnoEventHandler eventHandler) {
31709bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        Log.e(TAG, "setPnoList cmd " + sPnoCmdId);
3171dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
31729bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        synchronized (sLock) {
31739bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius            if (isHalStarted()) {
31749bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                sPnoCmdId = getNewCmdIdLocked();
31759bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                sPnoEventHandler = eventHandler;
31769bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                if (setPnoListNative(sWlan0Index, sPnoCmdId, settings)) {
31779bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                    return true;
31789bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                }
3179dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle            }
31809bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius            sPnoEventHandler = null;
31819bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius            return false;
3182dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        }
3183dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    }
3184dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
31859bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
31869bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Set the PNO network list in HAL to start PNO.
31879bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @param list PNO network list.
31889bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @param eventHandler Handler to receive notifications back during PNO scan.
31899bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @return true if success, false otherwise
31909bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
31919bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public boolean setPnoList(PnoNetwork[] list, PnoEventHandler eventHandler) {
31929bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        PnoSettings settings = new PnoSettings();
31939bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        settings.networkList = list;
31949bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        return setPnoList(settings, eventHandler);
3195dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    }
3196dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
31979bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    private static native boolean resetPnoListNative(int iface, int id);
3198dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
31999bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
32009bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Reset the PNO settings in HAL to stop PNO.
32019bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * @return true if success, false otherwise
32029bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
32039bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public boolean resetPnoList() {
32049bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        Log.e(TAG, "resetPnoList cmd " + sPnoCmdId);
3205dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
3206956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
320771d0be16c79791a005d60f9d5fa7d2d81e1f8c80xinhe            if (isHalStarted()) {
3208f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                sPnoCmdId = getNewCmdIdLocked();
32099bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                sPnoEventHandler = null;
32109bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius                if (resetPnoListNative(sWlan0Index, sPnoCmdId)) {
3211f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                    return true;
3212f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande                }
3213dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle            }
3214f49a59bda006b13e0118d144e0a4a5f569b2251eVinit Deshpande            return false;
3215dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        }
3216dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    }
3217dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
321818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
32193571366ac36c70746b9f013ec2b54482861c9292Randy Pan    private static void onPnoNetworkFound(int id, ScanResult[] results, int[] beaconCaps) {
3220dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        if (results == null) {
3221dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle            Log.e(TAG, "onPnoNetworkFound null results");
3222dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle            return;
3223dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
3224dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        }
3225dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        Log.d(TAG, "WifiNative.onPnoNetworkFound result " + results.length);
3226dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
32279bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        PnoEventHandler handler = sPnoEventHandler;
322818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (sPnoCmdId != 0 && handler != null) {
322918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            for (int i=0; i<results.length; i++) {
323018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                Log.e(TAG, "onPnoNetworkFound SSID " + results[i].SSID
323118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                        + " " + results[i].level + " " + results[i].frequency);
3232dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
32331ab129e587d334a144a0bca5323c27985397a403Randy Pan                populateScanResult(results[i], beaconCaps[i], "onPnoNetworkFound ");
323418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                results[i].wifiSsid = WifiSsid.createFromAsciiEncoded(results[i].SSID);
3235dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle            }
323618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
323718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onPnoNetworkFound(results);
323818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        } else {
323918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            /* this can happen because of race conditions */
324018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            Log.d(TAG, "Ignoring Pno Network found event");
3241dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle        }
3242d4c25fd76644d5490700ae69fada4669de5193a1Pierre Vandwalle    }
3243d4c25fd76644d5490700ae69fada4669de5193a1Pierre Vandwalle
3244c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    private native static int startSendingOffloadedPacketNative(int iface, int idx,
3245c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham                                    byte[] srcMac, byte[] dstMac, byte[] pktData, int period);
3246c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
324718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int
3248c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    startSendingOffloadedPacket(int slot, KeepalivePacketData keepAlivePacket, int period) {
3249c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham        Log.d(TAG, "startSendingOffloadedPacket slot=" + slot + " period=" + period);
32503bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham
32513bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        String[] macAddrStr = getMacAddress().split(":");
32523bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        byte[] srcMac = new byte[6];
32533bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        for(int i = 0; i < 6; i++) {
32543bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham            Integer hexVal = Integer.parseInt(macAddrStr[i], 16);
32553bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham            srcMac[i] = hexVal.byteValue();
32563bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        }
3257956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
3258c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            if (isHalStarted()) {
3259c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham                return startSendingOffloadedPacketNative(sWlan0Index, slot, srcMac,
326018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                        keepAlivePacket.dstMac, keepAlivePacket.data, period);
3261c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            } else {
3262c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham                return -1;
3263c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            }
3264c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham        }
3265c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
3266c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
3267c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    private native static int stopSendingOffloadedPacketNative(int iface, int idx);
3268c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
326918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int
3270c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    stopSendingOffloadedPacket(int slot) {
3271c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham        Log.d(TAG, "stopSendingOffloadedPacket " + slot);
3272956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
3273c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            if (isHalStarted()) {
3274c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham                return stopSendingOffloadedPacketNative(sWlan0Index, slot);
3275c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            } else {
3276c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham                return -1;
3277c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham            }
3278c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham        }
3279c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
3280aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
3281aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    public static interface WifiRssiEventHandler {
3282aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        void onRssiThresholdBreached(byte curRssi);
3283aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
3284aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
3285aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    private static WifiRssiEventHandler sWifiRssiEventHandler;
3286aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
328718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    // Callback from native
328818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private static void onRssiThresholdBreached(int id, byte curRssi) {
328918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        WifiRssiEventHandler handler = sWifiRssiEventHandler;
329018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (handler != null) {
329118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            handler.onRssiThresholdBreached(curRssi);
329218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        }
3293aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
3294aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
3295aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    private native static int startRssiMonitoringNative(int iface, int id,
3296aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                                        byte maxRssi, byte minRssi);
3297aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
3298aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    private static int sRssiMonitorCmdId = 0;
3299aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
330018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int startRssiMonitoring(byte maxRssi, byte minRssi,
3301aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                                                WifiRssiEventHandler rssiEventHandler) {
3302aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        Log.d(TAG, "startRssiMonitoring: maxRssi=" + maxRssi + " minRssi=" + minRssi);
3303956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
330418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            sWifiRssiEventHandler = rssiEventHandler;
3305aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            if (isHalStarted()) {
3306ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                if (sRssiMonitorCmdId != 0) {
3307ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                    stopRssiMonitoring();
3308ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                }
3309ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills
3310aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                sRssiMonitorCmdId = getNewCmdIdLocked();
3311aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                Log.d(TAG, "sRssiMonitorCmdId = " + sRssiMonitorCmdId);
3312ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                int ret = startRssiMonitoringNative(sWlan0Index, sRssiMonitorCmdId,
3313ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                        maxRssi, minRssi);
3314ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                if (ret != 0) { // if not success
3315ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                    sRssiMonitorCmdId = 0;
3316ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                }
3317ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                return ret;
3318aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            } else {
3319aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                return -1;
3320aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            }
3321aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        }
3322aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
3323aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
3324aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    private native static int stopRssiMonitoringNative(int iface, int idx);
3325aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
332618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int stopRssiMonitoring() {
3327aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        Log.d(TAG, "stopRssiMonitoring, cmdId " + sRssiMonitorCmdId);
3328956f54b391677d78379729dd14518edddf3c7660Etan Cohen        synchronized (sLock) {
3329aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            if (isHalStarted()) {
3330ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                int ret = 0;
3331ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                if (sRssiMonitorCmdId != 0) {
3332ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                    ret = stopRssiMonitoringNative(sWlan0Index, sRssiMonitorCmdId);
3333ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                }
3334ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                sRssiMonitorCmdId = 0;
3335ed34692d4c4e202748d41f90db397f1cc3dc8320Mitchell Wills                return ret;
3336aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            } else {
3337aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham                return -1;
3338aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham            }
3339aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        }
3340aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
33415ea42964ba17901a8d724736b450ace6ed48880fPrerepa Viswanadham
33425ea42964ba17901a8d724736b450ace6ed48880fPrerepa Viswanadham    private static native WifiWakeReasonAndCounts getWlanWakeReasonCountNative(int iface);
33436bf6986d359556010638dfae332b585162f06520Roshan Pius
33446bf6986d359556010638dfae332b585162f06520Roshan Pius    /**
33456bf6986d359556010638dfae332b585162f06520Roshan Pius     * Fetch the host wakeup reasons stats from wlan driver.
33466bf6986d359556010638dfae332b585162f06520Roshan Pius     * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver.
33476bf6986d359556010638dfae332b585162f06520Roshan Pius     */
33486bf6986d359556010638dfae332b585162f06520Roshan Pius    public WifiWakeReasonAndCounts getWlanWakeReasonCount() {
33496bf6986d359556010638dfae332b585162f06520Roshan Pius        Log.d(TAG, "getWlanWakeReasonCount " + sWlan0Index);
33506bf6986d359556010638dfae332b585162f06520Roshan Pius        synchronized (sLock) {
33516bf6986d359556010638dfae332b585162f06520Roshan Pius            if (isHalStarted()) {
33526bf6986d359556010638dfae332b585162f06520Roshan Pius                return getWlanWakeReasonCountNative(sWlan0Index);
33536bf6986d359556010638dfae332b585162f06520Roshan Pius            } else {
33546bf6986d359556010638dfae332b585162f06520Roshan Pius                return null;
33556bf6986d359556010638dfae332b585162f06520Roshan Pius            }
33566bf6986d359556010638dfae332b585162f06520Roshan Pius        }
33576bf6986d359556010638dfae332b585162f06520Roshan Pius    }
33583dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline
33593dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    private static native int configureNeighborDiscoveryOffload(int iface, boolean enabled);
33603dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline
33613dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    public boolean configureNeighborDiscoveryOffload(boolean enabled) {
33623dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline        final String logMsg =  "configureNeighborDiscoveryOffload(" + enabled + ")";
33633dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline        Log.d(mTAG, logMsg);
33643dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline        synchronized (sLock) {
33653dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline            if (isHalStarted()) {
33663dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline                final int ret = configureNeighborDiscoveryOffload(sWlan0Index, enabled);
33673dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline                if (ret != 0) {
33683dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline                    Log.d(mTAG, logMsg + " returned: " + ret);
33693dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline                }
33703dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline                return (ret == 0);
33713dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline            }
33723dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline        }
33733dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline        return false;
33743dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    }
3375da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3376da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    // Firmware roaming control.
3377da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3378da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3379da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class to retrieve firmware roaming capability parameters.
3380da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3381da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingCapabilities {
3382da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxBlacklistSize;
3383da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxWhitelistSize;
3384da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3385da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3386da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3387da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Query the firmware roaming capabilities.
3388da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3389da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public boolean getRoamingCapabilities(RoamingCapabilities capabilities) {
3390da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        Log.d(TAG, "getRoamingCapabilities ");
3391da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        try {
3392da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            if (mWifiVendorHal != null) {
3393da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan                return mWifiVendorHal.getRoamingCapabilities(capabilities);
3394da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            }
3395da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        } catch (UnsupportedOperationException e) {
3396da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        }
3397da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3398da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        return false;
3399da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3400da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3401da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3402da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Macros for controlling firmware roaming.
3403da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3404da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int DISABLE_FIRMWARE_ROAMING = 0;
3405da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int ENABLE_FIRMWARE_ROAMING = 1;
3406da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3407da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3408da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Enable/disable firmware roaming.
3409da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3410da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public int enableFirmwareRoaming(int state) {
3411da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        Log.d(TAG, "enableFirmwareRoaming: state =" + state);
3412da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        try {
3413da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            if (mWifiVendorHal != null) {
3414da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan                return mWifiVendorHal.enableFirmwareRoaming(state);
3415da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            }
3416da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        } catch (UnsupportedOperationException e) {
3417da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        }
3418da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3419da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        return -1;
3420da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3421da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3422da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3423da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class for specifying the roaming configurations.
3424da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3425da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingConfig {
3426da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> blacklistBssids;
3427da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> whitelistSsids;
3428da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3429da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3430da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
3431da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Set firmware roaming configurations.
3432da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
3433da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public boolean configureRoaming(RoamingConfig config) {
3434da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        Log.d(TAG, "configureRoaming ");
3435da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        try {
3436da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            if (mWifiVendorHal != null) {
3437da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan                return mWifiVendorHal.configureRoaming(config);
3438da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan            }
3439da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        } catch (UnsupportedOperationException e) {
3440da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        }
3441da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3442da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        return false;
3443da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3444da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3445374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    /**
3446374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     * Reset firmware roaming configuration.
3447374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     */
3448374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    public boolean resetRoamingConfiguration() {
3449374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        Log.d(TAG, "resetRoamingConfiguration ");
3450374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        try {
3451374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan            if (mWifiVendorHal != null) {
3452374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan                // Pass in an empty RoamingConfig object which translates to zero size
3453374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan                // blacklist and whitelist to reset the firmware roaming configuration.
3454374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan                RoamingConfig config = new RoamingConfig();
3455374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan                return mWifiVendorHal.configureRoaming(config);
3456374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan            }
3457374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        } catch (UnsupportedOperationException e) {
3458374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        }
3459374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan
3460374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        return false;
3461374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    }
3462374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan
3463da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
3464da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    StackTraceElement[] mTrace;
3465da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    void legacyHalWarning() {
3466da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        Thread cur = Thread.currentThread();
3467da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        mTrace = cur.getStackTrace();
3468da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        StackTraceElement s = mTrace[3];
3469da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        Log.e(TAG, "LEGACY HAL th " + cur.getId()
3470da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan                + " line " + s.getLineNumber() + " " + s.getMethodName());
3471da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
3472155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
3473