FileDocCategorySizeDatePackage
WifiNative.javaAPI DocAndroid 5.1 API54261Thu Mar 12 22:22:52 GMT 2015com.android.server.wifi

WifiNative

public class WifiNative extends Object
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}

Fields Summary
private static boolean
DBG
private final String
mTAG
private static final int
DEFAULT_GROUP_OWNER_INTENT
static final int
BLUETOOTH_COEXISTENCE_MODE_ENABLED
static final int
BLUETOOTH_COEXISTENCE_MODE_DISABLED
static final int
BLUETOOTH_COEXISTENCE_MODE_SENSE
static final int
SCAN_WITHOUT_CONNECTION_SETUP
static final int
SCAN_WITH_CONNECTION_SETUP
static final Object
mLock
public final String
mInterfaceName
public final String
mInterfacePrefix
private boolean
mSuspendOptEnabled
private static final android.util.LocalLog
mLocalLog
private static int
sCmdId
private static final String
TAG
private static long
sWifiHalHandle
private static long[]
sWifiIfaceHandles
private static int
sWlan0Index
private static int
sP2p0Index
private static boolean
sHalIsStarted
private static boolean
sHalFailed
private static int
WIFI_SCAN_BUFFER_FULL
private static int
WIFI_SCAN_COMPLETE
private static int
sScanCmdId
private static ScanEventHandler
sScanEventHandler
private static ScanSettings
sScanSettings
private static int
sHotlistCmdId
private static HotlistEventHandler
sHotlistEventHandler
private static SignificantWifiChangeEventHandler
sSignificantWifiChangeHandler
private static int
sSignificantWifiChangeCmdId
private static RttEventHandler
sRttEventHandler
private static int
sRttCmdId
Constructors Summary
public WifiNative(String interfaceName)


    /* Register native functions */

     
        /* Native functions are defined in libwifi-service.so */
        System.loadLibrary("wifi-service");
        registerNatives();
    
        mInterfaceName = interfaceName;
        mTAG = "WifiNative-" + interfaceName;
        if (!interfaceName.equals("p2p0")) {
            mInterfacePrefix = "IFNAME=" + interfaceName + " ";
        } else {
            // commands for p2p0 interface don't need prefix
            mInterfacePrefix = "";
        }
    
Methods Summary
public intaddNetwork()

        return doIntCommand("ADD_NETWORK");
    
public booleanaddToBlacklist(java.lang.String bssid)

        if (TextUtils.isEmpty(bssid)) return false;
        return doBooleanCommand("BLACKLIST " + bssid);
    
public voidbssFlush()

        doBooleanCommand("BSS_FLUSH 0");
    
private static native booleancancelRangeRequestNative(int iface, int id, RttManager.RttParams[] params)

public static synchronized booleancancelRtt(RttManager.RttParams[] params)

        synchronized(mLock) {
            if (sRttCmdId == 0) {
                return false;
            }

            if (cancelRangeRequestNative(sWlan0Index, sRttCmdId, params)) {
                sRttEventHandler = null;
                return true;
            } else {
                return false;
            }
        }
    
public booleancancelWps()

        return doBooleanCommand("WPS_CANCEL");
    
public booleanclearBlacklist()

        return doBooleanCommand("BLACKLIST clear");
    
public voidcloseSupplicantConnection()

        localLog(mInterfacePrefix + "closeSupplicantConnection");
        closeSupplicantConnectionNative();
    
private native voidcloseSupplicantConnectionNative()

public booleanconnectToSupplicant()

        // No synchronization necessary .. it is implemented in WifiMonitor
        localLog(mInterfacePrefix + "connectToSupplicant");
        return connectToSupplicantNative();
    
private native booleanconnectToSupplicantNative()

public booleandisableNetwork(int netId)

        if (DBG) logDbg("disableNetwork nid=" + Integer.toString(netId));
        return doBooleanCommand("DISABLE_NETWORK " + netId);
    
public booleandisconnect()

        if (DBG) logDbg("DISCONNECT ");
        return doBooleanCommand("DISCONNECT");
    
