WifiNative.java revision 86a5f5b9afa97a4ed6f5a2466fb9359ea131e2fb
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;
2155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.p2p.WifiP2pDevice;
2244b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriffimport android.os.SystemProperties;
23618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.text.TextUtils;
2455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.util.Log;
2555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.io.InputStream;
2755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.lang.Process;
2855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.ArrayList;
2955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.List;
3055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * Native calls for bring up/shut down of the supplicant daemon and for
331f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * sending requests to the supplicant daemon
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
351f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * waitForEvent() is called on the monitor thread for events. All other methods
361f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * must be serialized from the framework.
3755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class WifiNative {
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
427d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final boolean DBG = false;
437d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private final String mTAG;
44fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private static final int DEFAULT_GROUP_OWNER_INTENT = 7;
45fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED = 0;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int BLUETOOTH_COEXISTENCE_MODE_SENSE = 2;
495d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
50fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    String mInterface = "";
5144b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean loadDriver();
53a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff
54a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff    public native static boolean isDriverLoaded();
555d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean unloadDriver();
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
587d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    public native static boolean startSupplicant(boolean p2pSupported);
59f42c39b3d188ebb3ba9003cffc530717829fe874Irfan Sheriff
605d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff    /* Sends a kill signal to supplicant. To be used when we have lost connection
615d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff       or when the supplicant is hung */
6296071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    public native static boolean killSupplicant();
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
64fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native boolean connectToSupplicant(String iface);
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
66fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native void closeSupplicantConnection(String iface);
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
681f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /**
691f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * Wait for the supplicant to send an event, returning the event string.
701f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * @return the event string sent by the supplicant.
711f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     */
72fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native String waitForEvent(String iface);
7344b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
74fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native boolean doBooleanCommand(String iface, String command);
7544b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
76fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native int doIntCommand(String iface, String command);
7744b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
78fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private native String doStringCommand(String iface, String command);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
80fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public WifiNative(String iface) {
81fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mInterface = iface;
827d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        mTAG = "WifiNative-" + iface;
8344b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
8444b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
85fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean connectToSupplicant() {
86fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return connectToSupplicant(mInterface);
8744b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
885d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
89fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public void closeSupplicantConnection() {
90fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        closeSupplicantConnection(mInterface);
9144b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
93fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String waitForEvent() {
94fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return waitForEvent(mInterface);
9544b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
9644b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
97fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private boolean doBooleanCommand(String command) {
987d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        if (DBG) Log.d(mTAG, "doBoolean: " + command);
99fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return doBooleanCommand(mInterface, command);
10044b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
10144b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
102fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private int doIntCommand(String command) {
1037d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        if (DBG) Log.d(mTAG, "doInt: " + command);
104fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return doIntCommand(mInterface, command);
10544b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
10644b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff
107fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private String doStringCommand(String command) {
1087d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        if (DBG) Log.d(mTAG, "doString: " + command);
109fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return doStringCommand(mInterface, command);
11044b330dfb0aeecb4e2ac97ff72a5abfb341c74fbIrfan Sheriff    }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
112fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean ping() {
1131f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String pong = doStringCommand("PING");
1141f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return (pong != null && pong.equals("PONG"));
1151f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
117fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean scan() {
1181f095869536472c178046bb63c59947508eac4a6Irfan Sheriff       return doBooleanCommand("SCAN");
1191f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
121fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setScanMode(boolean setActive) {
1221f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (setActive) {
1231f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER SCAN-ACTIVE");
1241f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
1251f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER SCAN-PASSIVE");
1261f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
1271f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1291f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /* Does a graceful shutdown of supplicant. Is a common stop function for both p2p and sta.
1301f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
1311f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * Note that underneath we use a harsh-sounding "terminate" supplicant command
1321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * for a graceful stop and a mild-sounding "stop" interface
1331f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * to kill the process
1341f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     */
135fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean stopSupplicant() {
1361f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("TERMINATE");
1371f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
139fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String listNetworks() {
1401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("LIST_NETWORKS");
1411f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1425d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
143fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public int addNetwork() {
1441f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doIntCommand("ADD_NETWORK");
1451f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
147fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setNetworkVariable(int netId, String name, String value) {
1481f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(value)) return false;
1491f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value);
1501f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
152fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String getNetworkVariable(int netId, String name) {
1531f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (TextUtils.isEmpty(name)) return null;
1541f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("GET_NETWORK " + netId + " " + name);
1551f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
157fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean removeNetwork(int netId) {
1581f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("REMOVE_NETWORK " + netId);
1591f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
16096071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
161fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean enableNetwork(int netId, boolean disableOthers) {
1621f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (disableOthers) {
1631f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("SELECT_NETWORK " + netId);
1641f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
1651f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("ENABLE_NETWORK " + netId);
1661f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
1671f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
169fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean disableNetwork(int netId) {
1701f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DISABLE_NETWORK " + netId);
1711f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
173fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean reconnect() {
1741f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("RECONNECT");
1751f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
177fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean reassociate() {
1781f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("REASSOCIATE");
1791f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
181fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean disconnect() {
1821f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DISCONNECT");
1831f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1841f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
185fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String status() {
1861f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("STATUS");
1871f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1881f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
189fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String getMacAddress() {
1901f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        //Macaddr = XX.XX.XX.XX.XX.XX
1911f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String ret = doStringCommand("DRIVER MACADDR");
1921f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (!TextUtils.isEmpty(ret)) {
1931f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            String[] tokens = ret.split(" = ");
1941f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            if (tokens.length == 2) return tokens[1];
1951f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
1961f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return null;
1971f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1981f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
199fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String scanResults() {
2001f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("SCAN_RESULTS");
2011f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2021f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
203fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startDriver() {
2041f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER START");
2051f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2061f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
207fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean stopDriver() {
2081f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER STOP");
2091f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
211b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
212b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /**
213b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Start filtering out Multicast V4 packets
214b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * @return {@code true} if the operation succeeded, {@code false} otherwise
2151f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2161f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * Multicast filtering rules work as follows:
2171f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2181f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
2191f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * a power optimized mode (typically when screen goes off).
2201f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2211f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
2221f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
2231f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2241f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * DRIVER RXFILTER-ADD Num
2251f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
2261f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2271f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * and DRIVER RXFILTER-START
2281f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * In order to stop the usage of these rules, we do
2291f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2301f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * DRIVER RXFILTER-STOP
2311f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * DRIVER RXFILTER-REMOVE Num
2321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *   where Num is as described for RXFILTER-ADD
2331f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
2341f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * The  SETSUSPENDOPT driver command overrides the filtering rules
235b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     */
236fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startFilteringMulticastV4Packets() {
2371f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2381f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-REMOVE 2")
2391f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
241b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
242b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /**
243b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Stop filtering out Multicast V4 packets.
244b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * @return {@code true} if the operation succeeded, {@code false} otherwise
245b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     */
246fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean stopFilteringMulticastV4Packets() {
2471f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2481f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-ADD 2")
2491f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2501f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
251b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
253b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Start filtering out Multicast V6 packets
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} if the operation succeeded, {@code false} otherwise
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
256fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startFilteringMulticastV6Packets() {
2571f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2581f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-REMOVE 3")
2591f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2601f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
263b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Stop filtering out Multicast V6 packets.
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} if the operation succeeded, {@code false} otherwise
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
266fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean stopFilteringMulticastV6Packets() {
2671f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2681f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-ADD 3")
2691f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2701f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
272fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public int getPowerMode() {
2731f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String ret = doStringCommand("DRIVER GETPOWER");
2741f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (!TextUtils.isEmpty(ret)) {
2751f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            // reply comes back in the form "powermode = XX" where XX is the
2761f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            // number we're interested in.
2771f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            String[] tokens = ret.split(" = ");
2781f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            try {
2791f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                if (tokens.length == 2) return Integer.parseInt(tokens[1]);
2801f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            } catch (NumberFormatException e) {
2811f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                return -1;
2821f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            }
2831f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
2841f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return -1;
2851f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
287fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setPowerMode(int mode) {
2881f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER POWERMODE " + mode);
2891f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
29025c9bf2396ceb48fc5cfd5c1dd58aa4d4750d056Irfan Sheriff
291fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public int getBand() {
2921f095869536472c178046bb63c59947508eac4a6Irfan Sheriff       String ret = doStringCommand("DRIVER GETBAND");
2931f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (!TextUtils.isEmpty(ret)) {
2941f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            //reply is "BAND X" where X is the band
2951f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            String[] tokens = ret.split(" ");
2961f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            try {
2971f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                if (tokens.length == 2) return Integer.parseInt(tokens[1]);
2981f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            } catch (NumberFormatException e) {
2991f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                return -1;
3001f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            }
3011f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
3021f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return -1;
3031f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
30425c9bf2396ceb48fc5cfd5c1dd58aa4d4750d056Irfan Sheriff
305fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setBand(int band) {
3061f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER SETBAND " + band);
3071f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
308ea8bd1d1676dd96f8f9726bb8f67fa18dec7b9c1Mikael Kanstrup
3091f095869536472c178046bb63c59947508eac4a6Irfan Sheriff   /**
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the bluetooth coexistence mode.
3115d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff     *
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Whether the mode was successfully set.
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
317fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setBluetoothCoexistenceMode(int mode) {
3181f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
3191f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
320b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
321b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    /**
322b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
323b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * some of the low-level scan parameters used by the driver are changed to
324b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * reduce interference with A2DP streaming.
325b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     *
326b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * @param isSet whether to enable or disable this mode
327b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * @return {@code true} if the command succeeded, {@code false} otherwise.
328b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     */
329fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
3301f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (setCoexScanMode) {
3311f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER BTCOEXSCAN-START");
3321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
3331f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER BTCOEXSCAN-STOP");
3341f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
3351f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3365ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
337fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean saveConfig() {
3381f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        // Make sure we never write out a value for AP_SCAN other than 1
3391f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("AP_SCAN 1") && doBooleanCommand("SAVE_CONFIG");
3401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3415876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff
342fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setScanResultHandling(int mode) {
3431f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("AP_SCAN " + mode);
3441f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
345ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
346fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean addToBlacklist(String bssid) {
3471f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (TextUtils.isEmpty(bssid)) return false;
3481f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("BLACKLIST " + bssid);
3491f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
350fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff
351fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean clearBlacklist() {
3521f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("BLACKLIST clear");
3531f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3542b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff
355fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setSuspendOptimizations(boolean enabled) {
3561f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (enabled) {
3571f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER SETSUSPENDOPT 0");
3581f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
3591f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER SETSUSPENDOPT 1");
3601f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
3611f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
36255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
363fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setCountryCode(String countryCode) {
3641f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER COUNTRY " + countryCode);
3651f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
36655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
367fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public void enableBackgroundScan(boolean enable) {
3681f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        //Note: BGSCAN-START and BGSCAN-STOP are documented in core/res/res/values/config.xml
3691f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        //and will need an update if the names are changed
3701f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (enable) {
3711f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            doBooleanCommand("DRIVER BGSCAN-START");
3721f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
3731f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            doBooleanCommand("DRIVER BGSCAN-STOP");
3741f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
3751f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
37655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
377fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public void setScanInterval(int scanInterval) {
3781f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        doBooleanCommand("SCAN_INTERVAL " + scanInterval);
3791f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
38055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
381921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff    /** Example output:
382921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * RSSI=-65
383921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * LINKSPEED=48
384921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * NOISE=9999
385921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * FREQUENCY=0
386921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     */
387fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String signalPoll() {
388921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        return doStringCommand("SIGNAL_POLL");
389921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff    }
390921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
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
399fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startWpsPinKeypad(String pin) {
40086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(pin)) return false;
4012b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("WPS_PIN any " + pin);
4022b8edd0c485f74067605c19983e3e7f44b20ec50repo sync    }
4032b8edd0c485f74067605c19983e3e7f44b20ec50repo sync
404fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String startWpsPinDisplay(String bssid) {
40586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(bssid)) {
40686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            return doStringCommand("WPS_PIN any");
40786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        } else {
40886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            return doStringCommand("WPS_PIN " + bssid);
40986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        }
4101f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
4111f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
4121f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /* Configures an access point connection */
413fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean startWpsRegistrar(String bssid, String pin) {
41486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false;
4151f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("WPS_REG " + bssid + " " + pin);
4161f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
4171f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
41886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    public boolean cancelWps() {
41986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        return doBooleanCommand("WPS_CANCEL");
42086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    }
42186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
422fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setPersistentReconnect(boolean enabled) {
4239322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        int value = (enabled == true) ? 1 : 0;
4241f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET persistent_reconnect " + value);
4259322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
4269322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
427fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setDeviceName(String name) {
4281f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET device_name " + name);
4299322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
4309322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
431fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setDeviceType(String type) {
4321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET device_type " + type);
4339322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
4349322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
435fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setConfigMethods(String cfg) {
4361f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET config_methods " + cfg);
437618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
438618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
439fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean setP2pSsidPostfix(String postfix) {
4401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
441530040e0b9458994c02f4392765db168128d48daIrfan Sheriff    }
442530040e0b9458994c02f4392765db168128d48daIrfan Sheriff
443fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pFind() {
4442b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_FIND");
44555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
44655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
447fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pFind(int timeout) {
44855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (timeout <= 0) {
44955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return p2pFind();
45055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
4512b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_FIND " + timeout);
45255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
45355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
4547d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    public boolean p2pStopFind() {
4557d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff       return doBooleanCommand("P2P_STOP_FIND");
4567d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    }
4577d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff
458fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pListen() {
4592b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_LISTEN");
46055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
46155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
462fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pListen(int timeout) {
46355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (timeout <= 0) {
46455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return p2pListen();
46555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
4662b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_LISTEN " + timeout);
46755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
46855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
469fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pFlush() {
4702b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_FLUSH");
47155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
47255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
47355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
47455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
475fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
47655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (config == null) return null;
47755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        List<String> args = new ArrayList<String>();
478651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        WpsInfo wps = config.wps;
47955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        args.add(config.deviceAddress);
48055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
4816f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff        switch (wps.setup) {
482651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.PBC:
48355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("pbc");
48455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
485651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.DISPLAY:
486618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                if (TextUtils.isEmpty(wps.pin)) {
487618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    args.add("pin");
488618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                } else {
489618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    args.add(wps.pin);
490618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                }
49155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("display");
49255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
493651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.KEYPAD:
4946f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff                args.add(wps.pin);
49555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("keypad");
49655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
497651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.LABEL:
4986f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff                args.add(wps.pin);
49955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("label");
50055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            default:
50155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
50255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
50355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
504f9cb1d7082870d9fc5f90290e717065441f611acIrfan Sheriff        //TODO: Add persist behavior once the supplicant interaction is fixed for both
505f9cb1d7082870d9fc5f90290e717065441f611acIrfan Sheriff        // group and client scenarios
506ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        /* Persist unless there is an explicit request to not do so*/
507f9cb1d7082870d9fc5f90290e717065441f611acIrfan Sheriff        //if (config.persist != WifiP2pConfig.Persist.NO) args.add("persistent");
508f9cb1d7082870d9fc5f90290e717065441f611acIrfan Sheriff
509ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (joinExistingGroup) args.add("join");
51055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
511bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        //TODO: This can be adapted based on device plugged in state and
512bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        //device battery state
5132b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        int groupOwnerIntent = config.groupOwnerIntent;
5142b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
515fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            groupOwnerIntent = DEFAULT_GROUP_OWNER_INTENT;
5162b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        }
5172b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        args.add("go_intent=" + groupOwnerIntent);
51855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
5192b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        String command = "P2P_CONNECT ";
52055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        for (String s : args) command += s + " ";
52155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
5222b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doStringCommand(command);
52355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
52455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
525fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pCancelConnect() {
526651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        return doBooleanCommand("P2P_CANCEL");
527651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
528651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
529fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pProvisionDiscovery(WifiP2pConfig config) {
530618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        if (config == null) return false;
531618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
532618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        switch (config.wps.setup) {
533618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.PBC:
534618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " pbc");
535618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.DISPLAY:
536618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                //We are doing display, so provision discovery is keypad
537618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " keypad");
538618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.KEYPAD:
539618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                //We are doing keypad, so provision discovery is display
540618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " display");
541618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            default:
542618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
543618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
544618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        return false;
545618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
546618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
547fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pGroupAdd() {
5482b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_GROUP_ADD");
54955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
55055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
551fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pGroupRemove(String iface) {
55286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(iface)) return false;
5532b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
55455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
55555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
556fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pReject(String deviceAddress) {
5572b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_REJECT " + deviceAddress);
55855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
55955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
56055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Invite a peer to a group */
561fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
56286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(deviceAddress)) return false;
563ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
564ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (group == null) {
565ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            return doBooleanCommand("P2P_INVITE peer=" + deviceAddress);
566ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        } else {
567ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
568ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
569ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        }
570ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
571ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
572ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /* Reinvoke a persistent connection */
573fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public boolean p2pReinvoke(int netId, String deviceAddress) {
57486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(deviceAddress) || netId < 0) return false;
575ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
576ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
57755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
5788c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
579ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
580fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String p2pGetInterfaceAddress(String deviceAddress) {
58186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(deviceAddress)) return null;
5828c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
5838c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        //  "p2p_peer deviceAddress" returns a multi-line result containing
5848c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        //      intended_addr=fa:7b:7a:42:82:13
5858c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        String peerInfo = p2pPeer(deviceAddress);
58686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        if (TextUtils.isEmpty(peerInfo)) return null;
5878c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        String[] tokens= peerInfo.split("\n");
5888c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
5898c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        for (String token : tokens) {
5908c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            //TODO: update from interface_addr when wpa_supplicant implementation is fixed
5918c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            if (token.startsWith("intended_addr=")) {
5928c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                String[] nameValue = token.split("=");
5938c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                if (nameValue.length != 2) break;
5948c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                return nameValue[1];
5958c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            }
5968c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        }
5978c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        return null;
5988c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    }
5998c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
600fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String p2pGetDeviceAddress() {
6011f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String status = status();
6024be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        if (status == null) return "";
6034be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
6044be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        String[] tokens = status.split("\n");
6054be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        for (String token : tokens) {
6064be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            if (token.startsWith("p2p_device_address=")) {
6074be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                String[] nameValue = token.split("=");
6084be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                if (nameValue.length != 2) break;
6094be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                return nameValue[1];
6104be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            }
6114be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        }
6124be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        return "";
6134be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    }
6144be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
615fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String p2pPeer(String deviceAddress) {
6168c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        return doStringCommand("P2P_PEER " + deviceAddress);
6178c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    }
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
619