/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wifi;

import android.net.wifi.BatchedScanSettings;
import android.net.wifi.RttManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiLinkLayerStats;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.RttManager;
import android.net.wifi.WifiSsid;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
import android.net.wifi.WifiEnterpriseConfig;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Base64;
import android.util.LocalLog;
import android.util.Log;
import android.content.Context;
import android.content.Intent;
import android.app.PendingIntent;
import android.content.IntentFilter;
import android.content.BroadcastReceiver;
import com.android.server.connectivity.KeepalivePacketData;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.zip.Deflater;
import libcore.util.HexEncoding;
import android.app.AlarmManager;
/**
 * Native calls for bring up/shut down of the supplicant daemon and for
 * sending requests to the supplicant daemon
 *
 * waitForEvent() is called on the monitor thread for events. All other methods
 * must be serialized from the framework.
 *
 * {@hide}
 */
public class WifiNative {

    private static boolean DBG = false;
    private final String mTAG;
    private static final int DEFAULT_GROUP_OWNER_INTENT     = 6;

    static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED     = 0;
    static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED    = 1;
    static final int BLUETOOTH_COEXISTENCE_MODE_SENSE       = 2;

    static final int SCAN_WITHOUT_CONNECTION_SETUP          = 1;
    static final int SCAN_WITH_CONNECTION_SETUP             = 2;

    // Hold this lock before calling supplicant - it is required to
    // mutually exclude access from Wifi and P2p state machines
    static final Object mLock = new Object();

    public final String mInterfaceName;
    public final String mInterfacePrefix;

    private boolean mSuspendOptEnabled = false;

    private static final int EID_HT_OPERATION = 61;
    private static final int EID_VHT_OPERATION = 192;
    private static final int EID_EXTENDED_CAPS = 127;
    private static final int RTT_RESP_ENABLE_BIT = 70;
    /* Register native functions */

    static {
        /* Native functions are defined in libwifi-service.so */
        System.loadLibrary("wifi-service");
        registerNatives();
    }

    private static native int registerNatives();

    public native static boolean loadDriver();

    public native static boolean isDriverLoaded();

    public native static boolean unloadDriver();

    public native static boolean startSupplicant(boolean p2pSupported);

    /* Sends a kill signal to supplicant. To be used when we have lost connection
       or when the supplicant is hung */
    public native static boolean killSupplicant(boolean p2pSupported);

    private native boolean connectToSupplicantNative();

    private native void closeSupplicantConnectionNative();

    /**
     * Wait for the supplicant to send an event, returning the event string.
     * @return the event string sent by the supplicant.
     */
    private native String waitForEventNative();

    private native boolean doBooleanCommandNative(String command);

    private native int doIntCommandNative(String command);

    private native String doStringCommandNative(String command);

    private final Context mContext;
    private final PnoMonitor mPnoMonitor;
    public WifiNative(String interfaceName, Context context) {
        mInterfaceName = interfaceName;
        mContext = context;
        mTAG = "WifiNative-" + interfaceName;
        if (mContext != null) {
            mPnoMonitor = new PnoMonitor();
        } else {
            mPnoMonitor = null;
        }

        if (!interfaceName.equals("p2p0")) {
            mInterfacePrefix = "IFNAME=" + interfaceName + " ";
        } else {
            // commands for p2p0 interface don't need prefix
            mInterfacePrefix = "";
        }
    }

    public WifiNative(String interfaceName) {
        this(interfaceName, null);
    }

    void enableVerboseLogging(int verbose) {
        if (verbose > 0) {
            DBG = true;
        } else {
            DBG = false;
        }
    }

    private static final LocalLog mLocalLog = new LocalLog(16384);

    // hold mLock before accessing mCmdIdLock
    private static int sCmdId;

    public static LocalLog getLocalLog() {
        return mLocalLog;
    }

    private static int getNewCmdIdLocked() {
        return sCmdId++;
    }

    private void localLog(String s) {
        if (mLocalLog != null)
            mLocalLog.log(mInterfaceName + ": " + s);
    }

    public boolean connectToSupplicant() {
        synchronized(mLock) {
            localLog(mInterfacePrefix + "connectToSupplicant");
            return connectToSupplicantNative();
        }
    }

    public void closeSupplicantConnection() {
        synchronized(mLock) {
            localLog(mInterfacePrefix + "closeSupplicantConnection");
            closeSupplicantConnectionNative();
        }
    }

    public String waitForEvent() {
        // No synchronization necessary .. it is implemented in WifiMonitor
        return waitForEventNative();
    }

    private boolean doBooleanCommand(String command) {
        if (DBG) Log.d(mTAG, "doBoolean: " + command);
        synchronized (mLock) {
            int cmdId = getNewCmdIdLocked();
            String toLog = Integer.toString(cmdId) + ":" + mInterfacePrefix + command;
            boolean result = doBooleanCommandNative(mInterfacePrefix + command);
            localLog(toLog + " -> " + result);
            if (DBG) Log.d(mTAG, command + ": returned " + result);
            return result;
        }
    }

    private boolean doBooleanCommandWithoutLogging(String command) {
        if (DBG) Log.d(mTAG, "doBooleanCommandWithoutLogging: " + command);
        synchronized (mLock) {
            int cmdId = getNewCmdIdLocked();
            boolean result = doBooleanCommandNative(mInterfacePrefix + command);
            if (DBG) Log.d(mTAG, command + ": returned " + result);
            return result;
        }
    }

    private int doIntCommand(String command) {
        if (DBG) Log.d(mTAG, "doInt: " + command);
        synchronized (mLock) {
            int cmdId = getNewCmdIdLocked();
            String toLog = Integer.toString(cmdId) + ":" + mInterfacePrefix + command;
            int result = doIntCommandNative(mInterfacePrefix + command);
            localLog(toLog + " -> " + result);
            if (DBG) Log.d(mTAG, "   returned " + result);
            return result;
        }
    }

    private String doStringCommand(String command) {
        if (DBG) {
            //GET_NETWORK commands flood the logs
            if (!command.startsWith("GET_NETWORK")) {
                Log.d(mTAG, "doString: [" + command + "]");
            }
        }
        synchronized (mLock) {
            int cmdId = getNewCmdIdLocked();
            String toLog = Integer.toString(cmdId) + ":" + mInterfacePrefix + command;
            String result = doStringCommandNative(mInterfacePrefix + command);
            if (result == null) {
                if (DBG) Log.d(mTAG, "doStringCommandNative no result");
            } else {
                if (!command.startsWith("STATUS-")) {
                    localLog(toLog + " -> " + result);
                }
                if (DBG) Log.d(mTAG, "   returned " + result.replace("\n", " "));
            }
            return result;
        }
    }

    private String doStringCommandWithoutLogging(String command) {
        if (DBG) {
            //GET_NETWORK commands flood the logs
            if (!command.startsWith("GET_NETWORK")) {
                Log.d(mTAG, "doString: [" + command + "]");
            }
        }
        synchronized (mLock) {
            return doStringCommandNative(mInterfacePrefix + command);
        }
    }

    public boolean ping() {
        String pong = doStringCommand("PING");
        return (pong != null && pong.equals("PONG"));
    }

    public void setSupplicantLogLevel(String level) {
        doStringCommand("LOG_LEVEL " + level);
    }

    public String getFreqCapability() {
        return doStringCommand("GET_CAPABILITY freq");
    }

    public boolean scan(int type, String freqList) {
        if (type == SCAN_WITHOUT_CONNECTION_SETUP) {
            if (freqList == null) return doBooleanCommand("SCAN TYPE=ONLY");
            else return doBooleanCommand("SCAN TYPE=ONLY freq=" + freqList);
        } else if (type == SCAN_WITH_CONNECTION_SETUP) {
            if (freqList == null) return doBooleanCommand("SCAN");
            else return doBooleanCommand("SCAN freq=" + freqList);
        } else {
            throw new IllegalArgumentException("Invalid scan type");
        }
    }

    /* Does a graceful shutdown of supplicant. Is a common stop function for both p2p and sta.
     *
     * Note that underneath we use a harsh-sounding "terminate" supplicant command
     * for a graceful stop and a mild-sounding "stop" interface
     * to kill the process
     */
    public boolean stopSupplicant() {
        return doBooleanCommand("TERMINATE");
    }

    public String listNetworks() {
        return doStringCommand("LIST_NETWORKS");
    }

    public String listNetworks(int last_id) {
        return doStringCommand("LIST_NETWORKS LAST_ID=" + last_id);
    }

    public int addNetwork() {
        return doIntCommand("ADD_NETWORK");
    }

