19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.net.wifi;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.p2p.WifiP2pConfig;
2055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.p2p.WifiP2pGroup;
21618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.text.TextUtils;
2221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
2355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.util.Log;
2455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.ArrayList;
2655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.List;
2755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
291f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * Native calls for bring up/shut down of the supplicant daemon and for
301f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * sending requests to the supplicant daemon
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * waitForEvent() is called on the monitor thread for events. All other methods
331f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * must be serialized from the framework.
3455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class WifiNative {
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
397d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final boolean DBG = false;
407d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private final String mTAG;
41bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff    private static final int DEFAULT_GROUP_OWNER_INTENT     = 6;
42fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff
43bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff    static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED     = 0;
44bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff    static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED    = 1;
45bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff    static final int BLUETOOTH_COEXISTENCE_MODE_SENSE       = 2;
46bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff
47bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff    static final int SCAN_WITHOUT_CONNECTION_SETUP          = 1;
48bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff    static final int SCAN_WITH_CONNECTION_SETUP             = 2;
495d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
50fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    String mInterface = "";
51633fe60b78665979109d4796ba22430b7b1cd758Irfan Sheriff    private boolean mSuspendOptEnabled = false;
5244b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean loadDriver();
54a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff
55a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff    public native static boolean isDriverLoaded();
565d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean unloadDriver();
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
597d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    public native static boolean startSupplicant(boolean p2pSupported);
60f42c39b3d188ebb3ba9003cffc530717829fe874Irfan Sheriff
615d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff    /* Sends a kill signal to supplicant. To be used when we have lost connection
625d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff       or when the supplicant is hung */
63511d5346ced4b37e4ba68e0bd089d4dad8b3bff7Irfan Sheriff    public native static boolean killSupplicant(boolean p2pSupported);
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
65fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native boolean connectToSupplicant(String iface);
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
67fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native void closeSupplicantConnection(String iface);
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
691f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /**
701f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * Wait for the supplicant to send an event, returning the event string.
711f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * @return the event string sent by the supplicant.
721f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     */
73fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native String waitForEvent(String iface);
7444b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
75fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native boolean doBooleanCommand(String iface, String command);
7644b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
77fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native int doIntCommand(String iface, String command);
7844b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
79fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native String doStringCommand(String iface, String command);
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
81fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public WifiNative(String iface) {
82fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mInterface = iface;
837d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        mTAG = "WifiNative-" + iface;
8444b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
8544b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
86fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean connectToSupplicant() {
87fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return connectToSupplicant(mInterface);
8844b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
895d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
90fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public void closeSupplicantConnection() {
91fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        closeSupplicantConnection(mInterface);
9244b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
94fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String waitForEvent() {
95fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return waitForEvent(mInterface);
9644b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
9744b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
98fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private boolean doBooleanCommand(String command) {
997d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        if (DBG) Log.d(mTAG, "doBoolean: " + command);
100fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return doBooleanCommand(mInterface, command);
10144b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
10244b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
103fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private int doIntCommand(String command) {
1047d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        if (DBG) Log.d(mTAG, "doInt: " + command);
105fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return doIntCommand(mInterface, command);
10644b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
10744b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
108fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private String doStringCommand(String command) {
1097d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        if (DBG) Log.d(mTAG, "doString: " + command);
110fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return doStringCommand(mInterface, command);
11144b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
113fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean ping() {
1141f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String pong = doStringCommand("PING");
1151f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return (pong != null && pong.equals("PONG"));
1161f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
118bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff    public boolean scan(int type) {
119bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff        if (type == SCAN_WITHOUT_CONNECTION_SETUP) {
120bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff            return doBooleanCommand("SCAN TYPE=ONLY");
121bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff        } else if (type == SCAN_WITH_CONNECTION_SETUP) {
122bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff            return doBooleanCommand("SCAN");
1231f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
124bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff            throw new IllegalArgumentException("Invalid scan type");
1251f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
1261f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1281f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /* Does a graceful shutdown of supplicant. Is a common stop function for both p2p and sta.
1291f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
1301f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * Note that underneath we use a harsh-sounding "terminate" supplicant command
1311f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * for a graceful stop and a mild-sounding "stop" interface
1321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * to kill the process
1331f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     */
134fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean stopSupplicant() {
1351f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("TERMINATE");
1361f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
138fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String listNetworks() {
1391f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("LIST_NETWORKS");
1401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1415d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
142fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public int addNetwork() {
1431f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doIntCommand("ADD_NETWORK");
1441f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
146fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setNetworkVariable(int netId, String name, String value) {
1471f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(value)) return false;
1481f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value);
1491f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
151fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String getNetworkVariable(int netId, String name) {
1521f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (TextUtils.isEmpty(name)) return null;
1531f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("GET_NETWORK " + netId + " " + name);
1541f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
156fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean removeNetwork(int netId) {
1571f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("REMOVE_NETWORK " + netId);
1581f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
15996071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
160fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean enableNetwork(int netId, boolean disableOthers) {
1611f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (disableOthers) {
1621f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("SELECT_NETWORK " + netId);
1631f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
1641f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("ENABLE_NETWORK " + netId);
1651f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
1661f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
168fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean disableNetwork(int netId) {
1691f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DISABLE_NETWORK " + netId);
1701f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
172fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean reconnect() {
1731f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("RECONNECT");
1741f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
176fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean reassociate() {
1771f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("REASSOCIATE");
1781f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
180fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean disconnect() {
1811f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DISCONNECT");
1821f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1831f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
184fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String status() {
1851f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("STATUS");
1861f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1871f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
188fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String getMacAddress() {
1891f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        //Macaddr = XX.XX.XX.XX.XX.XX
1901f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String ret = doStringCommand("DRIVER MACADDR");
1911f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (!TextUtils.isEmpty(ret)) {
1921f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            String[] tokens = ret.split(" = ");
1931f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            if (tokens.length == 2) return tokens[1];
1941f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
1951f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return null;
1961f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1971f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
19806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev    /**
19906c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * Format of results:
20006c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * =================
2019233fc0023755e190e7c28374c5c6fa6558dec70Iliyan Malchev     * id=1
20206c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * bssid=68:7f:74:d7:1b:6e
20306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * freq=2412
20406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * level=-43
20506c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * tsf=1344621975160944
20606c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * age=2623
20706c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * flags=[WPA2-PSK-CCMP][WPS][ESS]
20806c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * ssid=zubyb
20914b628a3400b6c36e0604f403dd72553c6fe63c2Dmitry Shmidt     * ====
21006c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     *
21106c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * RANGE=ALL gets all scan results
2129233fc0023755e190e7c28374c5c6fa6558dec70Iliyan Malchev     * RANGE=ID- gets results from ID
21306c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     * MASK=<N> see wpa_supplicant/src/common/wpa_ctrl.h for details
21406c43d575c88976f8709ff3fc0bad7117bde23e7Iliyan Malchev     */
2159233fc0023755e190e7c28374c5c6fa6558dec70Iliyan Malchev    public String scanResults(int sid) {
2169233fc0023755e190e7c28374c5c6fa6558dec70Iliyan Malchev        return doStringCommand("BSS RANGE=" + sid + "- MASK=0x21987");
2171f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2181f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
219fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startDriver() {
2201f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER START");
2211f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2221f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
223fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean stopDriver() {
2241f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER STOP");
2251f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
227b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
228b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /**
229b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Start filtering out Multicast V4 packets
230b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * @return {@code true} if the operation succeeded, {@code false} otherwise
2311f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * Multicast filtering rules work as follows:
2331f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2341f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
2351f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * a power optimized mode (typically when screen goes off).
2361f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2371f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
2381f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
2391f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * DRIVER RXFILTER-ADD Num
2411f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
2421f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2431f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * and DRIVER RXFILTER-START
2441f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * In order to stop the usage of these rules, we do
2451f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2461f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * DRIVER RXFILTER-STOP
2471f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * DRIVER RXFILTER-REMOVE Num
2481f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *   where Num is as described for RXFILTER-ADD
2491f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2501f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * The  SETSUSPENDOPT driver command overrides the filtering rules
251b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     */
252fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startFilteringMulticastV4Packets() {
2531f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2541f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-REMOVE 2")
2551f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2561f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
257b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
258b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /**
259b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Stop filtering out Multicast V4 packets.
260b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * @return {@code true} if the operation succeeded, {@code false} otherwise
261b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     */
262fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean stopFilteringMulticastV4Packets() {
2631f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2641f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-ADD 2")
2651f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2661f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
267b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
269b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Start filtering out Multicast V6 packets
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} if the operation succeeded, {@code false} otherwise
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
272fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startFilteringMulticastV6Packets() {
2731f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2741f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-REMOVE 3")
2751f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2761f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
279b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Stop filtering out Multicast V6 packets.
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} if the operation succeeded, {@code false} otherwise
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
282fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean stopFilteringMulticastV6Packets() {
2831f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2841f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-ADD 3")
2851f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2861f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
288fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public int getBand() {
2891f095869536472c178046bb63c59947508eac4a6Irfan Sheriff       String ret = doStringCommand("DRIVER GETBAND");
2901f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (!TextUtils.isEmpty(ret)) {
2911f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            //reply is "BAND X" where X is the band
2921f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            String[] tokens = ret.split(" ");
2931f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            try {
2941f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                if (tokens.length == 2) return Integer.parseInt(tokens[1]);
2951f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            } catch (NumberFormatException e) {
2961f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                return -1;
2971f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            }
2981f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
2991f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return -1;
3001f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
30125c9bf2396ceb48fc5cfd5c1dd58aa4d4750d056Irfan Sheriff
302fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setBand(int band) {
3031f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER SETBAND " + band);
3041f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
305ea8bd1d1676dd96f8f9726bb8f67fa18dec7b9c1Mikael Kanstrup
3061f095869536472c178046bb63c59947508eac4a6Irfan Sheriff   /**
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the bluetooth coexistence mode.
3085d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff     *
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Whether the mode was successfully set.
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
314fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setBluetoothCoexistenceMode(int mode) {
3151f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
3161f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
317b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
318b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    /**
319b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
320b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * some of the low-level scan parameters used by the driver are changed to
321b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * reduce interference with A2DP streaming.
322b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     *
323b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * @param isSet whether to enable or disable this mode
324b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * @return {@code true} if the command succeeded, {@code false} otherwise.
325b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     */
326fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
3271f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (setCoexScanMode) {
3281f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER BTCOEXSCAN-START");
3291f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
3301f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER BTCOEXSCAN-STOP");
3311f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
3321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3335ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
334fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean saveConfig() {
335bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff        return doBooleanCommand("SAVE_CONFIG");
3361f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
337ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
338fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean addToBlacklist(String bssid) {
3391f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (TextUtils.isEmpty(bssid)) return false;
3401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("BLACKLIST " + bssid);
3411f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
342fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff
343fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean clearBlacklist() {
3441f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("BLACKLIST clear");
3451f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3462b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff
347fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setSuspendOptimizations(boolean enabled) {
348633fe60b78665979109d4796ba22430b7b1cd758Irfan Sheriff        if (mSuspendOptEnabled == enabled) return true;
349633fe60b78665979109d4796ba22430b7b1cd758Irfan Sheriff        mSuspendOptEnabled = enabled;
3501f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (enabled) {
351262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff            return doBooleanCommand("DRIVER SETSUSPENDMODE 1");
3521f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
353262f766ac8bd330008e1f0a61c1a37c64108b17cIrfan Sheriff            return doBooleanCommand("DRIVER SETSUSPENDMODE 0");
3541f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
3551f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
35655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
357fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setCountryCode(String countryCode) {
3581f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER COUNTRY " + countryCode);
3591f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
36055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
361fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public void enableBackgroundScan(boolean enable) {
3621f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (enable) {
363e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff            doBooleanCommand("SET pno 1");
3641f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
365e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff            doBooleanCommand("SET pno 0");
3661f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
3671f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
36855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
369fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public void setScanInterval(int scanInterval) {
3701f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        doBooleanCommand("SCAN_INTERVAL " + scanInterval);
3711f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
37255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
373921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff    /** Example output:
374921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * RSSI=-65
375921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * LINKSPEED=48
376921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * NOISE=9999
377921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * FREQUENCY=0
378921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     */
379fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String signalPoll() {
380921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        return doStringCommand("SIGNAL_POLL");
381921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff    }
382921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
383b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng    /** Example outout:
384b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng     * TXGOOD=396
385b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng     * TXBAD=1
386b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng     */
387b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng    public String pktcntPoll() {
388b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng        return doStringCommand("PKTCNT_POLL");
389b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng    }
390b33227d23eb0ec3507192f94c2eee651a0f97783Yuhao Zheng
391fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startWpsPbc(String bssid) {
39286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(bssid)) {
39386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            return doBooleanCommand("WPS_PBC");
39486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        } else {
39586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            return doBooleanCommand("WPS_PBC " + bssid);
39686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        }
3971f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3981f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
39955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    public boolean startWpsPbc(String iface, String bssid) {
40055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        if (TextUtils.isEmpty(bssid)) {
40155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            return doBooleanCommand("WPS_PBC interface=" + iface);
40255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        } else {
40355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            return doBooleanCommand("WPS_PBC interface=" + iface + " " + bssid);
40455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        }
40555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    }
40655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
407fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startWpsPinKeypad(String pin) {
40886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(pin)) return false;
4092b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("WPS_PIN any " + pin);
4102b8edd0c485f74067605c19983e3e7f44b20ec50repo sync    }
4112b8edd0c485f74067605c19983e3e7f44b20ec50repo sync
41255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    public boolean startWpsPinKeypad(String iface, String pin) {
41355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        if (TextUtils.isEmpty(pin)) return false;
41455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        return doBooleanCommand("WPS_PIN interface=" + iface + " any " + pin);
41555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    }
41655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
41755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
418fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String startWpsPinDisplay(String bssid) {
41986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(bssid)) {
42086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            return doStringCommand("WPS_PIN any");
42186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        } else {
42286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            return doStringCommand("WPS_PIN " + bssid);
42386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        }
4241f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
4251f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
42655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    public String startWpsPinDisplay(String iface, String bssid) {
42755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        if (TextUtils.isEmpty(bssid)) {
42855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            return doStringCommand("WPS_PIN interface=" + iface + " any");
42955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        } else {
43055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            return doStringCommand("WPS_PIN interface=" + iface + " " + bssid);
43155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        }
43255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    }
43355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
4341f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /* Configures an access point connection */
435fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startWpsRegistrar(String bssid, String pin) {
43686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false;
4371f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("WPS_REG " + bssid + " " + pin);
4381f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
4391f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
44086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    public boolean cancelWps() {
44186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        return doBooleanCommand("WPS_CANCEL");
44286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    }
44386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
444fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setPersistentReconnect(boolean enabled) {
4459322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        int value = (enabled == true) ? 1 : 0;
4461f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET persistent_reconnect " + value);
4479322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
4489322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
449fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setDeviceName(String name) {
4501f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET device_name " + name);
4519322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
4529322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
453fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setDeviceType(String type) {
4541f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET device_type " + type);
4559322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
4569322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
457fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setConfigMethods(String cfg) {
4581f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET config_methods " + cfg);
459618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
460618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
4614dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff    public boolean setManufacturer(String value) {
4624dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff        return doBooleanCommand("SET manufacturer " + value);
4634dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff    }
4644dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff
4654dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff    public boolean setModelName(String value) {
4664dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff        return doBooleanCommand("SET model_name " + value);
4674dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff    }
4684dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff
4694dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff    public boolean setModelNumber(String value) {
4704dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff        return doBooleanCommand("SET model_number " + value);
4714dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff    }
4724dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff
4734dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff    public boolean setSerialNumber(String value) {
4744dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff        return doBooleanCommand("SET serial_number " + value);
4754dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff    }
4764dd5a25a32dc4a721a411f92f0720672ee08020bIrfan Sheriff
477fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setP2pSsidPostfix(String postfix) {
4781f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
479530040e0b9458994c02f4392765db168128d48daIrfan Sheriff    }
480530040e0b9458994c02f4392765db168128d48daIrfan Sheriff
48110ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff    public boolean setP2pGroupIdle(String iface, int time) {
48210ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff        return doBooleanCommand("SET interface=" + iface + " p2p_group_idle " + time);
48355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    }
48455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
485e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff    public void setPowerSave(boolean enabled) {
486e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff        if (enabled) {
487e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff            doBooleanCommand("SET ps 1");
488e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff        } else {
489e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff            doBooleanCommand("SET ps 0");
490e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff        }
491e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff    }
492e2639d782eef1365a98dbd2639be23a6dd06e691Irfan Sheriff
49355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    public boolean setP2pPowerSave(String iface, boolean enabled) {
49455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        if (enabled) {
49555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            return doBooleanCommand("P2P_SET interface=" + iface + " ps 1");
49655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        } else {
49755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            return doBooleanCommand("P2P_SET interface=" + iface + " ps 0");
49855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        }
49955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    }
50055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
501ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    public boolean setWfdEnable(boolean enable) {
502ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        return doBooleanCommand("SET wifi_display " + (enable ? "1" : "0"));
503ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    }
504ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
505ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    public boolean setWfdDeviceInfo(String hex) {
506ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        return doBooleanCommand("WFD_SUBELEM_SET 0 " + hex);
507ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    }
508ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
50955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    /**
51055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff     * "sta" prioritizes STA connection over P2P and "p2p" prioritizes
51155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff     * P2P connection over STA
51255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff     */
51355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    public boolean setConcurrencyPriority(String s) {
514de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        return doBooleanCommand("P2P_SET conc_pref " + s);
51555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    }
51655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
517fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pFind() {
5182b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_FIND");
51955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
52055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
521fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pFind(int timeout) {
52255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (timeout <= 0) {
52355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return p2pFind();
52455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
5252b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_FIND " + timeout);
52655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
52755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
5287d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    public boolean p2pStopFind() {
5297d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff       return doBooleanCommand("P2P_STOP_FIND");
5307d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    }
5317d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff
532fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pListen() {
5332b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_LISTEN");
53455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
53555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
536fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pListen(int timeout) {
53755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (timeout <= 0) {
53855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return p2pListen();
53955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
5402b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_LISTEN " + timeout);
54155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
54255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
543fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pFlush() {
5442b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_FLUSH");
54555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
54655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
54755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
54855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
549fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
55055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (config == null) return null;
55155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        List<String> args = new ArrayList<String>();
552651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        WpsInfo wps = config.wps;
55355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        args.add(config.deviceAddress);
55455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
5556f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff        switch (wps.setup) {
556651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.PBC:
55755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("pbc");
55855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
559651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.DISPLAY:
560618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                if (TextUtils.isEmpty(wps.pin)) {
561618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    args.add("pin");
562618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                } else {
563618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    args.add(wps.pin);
564618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                }
56555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("display");
56655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
567651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.KEYPAD:
5686f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff                args.add(wps.pin);
56955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("keypad");
57055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
571651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.LABEL:
5726f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff                args.add(wps.pin);
57355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("label");
57455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            default:
57555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
57655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
57755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
5780879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (config.netId == WifiP2pGroup.PERSISTENT_NET_ID) {
5790879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            args.add("persistent");
5800879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
581f9cb1d7082870d9fc5f90290e717065441f611acIrfan Sheriff
582de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        if (joinExistingGroup) {
583de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff            args.add("join");
584de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        } else {
585de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff            //TODO: This can be adapted based on device plugged in state and
586de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff            //device battery state
587de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff            int groupOwnerIntent = config.groupOwnerIntent;
588de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff            if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
589de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                groupOwnerIntent = DEFAULT_GROUP_OWNER_INTENT;
590de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff            }
591de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff            args.add("go_intent=" + groupOwnerIntent);
5922b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        }
59355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
5942b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        String command = "P2P_CONNECT ";
59555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        for (String s : args) command += s + " ";
59655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
5972b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doStringCommand(command);
59855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
59955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
600fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pCancelConnect() {
601651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        return doBooleanCommand("P2P_CANCEL");
602651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
603651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
604fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pProvisionDiscovery(WifiP2pConfig config) {
605618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        if (config == null) return false;
606618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
607618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        switch (config.wps.setup) {
608618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.PBC:
609618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " pbc");
610618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.DISPLAY:
611618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                //We are doing display, so provision discovery is keypad
612618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " keypad");
613618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.KEYPAD:
614618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                //We are doing keypad, so provision discovery is display
615618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " display");
616618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            default:
617618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
618618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
619618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        return false;
620618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
621618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
6220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    public boolean p2pGroupAdd(boolean persistent) {
6230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (persistent) {
6240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return doBooleanCommand("P2P_GROUP_ADD persistent");
6250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
6262b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_GROUP_ADD");
62755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
62855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
6290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    public boolean p2pGroupAdd(int netId) {
6300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return doBooleanCommand("P2P_GROUP_ADD persistent=" + netId);
6310879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
6320879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
633fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pGroupRemove(String iface) {
63486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(iface)) return false;
6352b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
63655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
63755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
638fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pReject(String deviceAddress) {
6392b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_REJECT " + deviceAddress);
64055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
64155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
64255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Invite a peer to a group */
643fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
64486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(deviceAddress)) return false;
645ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
646ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (group == null) {
647ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            return doBooleanCommand("P2P_INVITE peer=" + deviceAddress);
648ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        } else {
649ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
650ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
651ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        }
652ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
653ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
654ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /* Reinvoke a persistent connection */
655fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pReinvoke(int netId, String deviceAddress) {
65686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(deviceAddress) || netId < 0) return false;
657ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
658ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
65955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
6608c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
6610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    public String p2pGetSsid(String deviceAddress) {
6620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return p2pGetParam(deviceAddress, "oper_ssid");
6630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
664ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
665fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String p2pGetDeviceAddress() {
6661f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String status = status();
6674be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        if (status == null) return "";
6684be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
6694be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        String[] tokens = status.split("\n");
6704be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        for (String token : tokens) {
6714be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            if (token.startsWith("p2p_device_address=")) {
6724be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                String[] nameValue = token.split("=");
6734be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                if (nameValue.length != 2) break;
6744be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                return nameValue[1];
6754be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            }
6764be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        }
6774be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        return "";
6784be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    }
6794be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
68057e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff    public int getGroupCapability(String deviceAddress) {
68157e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff        int gc = 0;
68257e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff        if (TextUtils.isEmpty(deviceAddress)) return gc;
68357e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff        String peerInfo = p2pPeer(deviceAddress);
68457e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff        if (TextUtils.isEmpty(peerInfo)) return gc;
68557e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff
68657e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff        String[] tokens = peerInfo.split("\n");
68757e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff        for (String token : tokens) {
68857e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff            if (token.startsWith("group_capab=")) {
68957e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                String[] nameValue = token.split("=");
69057e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                if (nameValue.length != 2) break;
69157e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                try {
69257e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                    return Integer.decode(nameValue[1]);
69357e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                } catch(NumberFormatException e) {
69457e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                    return gc;
69557e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                }
69657e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff            }
69757e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff        }
69857e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff        return gc;
69957e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff    }
70057e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff
701fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String p2pPeer(String deviceAddress) {
7028c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        return doStringCommand("P2P_PEER " + deviceAddress);
7038c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    }
70421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
7050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private String p2pGetParam(String deviceAddress, String key) {
7060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (deviceAddress == null) return null;
7070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
7080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String peerInfo = p2pPeer(deviceAddress);
7090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (peerInfo == null) return null;
7100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String[] tokens= peerInfo.split("\n");
7110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
7120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        key += "=";
7130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        for (String token : tokens) {
7140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (token.startsWith(key)) {
7150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                String[] nameValue = token.split("=");
7160879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (nameValue.length != 2) break;
7170879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return nameValue[1];
7180879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
7190879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
7200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return null;
7210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
7220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
72321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) {
72421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
72521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * P2P_SERVICE_ADD bonjour <query hexdump> <RDATA hexdump>
72621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * P2P_SERVICE_ADD upnp <version hex> <service>
72721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         *
72821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * e.g)
72921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * [Bonjour]
73021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * # IP Printing over TCP (PTR) (RDATA=MyPrinter._ipp._tcp.local.)
73121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * P2P_SERVICE_ADD bonjour 045f697070c00c000c01 094d795072696e746572c027
73221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * # IP Printing over TCP (TXT) (RDATA=txtvers=1,pdl=application/postscript)
73321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * P2P_SERVICE_ADD bonjour 096d797072696e746572045f697070c00c001001
73421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         *  09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074
73521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         *
73621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * [UPnP]
73721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012
73821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice
73921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp
74021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * -org:device:InternetGatewayDevice:1
74121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9322-123456789012::urn:schemas-upnp
74221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * -org:service:ContentDirectory:2
74321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
74421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (String s : servInfo.getSupplicantQueryList()) {
74521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            String command = "P2P_SERVICE_ADD";
74621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            command += (" " + s);
74721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (!doBooleanCommand(command)) {
74821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                return false;
74921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
75021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
75121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return true;
75221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
75321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
75421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public boolean p2pServiceDel(WifiP2pServiceInfo servInfo) {
75521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
75621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * P2P_SERVICE_DEL bonjour <query hexdump>
75721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * P2P_SERVICE_DEL upnp <version hex> <service>
75821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
75921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (String s : servInfo.getSupplicantQueryList()) {
76021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            String command = "P2P_SERVICE_DEL ";
76121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
76221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            String[] data = s.split(" ");
76321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (data.length < 2) {
76421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                return false;
76521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
76621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if ("upnp".equals(data[0])) {
76721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                command += s;
76821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            } else if ("bonjour".equals(data[0])) {
76921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                command += data[0];
77021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                command += (" " + data[1]);
77121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            } else {
77221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                return false;
77321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
77421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (!doBooleanCommand(command)) {
77521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                return false;
77621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
77721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
77821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return true;
77921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
78021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
78121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public boolean p2pServiceFlush() {
78221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return doBooleanCommand("P2P_SERVICE_FLUSH");
78321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
78421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
78521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public String p2pServDiscReq(String addr, String query) {
78621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        String command = "P2P_SERV_DISC_REQ";
78721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        command += (" " + addr);
78821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        command += (" " + query);
78921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
79021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return doStringCommand(command);
79121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
79221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
79321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public boolean p2pServDiscCancelReq(String id) {
79421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return doBooleanCommand("P2P_SERV_DISC_CANCEL_REQ " + id);
79521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
7968b485adffd7eaa7b7cab4c444b3d65097ef40a14Irfan Sheriff
7978b485adffd7eaa7b7cab4c444b3d65097ef40a14Irfan Sheriff    /* Set the current mode of miracast operation.
7988b485adffd7eaa7b7cab4c444b3d65097ef40a14Irfan Sheriff     *  0 = disabled
7998b485adffd7eaa7b7cab4c444b3d65097ef40a14Irfan Sheriff     *  1 = operating as source
8008b485adffd7eaa7b7cab4c444b3d65097ef40a14Irfan Sheriff     *  2 = operating as sink
8018b485adffd7eaa7b7cab4c444b3d65097ef40a14Irfan Sheriff     */
8028b485adffd7eaa7b7cab4c444b3d65097ef40a14Irfan Sheriff    public void setMiracastMode(int mode) {
8038b485adffd7eaa7b7cab4c444b3d65097ef40a14Irfan Sheriff        // Note: optional feature on the driver. It is ok for this to fail.
8048b485adffd7eaa7b7cab4c444b3d65097ef40a14Irfan Sheriff        doBooleanCommand("DRIVER MIRACAST " + mode);
8058b485adffd7eaa7b7cab4c444b3d65097ef40a14Irfan Sheriff    }
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
807