private booleandoBooleanCommand(java.lang.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 native booleandoBooleanCommandNative(java.lang.String command)

private intdoIntCommand(java.lang.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 native intdoIntCommandNative(java.lang.String command)

private java.lang.StringdoStringCommand(java.lang.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 native java.lang.StringdoStringCommandNative(java.lang.String command)

private java.lang.StringdoStringCommandWithoutLogging(java.lang.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 voidenableAutoConnect(boolean enable)

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

        if (enable) {
            doBooleanCommand("SET pno 1");
        } else {
            doBooleanCommand("SET pno 0");
        }
    
public booleanenableNetwork(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 voidenableSaveConfig()

        doBooleanCommand("SET update_config 1");
    
voidenableVerboseLogging(int verbose)

        if (verbose > 0) {
            DBG = true;
        } else {
            DBG = false;
        }
    
public booleanfetchAnqp(java.lang.String bssid, java.lang.String subtypes)

        return doBooleanCommand("ANQP_GET " + bssid + " " + subtypes);
    
public intgetBand()

       String ret = doStringCommand("DRIVER GETBAND");
        if (!TextUtils.isEmpty(ret)) {
            //reply is "BAND X" where X is the band
            String[] tokens = ret.split(" ");
            try {
                if (tokens.length == 2) return Integer.parseInt(tokens[1]);
            } catch (NumberFormatException e) {
                return -1;
            }
        }
        return -1;
    
public java.lang.StringgetBatchedScanResults()

        return doStringCommand("DRIVER WLS_BATCHING GET");
    
public static synchronized int[]getChannelsForBand(int band)

        synchronized (mLock) {
            if (startHal()) {
                return getChannelsForBandNative(sWlan0Index, band);
            } else {
                return null;
            }
        }
    
private static native int[]getChannelsForBandNative(int iface, int band)

public java.lang.StringgetFreqCapability()

        return doStringCommand("GET_CAPABILITY freq");
    
public intgetGroupCapability(java.lang.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 static synchronized java.lang.StringgetInterfaceName(int index)

        return getInterfaceNameNative(index);
    
private static native java.lang.StringgetInterfaceNameNative(int index)

public static synchronized intgetInterfaces()

        synchronized (mLock) {
            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;
            }
        }
    
private static native intgetInterfacesNative()

public android.util.LocalLoggetLocalLog()


       
        return mLocalLog;
    
public java.lang.StringgetMacAddress()

        //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;
    
public java.lang.StringgetNetworkVariable(int netId, java.lang.String name)

        if (TextUtils.isEmpty(name)) return null;

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

        return sCmdId++;
    
public java.lang.StringgetNfcHandoverRequest()

        return doStringCommand("NFC_GET_HANDOVER_REQ NDEF P2P-CR");
    
public java.lang.StringgetNfcHandoverSelect()

        return doStringCommand("NFC_GET_HANDOVER_SEL NDEF P2P-CR");
    
public java.lang.StringgetNfcWpsConfigurationToken(int netId)

        return doStringCommand("WPS_NFC_CONFIG_TOKEN WPS " + netId);
    
public static booleangetScanCapabilities(com.android.server.wifi.WifiNative$ScanCapabilities capabilities)

        return getScanCapabilitiesNative(sWlan0Index, capabilities);
    
private static native booleangetScanCapabilitiesNative(int iface, com.android.server.wifi.WifiNative$ScanCapabilities capabilities)

public static synchronized android.net.wifi.ScanResult[]getScanResults()

        synchronized (mLock) {
            return getScanResultsNative(sWlan0Index, /* flush = */ false);
        }
    
private static native android.net.wifi.ScanResult[]getScanResultsNative(int iface, boolean flush)

public static synchronized intgetSupportedFeatureSet()

        return getSupportedFeatureSetNative(sWlan0Index);
    
public static native intgetSupportedFeatureSetNative(int iface)

public static synchronized android.net.wifi.WifiLinkLayerStatsgetWifiLinkLayerStats(java.lang.String iface)

        // TODO: use correct iface name to Index translation
        if (iface == null) return null;
        synchronized (mLock) {
            if (!sHalIsStarted)
                startHal();
            if (sHalIsStarted)
                return getWifiLinkLayerStatsNative(sWlan0Index);
        }
        return null;
    
private static native android.net.wifi.WifiLinkLayerStatsgetWifiLinkLayerStatsNative(int iface)

public booleaninitiatorReportNfcHandover(java.lang.String selectMessage)

        return doBooleanCommand("NFC_REPORT_HANDOVER INIT P2P 00 " + selectMessage);
    
public static native booleanisDriverLoaded()

public static native booleankillSupplicant(boolean p2pSupported)

public java.lang.StringlistNetworks()

        return doStringCommand("LIST_NETWORKS");
    
public java.lang.StringlistNetworks(int last_id)

        return doStringCommand("LIST_NETWORKS LAST_ID=" + last_id);
    
public static native booleanloadDriver()

private voidlocalLog(java.lang.String s)

        if (mLocalLog != null)
            mLocalLog.log(mInterfaceName + ": " + s);
    
private voidlogDbg(java.lang.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());

    
static synchronized voidonFullScanResult(int id, android.net.wifi.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;
        }

        int num = 0;
        for (int i = 0; i < bytes.length; ) {
            int type  = bytes[i] & 0xFF;
            int len = bytes[i + 1] & 0xFF;

            if (i + len + 2 > bytes.length) {
                Log.w(TAG, "bad length " + len + " of IE " + type + " from " + result.BSSID);
                Log.w(TAG, "ignoring the rest of the IEs");
                break;
            }
            num++;
            i += len + 2;
            if (DBG) Log.i(TAG, "bytes[" + i + "] = [" + type + ", " + len + "]" + ", " +
                    "next = " + i);
        }

        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, "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;
            index += (len + 2);
        }

        result.informationElements = elements;
        sScanEventHandler.onFullScanResult(result);
    
public static synchronized voidonHotlistApFound(int id, android.net.wifi.ScanResult[] results)

        synchronized (mLock) {
            if (sHotlistCmdId != 0) {
                sHotlistEventHandler.onHotlistApFound(results);
            } else {
                /* this can happen because of race conditions */
                Log.d(TAG, "Ignoring hotlist AP found change");
            }
        }
    
private static synchronized voidonRttResults(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, "Received event for unknown cmd = " + id + ", current id = " + sRttCmdId);
        }
    
static synchronized voidonScanResultsAvailable(int id)

        if (sScanEventHandler  != null) {
            sScanEventHandler.onScanResultsAvailable();
        }
    
static synchronized voidonScanStatus(int status)


         
        Log.i(TAG, "Got a scan status changed event, status = " + 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.onSingleScanComplete();
            }
        }
    
static synchronized voidonSignificantWifiChange(int id, android.net.wifi.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");
            }
        }
    
public booleanp2pCancelConnect()

        return doBooleanCommand("P2P_CANCEL");
    
public java.lang.Stringp2pConnect(android.net.wifi.p2p.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 booleanp2pExtListen(boolean enable, int period, int interval)

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

        return doBooleanCommand("P2P_FIND");
    
public booleanp2pFind(int timeout)

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

        return doBooleanCommand("P2P_FLUSH");
    
public java.lang.Stringp2pGetDeviceAddress()


        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;
    
private java.lang.Stringp2pGetParam(java.lang.String deviceAddress, java.lang.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 java.lang.Stringp2pGetSsid(java.lang.String deviceAddress)

        return p2pGetParam(deviceAddress, "oper_ssid");
    
public booleanp2pGroupAdd(boolean persistent)

        if (persistent) {
            return doBooleanCommand("P2P_GROUP_ADD persistent");
        }
        return doBooleanCommand("P2P_GROUP_ADD");
    
public booleanp2pGroupAdd(int netId)

        return doBooleanCommand("P2P_GROUP_ADD persistent=" + netId);
    
public booleanp2pGroupRemove(java.lang.String iface)

        if (TextUtils.isEmpty(iface)) return false;
        synchronized (mLock) {
            return doBooleanCommandNative("IFNAME=" + iface + " P2P_GROUP_REMOVE " + iface);
        }
    
public booleanp2pInvite(android.net.wifi.p2p.WifiP2pGroup group, java.lang.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);
        }
    
public booleanp2pListen()

        return doBooleanCommand("P2P_LISTEN");
    
public booleanp2pListen(int timeout)

        if (timeout <= 0) {
            return p2pListen();
        }
        return doBooleanCommand("P2P_LISTEN " + timeout);
    
public java.lang.Stringp2pPeer(java.lang.String deviceAddress)

        return doStringCommand("P2P_PEER " + deviceAddress);
    
public booleanp2pProvisionDiscovery(android.net.wifi.p2p.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 booleanp2pReinvoke(int netId, java.lang.String deviceAddress)

        if (TextUtils.isEmpty(deviceAddress) || netId < 0) return false;

        return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
    
public booleanp2pReject(java.lang.String deviceAddress)

        return doBooleanCommand("P2P_REJECT " + deviceAddress);
    
public booleanp2pServDiscCancelReq(java.lang.String id)

        return doBooleanCommand("P2P_SERV_DISC_CANCEL_REQ " + id);
    
public java.lang.Stringp2pServDiscReq(java.lang.String addr, java.lang.String query)

        String command = "P2P_SERV_DISC_REQ";
        command += (" " + addr);
        command += (" " + query);

        return doStringCommand(command);
    
public booleanp2pServiceAdd(android.net.wifi.p2p.nsd.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 booleanp2pServiceDel(android.net.wifi.p2p.nsd.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 booleanp2pServiceFlush()

        return doBooleanCommand("P2P_SERVICE_FLUSH");
    
public booleanp2pSetChannel(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 booleanp2pStopFind()

       return doBooleanCommand("P2P_STOP_FIND");
    
public static synchronized voidpauseScan()

        synchronized (mLock) {
            if (sScanCmdId != 0 && sScanSettings != null && sScanEventHandler != null) {
                Log.d(TAG, "Pausing scan");
                stopScanNative(sWlan0Index, sScanCmdId);
                sScanCmdId = 0;
                sScanEventHandler.onScanPaused();
            }
        }
    
public booleanping()

        String pong = doStringCommand("PING");
        return (pong != null && pong.equals("PONG"));
    
public java.lang.StringpktcntPoll()
Example outout: TXGOOD=396 TXBAD=1

        return doStringCommand("PKTCNT_POLL");
    
public booleanreassociate()

        if (DBG) logDbg("REASSOCIATE ");
        return doBooleanCommand("REASSOCIATE");
    
public booleanreconnect()

        if (DBG) logDbg("RECONNECT ");
        return doBooleanCommand("RECONNECT");
    
private static native intregisterNatives()

public booleanremoveNetwork(int netId)

        return doBooleanCommand("REMOVE_NETWORK " + netId);
    
private static native booleanrequestRangeNative(int iface, int id, RttManager.RttParams[] params)

public static synchronized booleanrequestRtt(RttManager.RttParams[] params, com.android.server.wifi.WifiNative$RttEventHandler handler)

        synchronized (mLock) {
            if (sRttCmdId != 0) {
                return false;
            } else {
                sRttCmdId = getNewCmdIdLocked();
            }
            sRttEventHandler = handler;
            return requestRangeNative(sWlan0Index, sRttCmdId, params);
        }
    
public static synchronized voidresetHotlist()

        synchronized (mLock) {
            if (sHotlistCmdId != 0) {
                resetHotlistNative(sWlan0Index, sHotlistCmdId);
                sHotlistCmdId = 0;
                sHotlistEventHandler = null;
            }
        }
    
private static native booleanresetHotlistNative(int iface, int id)

public booleanresponderReportNfcHandover(java.lang.String requestMessage)

        return doBooleanCommand("NFC_REPORT_HANDOVER RESP P2P " + requestMessage + " 00");
    
public static synchronized voidrestartScan()

        synchronized (mLock) {
            if (sScanCmdId == 0 && sScanSettings != null && sScanEventHandler != null) {
                Log.d(TAG, "Restarting scan");
                startScan(sScanSettings, sScanEventHandler);
                sScanEventHandler.onScanRestarted();
            }
        }
    
public booleansaveConfig()

        return doBooleanCommand("SAVE_CONFIG");
    
public booleanscan(int type, java.lang.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");
        }
    
public java.lang.StringscanResult(java.lang.String bssid)
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...

        return doStringCommand("BSS " + bssid);
    
public java.lang.StringscanResults(int sid)
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= see wpa_supplicant/src/common/wpa_ctrl.h for details

        return doStringCommandWithoutLogging("BSS RANGE=" + sid + "- MASK=0x21987");
    
public booleansetBand(int band)

        return doBooleanCommand("DRIVER SETBAND " + band);
    
public java.lang.StringsetBatchedScanSettings(android.net.wifi.BatchedScanSettings settings)
Format of command DRIVER WLS_BATCHING SET SCANFREQ=x MSCAN=r BESTN=y CHANNEL= 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

        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 booleansetBluetoothCoexistenceMode(int mode)
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.

        return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
    
public booleansetBluetoothCoexistenceScanMode(boolean setCoexScanMode)
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.

        if (setCoexScanMode) {
            return doBooleanCommand("DRIVER BTCOEXSCAN-START");
        } else {
            return doBooleanCommand("DRIVER BTCOEXSCAN-STOP");
        }
    
public booleansetConcurrencyPriority(java.lang.String s)
"sta" prioritizes STA connection over P2P and "p2p" prioritizes P2P connection over STA

        return doBooleanCommand("P2P_SET conc_pref " + s);
    
public booleansetConfigMethods(java.lang.String cfg)

        return doBooleanCommand("SET config_methods " + cfg);
    
public booleansetCountryCode(java.lang.String countryCode)

        return doBooleanCommand("DRIVER COUNTRY " + countryCode.toUpperCase(Locale.ROOT));
    
public booleansetDeviceName(java.lang.String name)

        return doBooleanCommand("SET device_name " + name);
    
public booleansetDeviceType(java.lang.String type)

        return doBooleanCommand("SET device_type " + type);
    
public booleansetExternalSim(boolean external)

        synchronized (mLock) {
            String value = external ? "1" : "0";
            Log.d(TAG, "Setting external_sim to " + value);
            return doBooleanCommand("SET external_sim " + value);
        }
    
public static synchronized booleansetHotlist(WifiScanner.HotlistSettings settings, com.android.server.wifi.WifiNative$HotlistEventHandler eventHandler)


           
             
           

         
                                      
        synchronized (mLock) {
            if (sHotlistCmdId != 0) {
                return false;
            } else {
                sHotlistCmdId = getNewCmdIdLocked();
            }

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

            return true;
        }
    
private static native booleansetHotlistNative(int iface, int id, WifiScanner.HotlistSettings settings)

public booleansetManufacturer(java.lang.String value)

        return doBooleanCommand("SET manufacturer " + value);
    
public voidsetMiracastMode(int mode)

        // Note: optional feature on the driver. It is ok for this to fail.
        doBooleanCommand("DRIVER MIRACAST " + mode);
    
public booleansetModelName(java.lang.String value)

        return doBooleanCommand("SET model_name " + value);
    
public booleansetModelNumber(java.lang.String value)

        return doBooleanCommand("SET model_number " + value);
    
public booleansetNetworkVariable(int netId, java.lang.String name, java.lang.String value)

        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(value)) return false;
        return doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value);
    
public booleansetP2pGroupIdle(java.lang.String iface, int time)

        synchronized (mLock) {
            return doBooleanCommandNative("IFNAME=" + iface + " SET p2p_group_idle " + time);
        }
    
public booleansetP2pPowerSave(java.lang.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 booleansetP2pSsidPostfix(java.lang.String postfix)

        return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
    
public booleansetPersistentReconnect(boolean enabled)

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

        if (enabled) {
            doBooleanCommand("SET ps 1");
        } else {
            doBooleanCommand("SET ps 0");
        }
    
public voidsetScanInterval(int scanInterval)

        doBooleanCommand("SCAN_INTERVAL " + scanInterval);
    
public static synchronized booleansetScanningMacOui(byte[] oui)

        synchronized (mLock) {
            if (startHal()) {
                return setScanningMacOuiNative(sWlan0Index, oui);
            } else {
                return false;
            }
        }
    
private static native booleansetScanningMacOuiNative(int iface, byte[] oui)

public booleansetSerialNumber(java.lang.String value)

        return doBooleanCommand("SET serial_number " + value);
    
public voidsetSupplicantLogLevel(java.lang.String level)

        doStringCommand("LOG_LEVEL " + level);
    
public booleansetSuspendOptimizations(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 booleansetWfdDeviceInfo(java.lang.String hex)

        return doBooleanCommand("WFD_SUBELEM_SET 0 " + hex);
    
public booleansetWfdEnable(boolean enable)

        return doBooleanCommand("SET wifi_display " + (enable ? "1" : "0"));
    
public java.lang.StringsignalPoll()
Example output: RSSI=-65 LINKSPEED=48 NOISE=9999 FREQUENCY=0

        return doStringCommandWithoutLogging("SIGNAL_POLL");
    
public booleansimAuthResponse(int id, java.lang.String response)

        synchronized (mLock) {
            return doBooleanCommand("CTRL-RSP-SIM-" + id + ":GSM-AUTH" + response);
        }
    
public booleanstartDriver()

        return doBooleanCommand("DRIVER START");
    
public booleanstartFilteringMulticastV4Packets()
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

        return doBooleanCommand("DRIVER RXFILTER-STOP")
            && doBooleanCommand("DRIVER RXFILTER-REMOVE 2")
            && doBooleanCommand("DRIVER RXFILTER-START");
    
public booleanstartFilteringMulticastV6Packets()
Start filtering out Multicast V6 packets

return
{@code true} if the operation succeeded, {@code false} otherwise

        return doBooleanCommand("DRIVER RXFILTER-STOP")
            && doBooleanCommand("DRIVER RXFILTER-REMOVE 3")
            && doBooleanCommand("DRIVER RXFILTER-START");
    
public static synchronized booleanstartHal()

        Log.i(TAG, "startHal");
        synchronized (mLock) {
            if (sHalIsStarted)
                return true;
            if (sHalFailed)
                return false;
            if (startHalNative() && (getInterfaces() != 0) && (sWlan0Index != -1)) {
                new MonitorThread().start();
                sHalIsStarted = true;
                return true;
            } else {
                Log.i(TAG, "Could not start hal");
                sHalIsStarted = false;
                sHalFailed = true;
                return false;
            }
        }
    
private static native booleanstartHalNative()

public static synchronized booleanstartScan(com.android.server.wifi.WifiNative$ScanSettings settings, com.android.server.wifi.WifiNative$ScanEventHandler eventHandler)


        
                
        synchronized (mLock) {

            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;
                return false;
            }

            return true;
        }
    
private static native booleanstartScanNative(int iface, int id, com.android.server.wifi.WifiNative$ScanSettings settings)

public static native booleanstartSupplicant(boolean p2pSupported)

public voidstartTdls(java.lang.String macAddr, boolean enable)

        if (enable) {
            doBooleanCommand("TDLS_DISCOVER " + macAddr);
            doBooleanCommand("TDLS_SETUP " + macAddr);
        } else {
            doBooleanCommand("TDLS_TEARDOWN " + macAddr);
        }
    
public booleanstartWpsPbc(java.lang.String bssid)

        if (TextUtils.isEmpty(bssid)) {
            return doBooleanCommand("WPS_PBC");
        } else {
            return doBooleanCommand("WPS_PBC " + bssid);
        }
    
public booleanstartWpsPbc(java.lang.String iface, java.lang.String bssid)

        synchronized (mLock) {
            if (TextUtils.isEmpty(bssid)) {
                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC");
            } else {
                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC " + bssid);
            }
        }
    
public java.lang.StringstartWpsPinDisplay(java.lang.String bssid)

        if (TextUtils.isEmpty(bssid)) {
            return doStringCommand("WPS_PIN any");
        } else {
            return doStringCommand("WPS_PIN " + bssid);
        }
    
public java.lang.StringstartWpsPinDisplay(java.lang.String iface, java.lang.String bssid)

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

        if (TextUtils.isEmpty(pin)) return false;
        return doBooleanCommand("WPS_PIN any " + pin);
    
public booleanstartWpsPinKeypad(java.lang.String iface, java.lang.String pin)

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

        if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false;
        return doBooleanCommand("WPS_REG " + bssid + " " + pin);
    
public java.lang.Stringstatus()

        return status(false);
    
public java.lang.Stringstatus(boolean noEvents)

        if (noEvents) {
            return doStringCommand("STATUS-NO_EVENTS");
        } else {
            return doStringCommand("STATUS");
        }
    
public booleanstopDriver()

        return doBooleanCommand("DRIVER STOP");
    
public booleanstopFilteringMulticastV4Packets()
Stop filtering out Multicast V4 packets.

return
{@code true} if the operation succeeded, {@code false} otherwise

        return doBooleanCommand("DRIVER RXFILTER-STOP")
            && doBooleanCommand("DRIVER RXFILTER-ADD 2")
            && doBooleanCommand("DRIVER RXFILTER-START");
    
public booleanstopFilteringMulticastV6Packets()
Stop filtering out Multicast V6 packets.

return
{@code true} if the operation succeeded, {@code false} otherwise

        return doBooleanCommand("DRIVER RXFILTER-STOP")
            && doBooleanCommand("DRIVER RXFILTER-ADD 3")
            && doBooleanCommand("DRIVER RXFILTER-START");
    
public static synchronized voidstopHal()

        stopHalNative();
    
private static native voidstopHalNative()

public static synchronized voidstopScan()

        synchronized (mLock) {
            stopScanNative(sWlan0Index, sScanCmdId);
            sScanSettings = null;
            sScanEventHandler = null;
            sScanCmdId = 0;
        }
    
private static native booleanstopScanNative(int iface, int id)

public booleanstopSupplicant()

        return doBooleanCommand("TERMINATE");
    
public static synchronized booleantrackSignificantWifiChange(WifiScanner.WifiChangeSettings settings, com.android.server.wifi.WifiNative$SignificantWifiChangeEventHandler handler)

        synchronized (mLock) {
            if (sSignificantWifiChangeCmdId != 0) {
                return false;
            } else {
                sSignificantWifiChangeCmdId = getNewCmdIdLocked();
            }

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

            return true;
        }
    
private static native booleantrackSignificantWifiChangeNative(int iface, int id, WifiScanner.WifiChangeSettings settings)

public static native booleanunloadDriver()

static synchronized voiduntrackSignificantWifiChange()

        synchronized (mLock) {
            if (sSignificantWifiChangeCmdId != 0) {
                untrackSignificantWifiChangeNative(sWlan0Index, sSignificantWifiChangeCmdId);
                sSignificantWifiChangeCmdId = 0;
                sSignificantWifiChangeHandler = null;
            }
        }
    
private static native booleanuntrackSignificantWifiChangeNative(int iface, int id)

public java.lang.StringwaitForEvent()

        // No synchronization necessary .. it is implemented in WifiMonitor
        return waitForEventNative();
    
private native java.lang.StringwaitForEventNative()
Wait for the supplicant to send an event, returning the event string.

return
the event string sent by the supplicant.

private static native voidwaitForHalEventNative()