    public boolean setNetworkVariable(int netId, String name, String value) {
        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(value)) return false;
        if (name.equals(WifiConfiguration.pskVarName)
                || name.equals(WifiEnterpriseConfig.PASSWORD_KEY)) {
            return doBooleanCommandWithoutLogging("SET_NETWORK " + netId + " " + name + " " + value);
        } else {
            return doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value);
        }
    }

    public String getNetworkVariable(int netId, String name) {
        if (TextUtils.isEmpty(name)) return null;

        // GET_NETWORK will likely flood the logs ...
        return doStringCommandWithoutLogging("GET_NETWORK " + netId + " " + name);
    }

    public boolean removeNetwork(int netId) {
        return doBooleanCommand("REMOVE_NETWORK " + netId);
    }


    private void logDbg(String debug) {
        long now = SystemClock.elapsedRealtimeNanos();
        String ts = String.format("[%,d us] ", now/1000);
        Log.e("WifiNative: ", ts+debug+ " stack:"
                + Thread.currentThread().getStackTrace()[2].getMethodName() +" - "
                + Thread.currentThread().getStackTrace()[3].getMethodName() +" - "
                + Thread.currentThread().getStackTrace()[4].getMethodName() +" - "
                + Thread.currentThread().getStackTrace()[5].getMethodName()+" - "
                + Thread.currentThread().getStackTrace()[6].getMethodName());

    }
    public boolean enableNetwork(int netId, boolean disableOthers) {
        if (DBG) logDbg("enableNetwork nid=" + Integer.toString(netId)
                + " disableOthers=" + disableOthers);
        if (disableOthers) {
            return doBooleanCommand("SELECT_NETWORK " + netId);
        } else {
            return doBooleanCommand("ENABLE_NETWORK " + netId);
        }
    }

    public boolean disableNetwork(int netId) {
        if (DBG) logDbg("disableNetwork nid=" + Integer.toString(netId));
        return doBooleanCommand("DISABLE_NETWORK " + netId);
    }

    public boolean selectNetwork(int netId) {
        if (DBG) logDbg("selectNetwork nid=" + Integer.toString(netId));
        return doBooleanCommand("SELECT_NETWORK " + netId);
    }

    public boolean reconnect() {
        if (DBG) logDbg("RECONNECT ");
        return doBooleanCommand("RECONNECT");
    }

    public boolean reassociate() {
        if (DBG) logDbg("REASSOCIATE ");
        return doBooleanCommand("REASSOCIATE");
    }

    public boolean disconnect() {
        if (DBG) logDbg("DISCONNECT ");
        return doBooleanCommand("DISCONNECT");
    }

    public String status() {
        return status(false);
    }

    public String status(boolean noEvents) {
        if (noEvents) {
            return doStringCommand("STATUS-NO_EVENTS");
        } else {
            return doStringCommand("STATUS");
        }
    }

    public String getMacAddress() {
        //Macaddr = XX.XX.XX.XX.XX.XX
        String ret = doStringCommand("DRIVER MACADDR");
        if (!TextUtils.isEmpty(ret)) {
            String[] tokens = ret.split(" = ");
            if (tokens.length == 2) return tokens[1];
        }
        return null;
    }



    /**
     * Format of results:
     * =================
     * id=1
     * bssid=68:7f:74:d7:1b:6e
     * freq=2412
     * level=-43
     * tsf=1344621975160944
     * age=2623
     * flags=[WPA2-PSK-CCMP][WPS][ESS]
     * ssid=zubyb
     * ====
     *
     * RANGE=ALL gets all scan results
     * RANGE=ID- gets results from ID
     * MASK=<N> see wpa_supplicant/src/common/wpa_ctrl.h for details
     * 0                         0                        1                       0     2
     *                           WPA_BSS_MASK_MESH_SCAN | WPA_BSS_MASK_DELIM    | WPA_BSS_MASK_WIFI_DISPLAY
     * 0                         0                        0                       1     1   -> 9
     * WPA_BSS_MASK_INTERNETW  | WPA_BSS_MASK_P2P_SCAN  | WPA_BSS_MASK_WPS_SCAN | WPA_BSS_MASK_SSID
     * 1                         0                        0                       1     9   -> d
     * WPA_BSS_MASK_FLAGS      | WPA_BSS_MASK_IE        | WPA_BSS_MASK_AGE      | WPA_BSS_MASK_TSF
     * 1                         0                        0                       0     8
     * WPA_BSS_MASK_LEVEL      | WPA_BSS_MASK_NOISE     | WPA_BSS_MASK_QUAL     | WPA_BSS_MASK_CAPABILITIES
     * 0                         1                        1                       1     7
     * WPA_BSS_MASK_BEACON_INT | WPA_BSS_MASK_FREQ      | WPA_BSS_MASK_BSSID    | WPA_BSS_MASK_ID
     *
     * WPA_BSS_MASK_INTERNETW adds ANQP info (ctrl_iface:4151-4176)
     *
     * ctrl_iface.c:wpa_supplicant_ctrl_iface_process:7884
     *  wpa_supplicant_ctrl_iface_bss:4315
     *  print_bss_info
     */
    public String scanResults(int sid) {
        return doStringCommandWithoutLogging("BSS RANGE=" + sid + "- MASK=0x29d87");
    }

    public String doCustomCommand(String command) {
        return doStringCommand(command);
    }

    /**
     * Format of result:
     * id=1016
     * bssid=00:03:7f:40:84:10
     * freq=2462
     * beacon_int=200
     * capabilities=0x0431
     * qual=0
     * noise=0
     * level=-46
     * tsf=0000002669008476
     * age=5
     * ie=00105143412d485332302d52322d54455354010882848b960c12182403010b0706555...
     * flags=[WPA2-EAP-CCMP][ESS][P2P][HS20]
     * ssid=QCA-HS20-R2-TEST
     * p2p_device_name=
     * p2p_config_methods=0x0SET_NE
     * anqp_venue_name=02083d656e6757692d466920416c6c69616e63650a3239383920436f...
     * anqp_network_auth_type=010000
     * anqp_roaming_consortium=03506f9a05001bc504bd
     * anqp_ip_addr_type_availability=0c
     * anqp_nai_realm=0200300000246d61696c2e6578616d706c652e636f6d3b636973636f2...
     * anqp_3gpp=000600040132f465
     * anqp_domain_name=0b65786d61706c652e636f6d
     * hs20_operator_friendly_name=11656e6757692d466920416c6c69616e63650e636869...
     * hs20_wan_metrics=01c40900008001000000000a00
     * hs20_connection_capability=0100000006140001061600000650000106bb010106bb0...
     * hs20_osu_providers_list=0b5143412d4f53552d425353010901310015656e6757692d...
     */
    public String scanResult(String bssid) {
        return doStringCommand("BSS " + bssid);
    }

    /**
     * Format of command
     * DRIVER WLS_BATCHING SET SCANFREQ=x MSCAN=r BESTN=y CHANNEL=<z, w, t> RTT=s
     * where x is an ascii representation of an integer number of seconds between scans
     *       r is an ascii representation of an integer number of scans per batch
     *       y is an ascii representation of an integer number of the max AP to remember per scan
     *       z, w, t represent a 1..n size list of channel numbers and/or 'A', 'B' values
     *           indicating entire ranges of channels
     *       s is an ascii representation of an integer number of highest-strength AP
     *           for which we'd like approximate distance reported
     *
     * The return value is an ascii integer representing a guess of the number of scans
     * the firmware can remember before it runs out of buffer space or -1 on error
     */
    public String setBatchedScanSettings(BatchedScanSettings settings) {
        if (settings == null) {
            return doStringCommand("DRIVER WLS_BATCHING STOP");
        }
        String cmd = "DRIVER WLS_BATCHING SET SCANFREQ=" + settings.scanIntervalSec;
        cmd += " MSCAN=" + settings.maxScansPerBatch;
        if (settings.maxApPerScan != BatchedScanSettings.UNSPECIFIED) {
            cmd += " BESTN=" + settings.maxApPerScan;
        }
        if (settings.channelSet != null && !settings.channelSet.isEmpty()) {
            cmd += " CHANNEL=<";
            int i = 0;
            for (String channel : settings.channelSet) {
                cmd += (i > 0 ? "," : "") + channel;
                ++i;
            }
            cmd += ">";
        }
        if (settings.maxApForDistance != BatchedScanSettings.UNSPECIFIED) {
            cmd += " RTT=" + settings.maxApForDistance;
        }
        return doStringCommand(cmd);
    }

    public String getBatchedScanResults() {
        return doStringCommand("DRIVER WLS_BATCHING GET");
    }

    public boolean startDriver() {
        return doBooleanCommand("DRIVER START");
    }

    public boolean stopDriver() {
        return doBooleanCommand("DRIVER STOP");
    }


    /**
     * Start filtering out Multicast V4 packets
     * @return {@code true} if the operation succeeded, {@code false} otherwise
     *
     * Multicast filtering rules work as follows:
     *
     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
     * a power optimized mode (typically when screen goes off).
     *
     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
     *
     * DRIVER RXFILTER-ADD Num
     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
     *
     * and DRIVER RXFILTER-START
     * In order to stop the usage of these rules, we do
     *
     * DRIVER RXFILTER-STOP
     * DRIVER RXFILTER-REMOVE Num
     *   where Num is as described for RXFILTER-ADD
     *
     * The  SETSUSPENDOPT driver command overrides the filtering rules
     */
    public boolean startFilteringMulticastV4Packets() {
        return doBooleanCommand("DRIVER RXFILTER-STOP")
            && doBooleanCommand("DRIVER RXFILTER-REMOVE 2")
            && doBooleanCommand("DRIVER RXFILTER-START");
    }

    /**
     * Stop filtering out Multicast V4 packets.
     * @return {@code true} if the operation succeeded, {@code false} otherwise
     */
    public boolean stopFilteringMulticastV4Packets() {
        return doBooleanCommand("DRIVER RXFILTER-STOP")
            && doBooleanCommand("DRIVER RXFILTER-ADD 2")
            && doBooleanCommand("DRIVER RXFILTER-START");
    }

    /**
     * Start filtering out Multicast V6 packets
     * @return {@code true} if the operation succeeded, {@code false} otherwise
     */
    public boolean startFilteringMulticastV6Packets() {
        return doBooleanCommand("DRIVER RXFILTER-STOP")
            && doBooleanCommand("DRIVER RXFILTER-REMOVE 3")
            && doBooleanCommand("DRIVER RXFILTER-START");
    }

    /**
     * Stop filtering out Multicast V6 packets.
     * @return {@code true} if the operation succeeded, {@code false} otherwise
     */
    public boolean stopFilteringMulticastV6Packets() {
        return doBooleanCommand("DRIVER RXFILTER-STOP")
            && doBooleanCommand("DRIVER RXFILTER-ADD 3")
            && doBooleanCommand("DRIVER RXFILTER-START");
    }

    /**
     * Set the operational frequency band
     * @param band One of
     *     {@link WifiManager#WIFI_FREQUENCY_BAND_AUTO},
     *     {@link WifiManager#WIFI_FREQUENCY_BAND_5GHZ},
     *     {@link WifiManager#WIFI_FREQUENCY_BAND_2GHZ},
     * @return {@code true} if the operation succeeded, {@code false} otherwise
     */
    public boolean setBand(int band) {
        String bandstr;

        if (band == WifiManager.WIFI_FREQUENCY_BAND_5GHZ)
            bandstr = "5G";
        else if (band == WifiManager.WIFI_FREQUENCY_BAND_2GHZ)
            bandstr = "2G";
        else
            bandstr = "AUTO";
        return doBooleanCommand("SET SETBAND " + bandstr);
    }

    /**
      * Sets the bluetooth coexistence mode.
      *
      * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
      *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
      *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
      * @return Whether the mode was successfully set.
      */
    public boolean setBluetoothCoexistenceMode(int mode) {
        return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
    }

    /**
     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
     * some of the low-level scan parameters used by the driver are changed to
     * reduce interference with A2DP streaming.
     *
     * @param isSet whether to enable or disable this mode
     * @return {@code true} if the command succeeded, {@code false} otherwise.
     */
    public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
        if (setCoexScanMode) {
            return doBooleanCommand("DRIVER BTCOEXSCAN-START");
        } else {
            return doBooleanCommand("DRIVER BTCOEXSCAN-STOP");
        }
    }

    public void enableSaveConfig() {
        doBooleanCommand("SET update_config 1");
    }

    public boolean saveConfig() {
        return doBooleanCommand("SAVE_CONFIG");
    }

    public boolean addToBlacklist(String bssid) {
        if (TextUtils.isEmpty(bssid)) return false;
        return doBooleanCommand("BLACKLIST " + bssid);
    }

    public boolean clearBlacklist() {
        return doBooleanCommand("BLACKLIST clear");
    }

    public boolean setSuspendOptimizations(boolean enabled) {
       // if (mSuspendOptEnabled == enabled) return true;
        mSuspendOptEnabled = enabled;

        Log.e("native", "do suspend " + enabled);
        if (enabled) {
            return doBooleanCommand("DRIVER SETSUSPENDMODE 1");
        } else {
            return doBooleanCommand("DRIVER SETSUSPENDMODE 0");
        }
    }

    public boolean setCountryCode(String countryCode) {
        if (countryCode != null)
            return doBooleanCommand("DRIVER COUNTRY " + countryCode.toUpperCase(Locale.ROOT));
        else
            return doBooleanCommand("DRIVER COUNTRY");
    }

    //PNO Monitor
    private class PnoMonitor {
        private static final int MINIMUM_PNO_GAP = 5 * 1000;
        private static final String ACTION_TOGGLE_PNO =
            "com.android.server.Wifi.action.TOGGLE_PNO";
        long mLastPnoChangeTimeStamp = -1L;
        boolean mExpectedPnoState = false;
        boolean mCurrentPnoState = false;;
        boolean mWaitForTimer = false;
        final Object mPnoLock = new Object();
        private final AlarmManager mAlarmManager =
                (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        private final PendingIntent mPnoIntent;

        public PnoMonitor() {
            Intent intent = new Intent(ACTION_TOGGLE_PNO, null);
            intent.setPackage("android");
            mPnoIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);

            mContext.registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        synchronized(mPnoLock) {
                            if (DBG) Log.d(mTAG, "PNO timer expire, PNO should change to " +
                                    mExpectedPnoState);
                            if (mCurrentPnoState != mExpectedPnoState) {
                                if (DBG) Log.d(mTAG, "change PNO from " + mCurrentPnoState + " to "
                                        + mExpectedPnoState);
                                boolean ret = setPno(mExpectedPnoState);
                                if (!ret) {
                                    Log.e(mTAG, "set PNO failure");
                                }
                            } else {
                                if (DBG) Log.d(mTAG, "Do not change PNO since current is expected");
                            }
                            mWaitForTimer = false;
                        }
                    }
                },
                new IntentFilter(ACTION_TOGGLE_PNO));
        }

        private boolean setPno(boolean enable) {
            String cmd = enable ? "SET pno 1" : "SET pno 0";
            boolean ret = doBooleanCommand(cmd);
            mLastPnoChangeTimeStamp = System.currentTimeMillis();
            if (ret) {
                mCurrentPnoState = enable;
            }
            return ret;
        }

        public boolean enableBackgroundScan(boolean enable) {
            synchronized(mPnoLock) {
                if (mWaitForTimer) {
                    //already has a timer
                    mExpectedPnoState = enable;
                    if (DBG) Log.d(mTAG, "update expected PNO to " +  mExpectedPnoState);
                } else {
                    if (mCurrentPnoState == enable) {
                        return true;
                    }
                    long timeDifference = System.currentTimeMillis() - mLastPnoChangeTimeStamp;
                    if (timeDifference >= MINIMUM_PNO_GAP) {
                        return setPno(enable);
                    } else {
                        mExpectedPnoState = enable;
                        mWaitForTimer = true;
                        if (DBG) Log.d(mTAG, "start PNO timer with delay:" + timeDifference);
                        mAlarmManager.set(AlarmManager.RTC_WAKEUP,
                                System.currentTimeMillis() + timeDifference, mPnoIntent);
                    }
                }
                return true;
            }
        }
    }

    public boolean enableBackgroundScan(boolean enable) {
        if (mPnoMonitor != null) {
            return mPnoMonitor.enableBackgroundScan(enable);
        } else {
            return false;
        }
    }

    public void enableAutoConnect(boolean enable) {
        if (enable) {
            doBooleanCommand("STA_AUTOCONNECT 1");
        } else {
            doBooleanCommand("STA_AUTOCONNECT 0");
        }
    }

    public void setScanInterval(int scanInterval) {
        doBooleanCommand("SCAN_INTERVAL " + scanInterval);
    }

    public void setHs20(boolean hs20) {
        if (hs20) {
            doBooleanCommand("SET HS20 1");
        } else {
            doBooleanCommand("SET HS20 0");
        }
    }

    public void startTdls(String macAddr, boolean enable) {
        if (enable) {
            doBooleanCommand("TDLS_DISCOVER " + macAddr);
            doBooleanCommand("TDLS_SETUP " + macAddr);
        } else {
            doBooleanCommand("TDLS_TEARDOWN " + macAddr);
        }
    }

    /** Example output:
     * RSSI=-65
     * LINKSPEED=48
     * NOISE=9999
     * FREQUENCY=0
     */
    public String signalPoll() {
        return doStringCommandWithoutLogging("SIGNAL_POLL");
    }

    /** Example outout:
     * TXGOOD=396
     * TXBAD=1
     */
    public String pktcntPoll() {
        return doStringCommand("PKTCNT_POLL");
    }

    public void bssFlush() {
        doBooleanCommand("BSS_FLUSH 0");
    }

    public boolean startWpsPbc(String bssid) {
        if (TextUtils.isEmpty(bssid)) {
            return doBooleanCommand("WPS_PBC");
        } else {
            return doBooleanCommand("WPS_PBC " + bssid);
        }
    }

    public boolean startWpsPbc(String iface, String bssid) {
        synchronized (mLock) {
            if (TextUtils.isEmpty(bssid)) {
                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC");
            } else {
                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC " + bssid);
            }
        }
    }

    public boolean startWpsPinKeypad(String pin) {
        if (TextUtils.isEmpty(pin)) return false;
        return doBooleanCommand("WPS_PIN any " + pin);
    }

    public boolean startWpsPinKeypad(String iface, String pin) {
        if (TextUtils.isEmpty(pin)) return false;
        synchronized (mLock) {
            return doBooleanCommandNative("IFNAME=" + iface + " WPS_PIN any " + pin);
        }
    }


    public String startWpsPinDisplay(String bssid) {
        if (TextUtils.isEmpty(bssid)) {
            return doStringCommand("WPS_PIN any");
        } else {
            return doStringCommand("WPS_PIN " + bssid);
        }
    }

    public String startWpsPinDisplay(String iface, String bssid) {
        synchronized (mLock) {
            if (TextUtils.isEmpty(bssid)) {
                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN any");
            } else {
                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN " + bssid);
            }
        }
    }

    public boolean setExternalSim(boolean external) {
        synchronized (mLock) {
            String value = external ? "1" : "0";
            Log.d(TAG, "Setting external_sim to " + value);
            return doBooleanCommand("SET external_sim " + value);
        }
    }

    public boolean simAuthResponse(int id, String type, String response) {
        // with type = GSM-AUTH, UMTS-AUTH or UMTS-AUTS
        synchronized (mLock) {
            return doBooleanCommand("CTRL-RSP-SIM-" + id + ":" + type + response);
        }
    }

    public boolean simAuthFailedResponse(int id) {
        // should be used with type GSM-AUTH
        return doBooleanCommand("CTRL-RSP-SIM-" + id + ":GSM-FAIL");
    }

    public boolean umtsAuthFailedResponse(int id) {
        // should be used with type UMTS-AUTH
        return doBooleanCommand("CTRL-RSP-SIM-" + id + ":UMTS-FAIL");
    }

    public boolean simIdentityResponse(int id, String response) {
        synchronized (mLock) {
            return doBooleanCommand("CTRL-RSP-IDENTITY-" + id + ":" + response);
        }
    }

    /* Configures an access point connection */
    public boolean startWpsRegistrar(String bssid, String pin) {
        if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false;
        return doBooleanCommand("WPS_REG " + bssid + " " + pin);
    }

    public boolean cancelWps() {
        return doBooleanCommand("WPS_CANCEL");
    }

    public boolean setPersistentReconnect(boolean enabled) {
        int value = (enabled == true) ? 1 : 0;
        return doBooleanCommand("SET persistent_reconnect " + value);
    }

    public boolean setDeviceName(String name) {
        return doBooleanCommand("SET device_name " + name);
    }

    public boolean setDeviceType(String type) {
        return doBooleanCommand("SET device_type " + type);
    }

    public boolean setConfigMethods(String cfg) {
        return doBooleanCommand("SET config_methods " + cfg);
    }

    public boolean setManufacturer(String value) {
        return doBooleanCommand("SET manufacturer " + value);
    }

    public boolean setModelName(String value) {
        return doBooleanCommand("SET model_name " + value);
    }

    public boolean setModelNumber(String value) {
        return doBooleanCommand("SET model_number " + value);
    }

    public boolean setSerialNumber(String value) {
        return doBooleanCommand("SET serial_number " + value);
    }

    public boolean setP2pSsidPostfix(String postfix) {
        return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
    }

    public boolean setP2pGroupIdle(String iface, int time) {
        synchronized (mLock) {
            return doBooleanCommandNative("IFNAME=" + iface + " SET p2p_group_idle " + time);
        }
    }

    public void setPowerSave(boolean enabled) {
        if (enabled) {
            doBooleanCommand("SET ps 1");
        } else {
            doBooleanCommand("SET ps 0");
        }
    }

    public boolean setP2pPowerSave(String iface, boolean enabled) {
        synchronized (mLock) {
            if (enabled) {
                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 1");
            } else {
                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 0");
            }
        }
    }

    public boolean setWfdEnable(boolean enable) {
        return doBooleanCommand("SET wifi_display " + (enable ? "1" : "0"));
    }

    public boolean setWfdDeviceInfo(String hex) {
        return doBooleanCommand("WFD_SUBELEM_SET 0 " + hex);
    }

    /**
     * "sta" prioritizes STA connection over P2P and "p2p" prioritizes
     * P2P connection over STA
     */
    public boolean setConcurrencyPriority(String s) {
        return doBooleanCommand("P2P_SET conc_pref " + s);
    }

    public boolean p2pFind() {
        return doBooleanCommand("P2P_FIND");
    }

    public boolean p2pFind(int timeout) {
        if (timeout <= 0) {
            return p2pFind();
        }
        return doBooleanCommand("P2P_FIND " + timeout);
    }

    public boolean p2pStopFind() {
       return doBooleanCommand("P2P_STOP_FIND");
    }

    public boolean p2pListen() {
        return doBooleanCommand("P2P_LISTEN");
    }

    public boolean p2pListen(int timeout) {
        if (timeout <= 0) {
            return p2pListen();
        }
        return doBooleanCommand("P2P_LISTEN " + timeout);
    }

    public boolean p2pExtListen(boolean enable, int period, int interval) {
        if (enable && interval < period) {
            return false;
        }
        return doBooleanCommand("P2P_EXT_LISTEN"
                    + (enable ? (" " + period + " " + interval) : ""));
    }

    public boolean p2pSetChannel(int lc, int oc) {
        if (DBG) Log.d(mTAG, "p2pSetChannel: lc="+lc+", oc="+oc);

        if (lc >=1 && lc <= 11) {
            if (!doBooleanCommand("P2P_SET listen_channel " + lc)) {
                return false;
            }
        } else if (lc != 0) {
            return false;
        }

        if (oc >= 1 && oc <= 165 ) {
            int freq = (oc <= 14 ? 2407 : 5000) + oc * 5;
            return doBooleanCommand("P2P_SET disallow_freq 1000-"
                    + (freq - 5) + "," + (freq + 5) + "-6000");
        } else if (oc == 0) {
            /* oc==0 disables "P2P_SET disallow_freq" (enables all freqs) */
            return doBooleanCommand("P2P_SET disallow_freq \"\"");
        }

        return false;
    }

    public boolean p2pFlush() {
        return doBooleanCommand("P2P_FLUSH");
    }

    /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
        [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
    public String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
        if (config == null) return null;
        List<String> args = new ArrayList<String>();
        WpsInfo wps = config.wps;
        args.add(config.deviceAddress);

        switch (wps.setup) {
            case WpsInfo.PBC:
                args.add("pbc");
                break;
            case WpsInfo.DISPLAY:
                if (TextUtils.isEmpty(wps.pin)) {
                    args.add("pin");
                } else {
                    args.add(wps.pin);
                }
                args.add("display");
                break;
            case WpsInfo.KEYPAD:
                args.add(wps.pin);
                args.add("keypad");
                break;
            case WpsInfo.LABEL:
                args.add(wps.pin);
                args.add("label");
            default:
                break;
        }

        if (config.netId == WifiP2pGroup.PERSISTENT_NET_ID) {
            args.add("persistent");
        }

        if (joinExistingGroup) {
            args.add("join");
        } else {
            //TODO: This can be adapted based on device plugged in state and
            //device battery state
            int groupOwnerIntent = config.groupOwnerIntent;
            if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
                groupOwnerIntent = DEFAULT_GROUP_OWNER_INTENT;
            }
            args.add("go_intent=" + groupOwnerIntent);
        }

        String command = "P2P_CONNECT ";
        for (String s : args) command += s + " ";

        return doStringCommand(command);
    }

    public boolean p2pCancelConnect() {
        return doBooleanCommand("P2P_CANCEL");
    }

    public boolean p2pProvisionDiscovery(WifiP2pConfig config) {
        if (config == null) return false;

        switch (config.wps.setup) {
            case WpsInfo.PBC:
                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " pbc");
            case WpsInfo.DISPLAY:
                //We are doing display, so provision discovery is keypad
                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " keypad");
            case WpsInfo.KEYPAD:
                //We are doing keypad, so provision discovery is display
                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " display");
            default:
                break;
        }
        return false;
    }

    public boolean p2pGroupAdd(boolean persistent) {
        if (persistent) {
            return doBooleanCommand("P2P_GROUP_ADD persistent");
        }
        return doBooleanCommand("P2P_GROUP_ADD");
    }

    public boolean p2pGroupAdd(int netId) {
        return doBooleanCommand("P2P_GROUP_ADD persistent=" + netId);
    }

    public boolean p2pGroupRemove(String iface) {
        if (TextUtils.isEmpty(iface)) return false;
        synchronized (mLock) {
            return doBooleanCommandNative("IFNAME=" + iface + " P2P_GROUP_REMOVE " + iface);
        }
    }

    public boolean p2pReject(String deviceAddress) {
        return doBooleanCommand("P2P_REJECT " + deviceAddress);
    }

    /* Invite a peer to a group */
    public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
        if (TextUtils.isEmpty(deviceAddress)) return false;

        if (group == null) {
            return doBooleanCommand("P2P_INVITE peer=" + deviceAddress);
        } else {
            return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
                    + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
        }
    }

    /* Reinvoke a persistent connection */
    public boolean p2pReinvoke(int netId, String deviceAddress) {
        if (TextUtils.isEmpty(deviceAddress) || netId < 0) return false;

        return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
    }

    public String p2pGetSsid(String deviceAddress) {
        return p2pGetParam(deviceAddress, "oper_ssid");
    }

    public String p2pGetDeviceAddress() {

        Log.d(TAG, "p2pGetDeviceAddress");

        String status = null;

        /* Explicitly calling the API without IFNAME= prefix to take care of the devices that
        don't have p2p0 interface. Supplicant seems to be returning the correct address anyway. */

        synchronized (mLock) {
            status = doStringCommandNative("STATUS");
        }

        String result = "";
        if (status != null) {
            String[] tokens = status.split("\n");
            for (String token : tokens) {
                if (token.startsWith("p2p_device_address=")) {
                    String[] nameValue = token.split("=");
                    if (nameValue.length != 2)
                        break;
                    result = nameValue[1];
                }
            }
        }

        Log.d(TAG, "p2pGetDeviceAddress returning " + result);
        return result;
    }

    public int getGroupCapability(String deviceAddress) {
        int gc = 0;
        if (TextUtils.isEmpty(deviceAddress)) return gc;
        String peerInfo = p2pPeer(deviceAddress);
        if (TextUtils.isEmpty(peerInfo)) return gc;

        String[] tokens = peerInfo.split("\n");
        for (String token : tokens) {
            if (token.startsWith("group_capab=")) {
                String[] nameValue = token.split("=");
                if (nameValue.length != 2) break;
                try {
                    return Integer.decode(nameValue[1]);
                } catch(NumberFormatException e) {
                    return gc;
                }
            }
        }
        return gc;
    }

    public String p2pPeer(String deviceAddress) {
        return doStringCommand("P2P_PEER " + deviceAddress);
    }

    private String p2pGetParam(String deviceAddress, String key) {
        if (deviceAddress == null) return null;

        String peerInfo = p2pPeer(deviceAddress);
        if (peerInfo == null) return null;
        String[] tokens= peerInfo.split("\n");

        key += "=";
        for (String token : tokens) {
            if (token.startsWith(key)) {
                String[] nameValue = token.split("=");
                if (nameValue.length != 2) break;
                return nameValue[1];
            }
        }
        return null;
    }

    public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) {
        /*
         * P2P_SERVICE_ADD bonjour <query hexdump> <RDATA hexdump>
         * P2P_SERVICE_ADD upnp <version hex> <service>
         *
         * e.g)
         * [Bonjour]
         * # IP Printing over TCP (PTR) (RDATA=MyPrinter._ipp._tcp.local.)
         * P2P_SERVICE_ADD bonjour 045f697070c00c000c01 094d795072696e746572c027
         * # IP Printing over TCP (TXT) (RDATA=txtvers=1,pdl=application/postscript)
         * P2P_SERVICE_ADD bonjour 096d797072696e746572045f697070c00c001001
         *  09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074
         *
         * [UPnP]
         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012
         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice
         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp
         * -org:device:InternetGatewayDevice:1
         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9322-123456789012::urn:schemas-upnp
         * -org:service:ContentDirectory:2
         */
        for (String s : servInfo.getSupplicantQueryList()) {
            String command = "P2P_SERVICE_ADD";
            command += (" " + s);
            if (!doBooleanCommand(command)) {
                return false;
            }
        }
        return true;
    }

    public boolean p2pServiceDel(WifiP2pServiceInfo servInfo) {
        /*
         * P2P_SERVICE_DEL bonjour <query hexdump>
         * P2P_SERVICE_DEL upnp <version hex> <service>
         */
        for (String s : servInfo.getSupplicantQueryList()) {
            String command = "P2P_SERVICE_DEL ";

            String[] data = s.split(" ");
            if (data.length < 2) {
                return false;
            }
            if ("upnp".equals(data[0])) {
                command += s;
            } else if ("bonjour".equals(data[0])) {
                command += data[0];
                command += (" " + data[1]);
            } else {
                return false;
            }
            if (!doBooleanCommand(command)) {
                return false;
            }
        }
        return true;
    }

    public boolean p2pServiceFlush() {
        return doBooleanCommand("P2P_SERVICE_FLUSH");
    }

    public String p2pServDiscReq(String addr, String query) {
        String command = "P2P_SERV_DISC_REQ";
        command += (" " + addr);
        command += (" " + query);

        return doStringCommand(command);
    }

    public boolean p2pServDiscCancelReq(String id) {
        return doBooleanCommand("P2P_SERV_DISC_CANCEL_REQ " + id);
    }

    /* Set the current mode of miracast operation.
     *  0 = disabled
     *  1 = operating as source
     *  2 = operating as sink
     */
    public void setMiracastMode(int mode) {
        // Note: optional feature on the driver. It is ok for this to fail.
        doBooleanCommand("DRIVER MIRACAST " + mode);
    }

    public boolean fetchAnqp(String bssid, String subtypes) {
        return doBooleanCommand("ANQP_GET " + bssid + " " + subtypes);
    }

    /*
     * NFC-related calls
     */
    public String getNfcWpsConfigurationToken(int netId) {
        return doStringCommand("WPS_NFC_CONFIG_TOKEN WPS " + netId);
    }

    public String getNfcHandoverRequest() {
        return doStringCommand("NFC_GET_HANDOVER_REQ NDEF P2P-CR");
    }

    public String getNfcHandoverSelect() {
        return doStringCommand("NFC_GET_HANDOVER_SEL NDEF P2P-CR");
    }

    public boolean initiatorReportNfcHandover(String selectMessage) {
        return doBooleanCommand("NFC_REPORT_HANDOVER INIT P2P 00 " + selectMessage);
    }

    public boolean responderReportNfcHandover(String requestMessage) {
        return doBooleanCommand("NFC_REPORT_HANDOVER RESP P2P " + requestMessage + " 00");
    }

    /* WIFI HAL support */

    private static final String TAG = "WifiNative-HAL";
    private static long sWifiHalHandle = 0;             /* used by JNI to save wifi_handle */
    private static long[] sWifiIfaceHandles = null;     /* used by JNI to save interface handles */
    private static int sWlan0Index = -1;
    private static int sP2p0Index = -1;
    private static MonitorThread sThread;
    private static final int STOP_HAL_TIMEOUT_MS = 1000;

    private static native boolean startHalNative();
    private static native void stopHalNative();
    private static native void waitForHalEventNative();

    private static class MonitorThread extends Thread {
        public void run() {
            Log.i(TAG, "Waiting for HAL events mWifiHalHandle=" + Long.toString(sWifiHalHandle));
            waitForHalEventNative();
        }
    }

    synchronized public static boolean startHal() {

        String debugLog = "startHal stack: ";
        java.lang.StackTraceElement[] elements = Thread.currentThread().getStackTrace();
        for (int i = 2; i < elements.length && i <= 7; i++ ) {
            debugLog = debugLog + " - " + elements[i].getMethodName();
        }

        mLocalLog.log(debugLog);

        synchronized (mLock) {
            if (startHalNative() && (getInterfaces() != 0) && (sWlan0Index != -1)) {
                sThread = new MonitorThread();
                sThread.start();
                return true;
            } else {
                if (DBG) mLocalLog.log("Could not start hal");
                Log.e(TAG, "Could not start hal");
                return false;
            }
        }
    }

    synchronized public static void stopHal() {
        synchronized (mLock) {
            if (isHalStarted()) {
                stopHalNative();
                try {
                    sThread.join(STOP_HAL_TIMEOUT_MS);
                    Log.d(TAG, "HAL event thread stopped successfully");
                } catch (InterruptedException e) {
                    Log.e(TAG, "Could not stop HAL cleanly");
                }
                sThread = null;
                sWifiHalHandle = 0;
                sWifiIfaceHandles = null;
                sWlan0Index = -1;
                sP2p0Index = -1;
            }
        }
    }

    public static boolean isHalStarted() {
        return (sWifiHalHandle != 0);
    }
    private static native int getInterfacesNative();

    synchronized public static int getInterfaces() {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sWifiIfaceHandles == null) {
                    int num = getInterfacesNative();
                    int wifi_num = 0;
                    for (int i = 0; i < num; i++) {
                        String name = getInterfaceNameNative(i);
                        Log.i(TAG, "interface[" + i + "] = " + name);
                        if (name.equals("wlan0")) {
                            sWlan0Index = i;
                            wifi_num++;
                        } else if (name.equals("p2p0")) {
                            sP2p0Index = i;
                            wifi_num++;
                        }
                    }
                    return wifi_num;
                } else {
                    return sWifiIfaceHandles.length;
                }
            } else {
                return 0;
            }
        }
    }

    private static native String getInterfaceNameNative(int index);
    synchronized public static String getInterfaceName(int index) {
        return getInterfaceNameNative(index);
    }

    public static class ScanCapabilities {
        public int  max_scan_cache_size;                 // in number of scan results??
        public int  max_scan_buckets;
        public int  max_ap_cache_per_scan;
        public int  max_rssi_sample_size;
        public int  max_scan_reporting_threshold;        // in number of scan results??
        public int  max_hotlist_bssids;
        public int  max_significant_wifi_change_aps;
    }

    synchronized public static boolean getScanCapabilities(ScanCapabilities capabilities) {
        synchronized (mLock) {
            return isHalStarted() && getScanCapabilitiesNative(sWlan0Index, capabilities);
        }
    }

    private static native boolean getScanCapabilitiesNative(
            int iface, ScanCapabilities capabilities);

    private static native boolean startScanNative(int iface, int id, ScanSettings settings);
    private static native boolean stopScanNative(int iface, int id);
    private static native WifiScanner.ScanData[] getScanResultsNative(int iface, boolean flush);
    private static native WifiLinkLayerStats getWifiLinkLayerStatsNative(int iface);
    private static native void setWifiLinkLayerStatsNative(int iface, int enable);

    public static class ChannelSettings {
        int frequency;
        int dwell_time_ms;
        boolean passive;
    }

    public static class BucketSettings {
        int bucket;
        int band;
        int period_ms;
        int report_events;
        int num_channels;
        ChannelSettings channels[];
    }

    public static class ScanSettings {
        int base_period_ms;
        int max_ap_per_scan;
        int report_threshold_percent;
        int report_threshold_num_scans;
        int num_buckets;
        BucketSettings buckets[];
    }

    public static interface ScanEventHandler {
        void onScanResultsAvailable();
        void onFullScanResult(ScanResult fullScanResult);
        void onScanStatus();
        void onScanPaused(WifiScanner.ScanData[] data);
        void onScanRestarted();
    }

    synchronized static void onScanResultsAvailable(int id) {
        if (sScanEventHandler  != null) {
            sScanEventHandler.onScanResultsAvailable();
        }
    }

    /* scan status, keep these values in sync with gscan.h */
    private static int WIFI_SCAN_BUFFER_FULL = 0;
    private static int WIFI_SCAN_COMPLETE = 1;

    synchronized static void onScanStatus(int status) {
        if (status == WIFI_SCAN_BUFFER_FULL) {
            /* we have a separate event to take care of this */
        } else if (status == WIFI_SCAN_COMPLETE) {
            if (sScanEventHandler  != null) {
                sScanEventHandler.onScanStatus();
            }
        }
    }

    public static  WifiSsid createWifiSsid (byte[] rawSsid) {
        String ssidHexString = String.valueOf(HexEncoding.encode(rawSsid));

        if (ssidHexString == null) {
            return null;
        }

        WifiSsid wifiSsid = WifiSsid.createFromHex(ssidHexString);

        return wifiSsid;
    }

    public static String ssidConvert(byte[] rawSsid) {
        String ssid;

        CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
        try {
            CharBuffer decoded = decoder.decode(ByteBuffer.wrap(rawSsid));
            ssid = decoded.toString();
        } catch (CharacterCodingException cce) {
            ssid = null;
        }

        if (ssid == null) {
            ssid = new String(rawSsid, StandardCharsets.ISO_8859_1);
        }

        return ssid;
    }

    public static boolean setSsid(byte[] rawSsid, ScanResult result) {
        if (rawSsid == null || rawSsid.length == 0 || result == null) {
            return false;
        }

        result.SSID = ssidConvert(rawSsid);
        result.wifiSsid = createWifiSsid(rawSsid);
        return true;
    }

    static void populateScanResult(ScanResult result, byte bytes[], String dbg) {
        int num = 0;
        if (bytes == null) return;
        if (dbg == null) dbg = "";
        for (int i = 0; i < bytes.length - 1; ) {
            int type  = bytes[i] & 0xFF;
            int len = bytes[i + 1] & 0xFF;
            if (i + len + 2 > bytes.length) {
                Log.w(TAG, dbg + "bad length " + len + " of IE " + type + " from " + result.BSSID);
                Log.w(TAG, dbg + "ignoring the rest of the IEs");
                break;
            }
            num++;
            if (DBG) Log.i(TAG, dbg + "bytes[" + i + "] = [" + type + ", " + len + "]" + ", " +
                    "next = " + (i + len + 2));
            i += len + 2;
        }

        int secondChanelOffset = 0;
        byte channelMode = 0;
        int centerFreqIndex1 = 0;
        int centerFreqIndex2 = 0;

        boolean is80211McRTTResponder = false;

        ScanResult.InformationElement elements[] = new ScanResult.InformationElement[num];
        for (int i = 0, index = 0; i < num; i++) {
            int type  = bytes[index] & 0xFF;
            int len = bytes[index + 1] & 0xFF;
            if (DBG) Log.i(TAG, dbg + "index = " + index + ", type = " + type + ", len = " + len);
            ScanResult.InformationElement elem = new ScanResult.InformationElement();
            elem.id = type;
            elem.bytes = new byte[len];
            for (int j = 0; j < len; j++) {
                elem.bytes[j] = bytes[index + j + 2];
            }
            elements[i] = elem;
            int inforStart = index + 2;
            index += (len + 2);

            if(type == EID_HT_OPERATION) {
                secondChanelOffset = bytes[inforStart + 1] & 0x3;
            } else if(type == EID_VHT_OPERATION) {
                channelMode = bytes[inforStart];
                centerFreqIndex1 = bytes[inforStart + 1] & 0xFF;
                centerFreqIndex2 = bytes[inforStart + 2] & 0xFF;
            } else if (type == EID_EXTENDED_CAPS) {
                int tempIndex = RTT_RESP_ENABLE_BIT / 8;
                byte offset = RTT_RESP_ENABLE_BIT % 8;

                if(len < tempIndex + 1) {
                    is80211McRTTResponder = false;
                } else {
                    if ((bytes[inforStart + tempIndex] & ((byte)0x1 << offset)) != 0) {
                        is80211McRTTResponder = true;
                    } else {
                        is80211McRTTResponder = false;
                    }
                }
            }
        }

        if (is80211McRTTResponder) {
            result.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
        } else {
            result.clearFlag(ScanResult.FLAG_80211mc_RESPONDER);
        }

        //handle RTT related information
        if (channelMode != 0) {
            // 80 or 160 MHz
            result.channelWidth = channelMode + 1;

            //convert channel index to frequency in MHz, channel 36 is 5180MHz
            result.centerFreq0 = (centerFreqIndex1 - 36) * 5 + 5180;

            if(channelMode > 1) { //160MHz
                result.centerFreq1 = (centerFreqIndex2 - 36) * 5 + 5180;
            } else {
                result.centerFreq1 = 0;
            }
        } else {
            //20 or 40 MHz
            if (secondChanelOffset != 0) {//40MHz
                result.channelWidth = 1;
                if (secondChanelOffset == 1) {
                    result.centerFreq0 = result.frequency + 20;
                } else if (secondChanelOffset == 3) {
                    result.centerFreq0 = result.frequency - 20;
                } else {
                    result.centerFreq0 = 0;
                    Log.e(TAG, dbg + ": Error on secondChanelOffset");
                }
            } else {
                result.centerFreq0  = 0;
                result.centerFreq1  = 0;
            }
            result.centerFreq1  = 0;
        }
        if(DBG) {
            Log.d(TAG, dbg + "SSID: " + result.SSID + " ChannelWidth is: " + result.channelWidth +
                    " PrimaryFreq: " + result.frequency +" mCenterfreq0: " + result.centerFreq0 +
                    " mCenterfreq1: " + result.centerFreq1 + (is80211McRTTResponder ?
                    "Support RTT reponder: " : "Do not support RTT responder"));
        }

        result.informationElements = elements;
    }

    synchronized static void onFullScanResult(int id, ScanResult result, byte bytes[]) {
        if (DBG) Log.i(TAG, "Got a full scan results event, ssid = " + result.SSID + ", " +
                "num = " + bytes.length);

        if (sScanEventHandler == null) {
            return;
        }
        populateScanResult(result, bytes, " onFullScanResult ");

        sScanEventHandler.onFullScanResult(result);
    }

    private static int sScanCmdId = 0;
    private static ScanEventHandler sScanEventHandler;
    private static ScanSettings sScanSettings;

    synchronized public static boolean startScan(
            ScanSettings settings, ScanEventHandler eventHandler) {
        synchronized (mLock) {
            if (isHalStarted()) {

                if (sScanCmdId != 0) {
                    stopScan();
                } else if (sScanSettings != null || sScanEventHandler != null) {
                /* current scan is paused; no need to stop it */
                }

                sScanCmdId = getNewCmdIdLocked();

                sScanSettings = settings;
                sScanEventHandler = eventHandler;

                if (startScanNative(sWlan0Index, sScanCmdId, settings) == false) {
                    sScanEventHandler = null;
                    sScanSettings = null;
                    sScanCmdId = 0;
                    return false;
                }

                return true;
            } else {
                return false;
            }
        }
    }

    synchronized public static void stopScan() {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sScanCmdId != 0) {
                    stopScanNative(sWlan0Index, sScanCmdId);
                }
                sScanSettings = null;
                sScanEventHandler = null;
                sScanCmdId = 0;
            }
        }
    }

    synchronized public static void pauseScan() {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sScanCmdId != 0 && sScanSettings != null && sScanEventHandler != null) {
                    Log.d(TAG, "Pausing scan");
                    WifiScanner.ScanData scanData[] = getScanResultsNative(sWlan0Index, true);
                    stopScanNative(sWlan0Index, sScanCmdId);
                    sScanCmdId = 0;
                    sScanEventHandler.onScanPaused(scanData);
                }
            }
        }
    }

    synchronized public static void restartScan() {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sScanCmdId == 0 && sScanSettings != null && sScanEventHandler != null) {
                    Log.d(TAG, "Restarting scan");
                    ScanEventHandler handler = sScanEventHandler;
                    ScanSettings settings = sScanSettings;
                    if (startScan(sScanSettings, sScanEventHandler)) {
                        sScanEventHandler.onScanRestarted();
                    } else {
                    /* we are still paused; don't change state */
                        sScanEventHandler = handler;
                        sScanSettings = settings;
                    }
                }
            }
        }
    }

    synchronized public static WifiScanner.ScanData[] getScanResults(boolean flush) {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getScanResultsNative(sWlan0Index, flush);
            } else {
                return null;
            }
        }
    }

    public static interface HotlistEventHandler {
        void onHotlistApFound (ScanResult[] result);
        void onHotlistApLost  (ScanResult[] result);
    }

    private static int sHotlistCmdId = 0;
    private static HotlistEventHandler sHotlistEventHandler;

    private native static boolean setHotlistNative(int iface, int id,
            WifiScanner.HotlistSettings settings);
    private native static boolean resetHotlistNative(int iface, int id);

    synchronized public static boolean setHotlist(WifiScanner.HotlistSettings settings,
                                    HotlistEventHandler eventHandler) {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sHotlistCmdId != 0) {
                    return false;
                } else {
                    sHotlistCmdId = getNewCmdIdLocked();
                }

                sHotlistEventHandler = eventHandler;
                if (setHotlistNative(sWlan0Index, sHotlistCmdId, settings) == false) {
                    sHotlistEventHandler = null;
                    return false;
                }

                return true;
            } else {
                return false;
            }
        }
    }

    synchronized public static void resetHotlist() {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sHotlistCmdId != 0) {
                    resetHotlistNative(sWlan0Index, sHotlistCmdId);
                    sHotlistCmdId = 0;
                    sHotlistEventHandler = null;
                }
            }
        }
    }

    synchronized public static void onHotlistApFound(int id, ScanResult[] results) {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sHotlistCmdId != 0) {
                    sHotlistEventHandler.onHotlistApFound(results);
                } else {
                /* this can happen because of race conditions */
                    Log.d(TAG, "Ignoring hotlist AP found event");
                }
            }
        }
    }

    synchronized public static void onHotlistApLost(int id, ScanResult[] results) {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sHotlistCmdId != 0) {
                    sHotlistEventHandler.onHotlistApLost(results);
                } else {
                /* this can happen because of race conditions */
                    Log.d(TAG, "Ignoring hotlist AP lost event");
                }
            }
        }
    }

    public static interface SignificantWifiChangeEventHandler {
        void onChangesFound(ScanResult[] result);
    }

    private static SignificantWifiChangeEventHandler sSignificantWifiChangeHandler;
    private static int sSignificantWifiChangeCmdId;

    private static native boolean trackSignificantWifiChangeNative(
            int iface, int id, WifiScanner.WifiChangeSettings settings);
    private static native boolean untrackSignificantWifiChangeNative(int iface, int id);

    synchronized public static boolean trackSignificantWifiChange(
            WifiScanner.WifiChangeSettings settings, SignificantWifiChangeEventHandler handler) {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sSignificantWifiChangeCmdId != 0) {
                    return false;
                } else {
                    sSignificantWifiChangeCmdId = getNewCmdIdLocked();
                }

                sSignificantWifiChangeHandler = handler;
                if (trackSignificantWifiChangeNative(sWlan0Index, sScanCmdId, settings) == false) {
                    sSignificantWifiChangeHandler = null;
                    return false;
                }

                return true;
            } else {
                return false;
            }

        }
    }

    synchronized static void untrackSignificantWifiChange() {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sSignificantWifiChangeCmdId != 0) {
                    untrackSignificantWifiChangeNative(sWlan0Index, sSignificantWifiChangeCmdId);
                    sSignificantWifiChangeCmdId = 0;
                    sSignificantWifiChangeHandler = null;
                }
            }
        }
    }

    synchronized static void onSignificantWifiChange(int id, ScanResult[] results) {
        synchronized (mLock) {
            if (sSignificantWifiChangeCmdId != 0) {
                sSignificantWifiChangeHandler.onChangesFound(results);
            } else {
            /* this can happen because of race conditions */
                Log.d(TAG, "Ignoring significant wifi change");
            }
        }
    }

    synchronized public static WifiLinkLayerStats getWifiLinkLayerStats(String iface) {
        // TODO: use correct iface name to Index translation
        if (iface == null) return null;
        synchronized (mLock) {
            if (isHalStarted()) {
                return getWifiLinkLayerStatsNative(sWlan0Index);
            } else {
                return null;
            }
        }
    }

    synchronized public static void setWifiLinkLayerStats(String iface, int enable) {
        if (iface == null) return;
        synchronized (mLock) {
            if (isHalStarted()) {
                setWifiLinkLayerStatsNative(sWlan0Index, enable);
            }
        }
    }

    public static native int getSupportedFeatureSetNative(int iface);
    synchronized public static int getSupportedFeatureSet() {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getSupportedFeatureSetNative(sWlan0Index);
            } else {
                Log.d(TAG, "Failing getSupportedFeatureset because HAL isn't started");
                return 0;
            }
        }
    }

    /* Rtt related commands/events */
    public static interface RttEventHandler {
        void onRttResults(RttManager.RttResult[] result);
    }

    private static RttEventHandler sRttEventHandler;
    private static int sRttCmdId;

    synchronized private static void onRttResults(int id, RttManager.RttResult[] results) {
        if (id == sRttCmdId) {
            Log.d(TAG, "Received " + results.length + " rtt results");
            sRttEventHandler.onRttResults(results);
            sRttCmdId = 0;
        } else {
            Log.d(TAG, "RTT Received event for unknown cmd = " + id + ", current id = " + sRttCmdId);
        }
    }

    private static native boolean requestRangeNative(
            int iface, int id, RttManager.RttParams[] params);
    private static native boolean cancelRangeRequestNative(
            int iface, int id, RttManager.RttParams[] params);

    synchronized public static boolean requestRtt(
            RttManager.RttParams[] params, RttEventHandler handler) {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sRttCmdId != 0) {
                    Log.v("TAG", "Last one is still under measurement!");
                    return false;
                } else {
                    sRttCmdId = getNewCmdIdLocked();
                }
                sRttEventHandler = handler;
                Log.v(TAG, "native issue RTT request");
                return requestRangeNative(sWlan0Index, sRttCmdId, params);
            } else {
                return false;
            }
        }
    }

    synchronized public static boolean cancelRtt(RttManager.RttParams[] params) {
        synchronized(mLock) {
            if (isHalStarted()) {
                if (sRttCmdId == 0) {
                    return false;
                }

                sRttCmdId = 0;

                if (cancelRangeRequestNative(sWlan0Index, sRttCmdId, params)) {
                    sRttEventHandler = null;
                    Log.v(TAG, "RTT cancel Request Successfully");
                    return true;
                } else {
                    Log.e(TAG, "RTT cancel Request failed");
                    return false;
                }
            } else {
                return false;
            }
        }
    }

    private static native boolean setScanningMacOuiNative(int iface, byte[] oui);

    synchronized public static boolean setScanningMacOui(byte[] oui) {
        synchronized (mLock) {
            if (isHalStarted()) {
                return setScanningMacOuiNative(sWlan0Index, oui);
            } else {
                return false;
            }
        }
    }

    private static native int[] getChannelsForBandNative(
            int iface, int band);

    synchronized public static int [] getChannelsForBand(int band) {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getChannelsForBandNative(sWlan0Index, band);
	    } else {
                return null;
            }
        }
    }

    private static native boolean isGetChannelsForBandSupportedNative();
    synchronized public static boolean isGetChannelsForBandSupported(){
        synchronized (mLock) {
            if (isHalStarted()) {
                return isGetChannelsForBandSupportedNative();
	    } else {
                return false;
            }
        }
    }

    private static native boolean setDfsFlagNative(int iface, boolean dfsOn);
    synchronized public static boolean setDfsFlag(boolean dfsOn) {
        synchronized (mLock) {
            if (isHalStarted()) {
                return setDfsFlagNative(sWlan0Index, dfsOn);
            } else {
                return false;
            }
        }
    }

    private static native boolean toggleInterfaceNative(int on);
    synchronized public static boolean toggleInterface(int on) {
        synchronized (mLock) {
            if (isHalStarted()) {
                return toggleInterfaceNative(0);
            } else {
                return false;
            }
        }
    }

    private static native RttManager.RttCapabilities getRttCapabilitiesNative(int iface);
    synchronized public static RttManager.RttCapabilities getRttCapabilities() {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getRttCapabilitiesNative(sWlan0Index);
            }else {
                return null;
            }
        }
    }

    private static native boolean setCountryCodeHalNative(int iface, String CountryCode);
    synchronized public static boolean setCountryCodeHal( String CountryCode) {
        synchronized (mLock) {
            if (isHalStarted()) {
                return setCountryCodeHalNative(sWlan0Index, CountryCode);
            } else {
                return false;
            }
        }
    }

    /* Rtt related commands/events */
    public abstract class TdlsEventHandler {
        abstract public void onTdlsStatus(String macAddr, int status, int reason);
    }

    private static TdlsEventHandler sTdlsEventHandler;

    private static native boolean enableDisableTdlsNative(int iface, boolean enable,
            String macAddr);
    synchronized public static boolean enableDisableTdls(boolean enable, String macAdd,
            TdlsEventHandler tdlsCallBack) {
        synchronized (mLock) {
            sTdlsEventHandler = tdlsCallBack;
            return enableDisableTdlsNative(sWlan0Index, enable, macAdd);
        }
    }

    // Once TDLS per mac and event feature is implemented, this class definition should be
    // moved to the right place, like WifiManager etc
    public static class TdlsStatus {
        int channel;
        int global_operating_class;
        int state;
        int reason;
    }
    private static native TdlsStatus getTdlsStatusNative(int iface, String macAddr);
    synchronized public static TdlsStatus getTdlsStatus (String macAdd) {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getTdlsStatusNative(sWlan0Index, macAdd);
            } else {
                return null;
            }
        }
    }

    //ToFix: Once TDLS per mac and event feature is implemented, this class definition should be
    // moved to the right place, like WifiStateMachine etc
    public static class TdlsCapabilities {
        /* Maximum TDLS session number can be supported by the Firmware and hardware */
        int maxConcurrentTdlsSessionNumber;
        boolean isGlobalTdlsSupported;
        boolean isPerMacTdlsSupported;
        boolean isOffChannelTdlsSupported;
    }



    private static native TdlsCapabilities getTdlsCapabilitiesNative(int iface);
    synchronized public static TdlsCapabilities getTdlsCapabilities () {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getTdlsCapabilitiesNative(sWlan0Index);
            } else {
                return null;
            }
        }
    }

    synchronized private static boolean onTdlsStatus(String macAddr, int status, int reason) {
         if (sTdlsEventHandler == null) {
             return false;
         } else {
             sTdlsEventHandler.onTdlsStatus(macAddr, status, reason);
             return true;
         }
    }

    //---------------------------------------------------------------------------------

    /* Wifi Logger commands/events */

    public static native boolean startLogging(int iface);

    public static interface WifiLoggerEventHandler {
        void onRingBufferData(RingBufferStatus status, byte[] buffer);
        void onWifiAlert(int errorCode, byte[] buffer);
    }

    private static WifiLoggerEventHandler sWifiLoggerEventHandler = null;

    private static void onRingBufferData(RingBufferStatus status, byte[] buffer) {
        if (sWifiLoggerEventHandler != null)
            sWifiLoggerEventHandler.onRingBufferData(status, buffer);
    }

    private static void onWifiAlert(byte[] buffer, int errorCode) {
        if (sWifiLoggerEventHandler != null)
            sWifiLoggerEventHandler.onWifiAlert(errorCode, buffer);
    }

    private static int sLogCmdId = -1;
    private static native boolean setLoggingEventHandlerNative(int iface, int id);
    synchronized public static boolean setLoggingEventHandler(WifiLoggerEventHandler handler) {
        synchronized (mLock) {
            if (isHalStarted()) {
                int oldId =  sLogCmdId;
                sLogCmdId = getNewCmdIdLocked();
                if (!setLoggingEventHandlerNative(sWlan0Index, sLogCmdId)) {
                    sLogCmdId = oldId;
                    return false;
                }
                sWifiLoggerEventHandler = handler;
                return true;
            } else {
                return false;
            }
        }
    }

    private static native boolean startLoggingRingBufferNative(int iface, int verboseLevel,
            int flags, int minIntervalSec ,int minDataSize, String ringName);
    synchronized public static boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval,
            int minDataSize, String ringName){
        synchronized (mLock) {
            if (isHalStarted()) {
                return startLoggingRingBufferNative(sWlan0Index, verboseLevel, flags, maxInterval,
                        minDataSize, ringName);
            } else {
                return false;
            }
        }
    }

    private static native int getSupportedLoggerFeatureSetNative(int iface);
    synchronized public static int getSupportedLoggerFeatureSet() {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getSupportedLoggerFeatureSetNative(sWlan0Index);
            } else {
                return 0;
            }
        }
    }

    private static native boolean resetLogHandlerNative(int iface, int id);
    synchronized public static boolean resetLogHandler() {
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sLogCmdId == -1) {
                    Log.e(TAG,"Can not reset handler Before set any handler");
                    return false;
                }
                sWifiLoggerEventHandler = null;
                if (resetLogHandlerNative(sWlan0Index, sLogCmdId)) {
                    sLogCmdId = -1;
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
    }

    private static native String getDriverVersionNative(int iface);
    synchronized public static String getDriverVersion() {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getDriverVersionNative(sWlan0Index);
            } else {
                return "";
            }
        }
    }


    private static native String getFirmwareVersionNative(int iface);
    synchronized public static String getFirmwareVersion() {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getFirmwareVersionNative(sWlan0Index);
            } else {
                return "";
            }
        }
    }

    public static class RingBufferStatus{
        String name;
        int flag;
        int ringBufferId;
        int ringBufferByteSize;
        int verboseLevel;
        int writtenBytes;
        int readBytes;
        int writtenRecords;

        @Override
        public String toString() {
            return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
                    " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel +
                    " writtenBytes: " + writtenBytes + " readBytes: " + readBytes +
                    " writtenRecords: " + writtenRecords;
        }
    }

    private static native RingBufferStatus[] getRingBufferStatusNative(int iface);
    synchronized public static RingBufferStatus[] getRingBufferStatus() {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getRingBufferStatusNative(sWlan0Index);
            } else {
                return null;
            }
        }
    }

    private static native boolean getRingBufferDataNative(int iface, String ringName);
    synchronized public static boolean getRingBufferData(String ringName) {
        synchronized (mLock) {
            if (isHalStarted()) {
                return getRingBufferDataNative(sWlan0Index, ringName);
            } else {
                return false;
            }
        }
    }

    static private byte[] mFwMemoryDump;
    private static void onWifiFwMemoryAvailable(byte[] buffer) {
        mFwMemoryDump = buffer;
        if (DBG) {
            Log.d(TAG, "onWifiFwMemoryAvailable is called and buffer length is: " +
                    (buffer == null ? 0 :  buffer.length));
        }
    }

    private static native boolean getFwMemoryDumpNative(int iface);
    synchronized public static byte[] getFwMemoryDump() {
        synchronized (mLock) {
            if (isHalStarted()) {
                if(getFwMemoryDumpNative(sWlan0Index)) {
                    byte[] fwMemoryDump = mFwMemoryDump;
                    mFwMemoryDump = null;
                    return fwMemoryDump;
                } else {
                    return null;
                }
            }

            return null;
        }
    }

    //---------------------------------------------------------------------------------
    /* Configure ePNO */

    public class WifiPnoNetwork {
        String SSID;
        int rssi_threshold;
        int flags;
        int auth;
        String configKey; // kept for reference

        WifiPnoNetwork(WifiConfiguration config, int threshold) {
            if (config.SSID == null) {
                this.SSID = "";
                this.flags = 1;
            } else {
                this.SSID = config.SSID;
            }
            this.rssi_threshold = threshold;
            if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
                auth |= 2;
            } else if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP) ||
                    config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) {
                auth |= 4;
            } else if (config.wepKeys[0] != null) {
                auth |= 1;
            } else {
                auth |= 1;
            }
//            auth = 0;
            flags |= 6; //A and G
            configKey = config.configKey();
        }

        @Override
        public String toString() {
            StringBuilder sbuf = new StringBuilder();
            sbuf.append(this.SSID);
            sbuf.append(" flags=").append(this.flags);
            sbuf.append(" rssi=").append(this.rssi_threshold);
            sbuf.append(" auth=").append(this.auth);
            return sbuf.toString();
        }
    }

    public static interface WifiPnoEventHandler {
        void onPnoNetworkFound(ScanResult results[]);
    }

    private static WifiPnoEventHandler sWifiPnoEventHandler;

    private static int sPnoCmdId = 0;

    private native static boolean setPnoListNative(int iface, int id, WifiPnoNetwork list[]);

    synchronized public static boolean setPnoList(WifiPnoNetwork list[],
                                                  WifiPnoEventHandler eventHandler) {
        Log.e(TAG, "setPnoList cmd " + sPnoCmdId);

        synchronized (mLock) {
            if (isHalStarted()) {

                sPnoCmdId = getNewCmdIdLocked();

                sWifiPnoEventHandler = eventHandler;
                if (setPnoListNative(sWlan0Index, sPnoCmdId, list)) {
                    return true;
                }
            }

            sWifiPnoEventHandler = null;
            return false;
        }
    }

    synchronized public static void onPnoNetworkFound(int id, ScanResult[] results) {

        if (results == null) {
            Log.e(TAG, "onPnoNetworkFound null results");
            return;

        }
        Log.d(TAG, "WifiNative.onPnoNetworkFound result " + results.length);

        //Log.e(TAG, "onPnoNetworkFound length " + results.length);
        //return;
        for (int i=0; i<results.length; i++) {
            Log.e(TAG, "onPnoNetworkFound SSID " + results[i].SSID
                    + " " + results[i].level + " " + results[i].frequency);

            populateScanResult(results[i], results[i].bytes, "onPnoNetworkFound ");
            results[i].wifiSsid = WifiSsid.createFromAsciiEncoded(results[i].SSID);
        }
        synchronized (mLock) {
            if (sPnoCmdId != 0 && sWifiPnoEventHandler != null) {
                sWifiPnoEventHandler.onPnoNetworkFound(results);
            } else {
                /* this can happen because of race conditions */
                Log.d(TAG, "Ignoring Pno Network found event");
            }
        }
    }

    public class WifiLazyRoamParams {
        int A_band_boost_threshold;
        int A_band_penalty_threshold;
        int A_band_boost_factor;
        int A_band_penalty_factor;
        int A_band_max_boost;
        int lazy_roam_hysteresis;
        int alert_roam_rssi_trigger;

        WifiLazyRoamParams() {
        }

        @Override
        public String toString() {
            StringBuilder sbuf = new StringBuilder();
            sbuf.append(" A_band_boost_threshold=").append(this.A_band_boost_threshold);
            sbuf.append(" A_band_penalty_threshold=").append(this.A_band_penalty_threshold);
            sbuf.append(" A_band_boost_factor=").append(this.A_band_boost_factor);
            sbuf.append(" A_band_penalty_factor=").append(this.A_band_penalty_factor);
            sbuf.append(" A_band_max_boost=").append(this.A_band_max_boost);
            sbuf.append(" lazy_roam_hysteresis=").append(this.lazy_roam_hysteresis);
            sbuf.append(" alert_roam_rssi_trigger=").append(this.alert_roam_rssi_trigger);
            return sbuf.toString();
        }
    }

    private native static boolean setLazyRoamNative(int iface, int id,
                                              boolean enabled, WifiLazyRoamParams param);

    synchronized public static boolean setLazyRoam(boolean enabled, WifiLazyRoamParams params) {
        synchronized (mLock) {
            if (isHalStarted()) {
                sPnoCmdId = getNewCmdIdLocked();
                return setLazyRoamNative(sWlan0Index, sPnoCmdId, enabled, params);
            } else {
                return false;
            }
        }
    }

    private native static boolean setBssidBlacklistNative(int iface, int id,
                                              String list[]);

    synchronized public static boolean setBssidBlacklist(String list[]) {
        int size = 0;
        if (list != null) {
            size = list.length;
        }
        Log.e(TAG, "setBssidBlacklist cmd " + sPnoCmdId + " size " + size);

        synchronized (mLock) {
            if (isHalStarted()) {
                sPnoCmdId = getNewCmdIdLocked();
                return setBssidBlacklistNative(sWlan0Index, sPnoCmdId, list);
            } else {
                return false;
            }
        }
    }

    private native static boolean setSsidWhitelistNative(int iface, int id, String list[]);

    synchronized public static boolean setSsidWhitelist(String list[]) {
        int size = 0;
        if (list != null) {
            size = list.length;
        }
        Log.e(TAG, "setSsidWhitelist cmd " + sPnoCmdId + " size " + size);

        synchronized (mLock) {
            if (isHalStarted()) {
                sPnoCmdId = getNewCmdIdLocked();

                return setSsidWhitelistNative(sWlan0Index, sPnoCmdId, list);
            } else {
                return false;
            }
        }
    }

    private native static int startSendingOffloadedPacketNative(int iface, int idx,
                                    byte[] srcMac, byte[] dstMac, byte[] pktData, int period);

    synchronized public int
    startSendingOffloadedPacket(int slot, KeepalivePacketData keepAlivePacket, int period) {
        Log.d(TAG, "startSendingOffloadedPacket slot=" + slot + " period=" + period);

        String[] macAddrStr = getMacAddress().split(":");
        byte[] srcMac = new byte[6];
        for(int i = 0; i < 6; i++) {
            Integer hexVal = Integer.parseInt(macAddrStr[i], 16);
            srcMac[i] = hexVal.byteValue();
        }
        synchronized (mLock) {
            if (isHalStarted()) {
                return startSendingOffloadedPacketNative(sWlan0Index, slot, srcMac,
                                keepAlivePacket.dstMac, keepAlivePacket.data, period);
            } else {
                return -1;
            }
        }
    }

    private native static int stopSendingOffloadedPacketNative(int iface, int idx);

    synchronized public int
    stopSendingOffloadedPacket(int slot) {
        Log.d(TAG, "stopSendingOffloadedPacket " + slot);
        synchronized (mLock) {
            if (isHalStarted()) {
                return stopSendingOffloadedPacketNative(sWlan0Index, slot);
            } else {
                return -1;
            }
        }
    }

    public static interface WifiRssiEventHandler {
        void onRssiThresholdBreached(byte curRssi);
    }

    private static WifiRssiEventHandler sWifiRssiEventHandler;

    synchronized static void onRssiThresholdBreached(int id, byte curRssi) {
        sWifiRssiEventHandler.onRssiThresholdBreached(curRssi);
    }

    private native static int startRssiMonitoringNative(int iface, int id,
                                        byte maxRssi, byte minRssi);

    private static int sRssiMonitorCmdId = 0;

    synchronized public int startRssiMonitoring(byte maxRssi, byte minRssi,
                                                WifiRssiEventHandler rssiEventHandler) {
        Log.d(TAG, "startRssiMonitoring: maxRssi=" + maxRssi + " minRssi=" + minRssi);
        sWifiRssiEventHandler = rssiEventHandler;
        synchronized (mLock) {
            if (isHalStarted()) {
                if (sRssiMonitorCmdId != 0) {
                    stopRssiMonitoring();
                }

                sRssiMonitorCmdId = getNewCmdIdLocked();
                Log.d(TAG, "sRssiMonitorCmdId = " + sRssiMonitorCmdId);
                int ret = startRssiMonitoringNative(sWlan0Index, sRssiMonitorCmdId,
                        maxRssi, minRssi);
                if (ret != 0) { // if not success
                    sRssiMonitorCmdId = 0;
                }
                return ret;
            } else {
                return -1;
            }
        }
    }

    private native static int stopRssiMonitoringNative(int iface, int idx);

    synchronized public int stopRssiMonitoring() {
        Log.d(TAG, "stopRssiMonitoring, cmdId " + sRssiMonitorCmdId);
        synchronized (mLock) {
            if (isHalStarted()) {
                int ret = 0;
                if (sRssiMonitorCmdId != 0) {
                    ret = stopRssiMonitoringNative(sWlan0Index, sRssiMonitorCmdId);
                }
                sRssiMonitorCmdId = 0;
                return ret;
            } else {
                return -1;
            }
        }
    }
}
