WifiNative.java revision 1f095869536472c178046bb63c59947508eac4a6
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;
22618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.text.TextUtils;
2355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.util.Log;
2455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.io.InputStream;
2655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.lang.Process;
2755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.ArrayList;
2855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.List;
2955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
311f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * Native calls for bring up/shut down of the supplicant daemon and for
321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * sending requests to the supplicant daemon
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
341f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * waitForEvent() is called on the monitor thread for events. All other methods
351f095869536472c178046bb63c59947508eac4a6Irfan Sheriff * must be serialized from the framework.
3655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class WifiNative {
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED = 0;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int BLUETOOTH_COEXISTENCE_MODE_SENSE = 2;
445d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean loadDriver();
46a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff
47a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff    public native static boolean isDriverLoaded();
485d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean unloadDriver();
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean startSupplicant();
525d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
53f42c39b3d188ebb3ba9003cffc530717829fe874Irfan Sheriff    public native static boolean startP2pSupplicant();
54f42c39b3d188ebb3ba9003cffc530717829fe874Irfan Sheriff
555d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff    /* Sends a kill signal to supplicant. To be used when we have lost connection
565d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff       or when the supplicant is hung */
5796071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff    public native static boolean killSupplicant();
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean connectToSupplicant();
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static void closeSupplicantConnection();
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
631f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /**
641f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * Wait for the supplicant to send an event, returning the event string.
651f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * @return the event string sent by the supplicant.
661f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     */
671f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public native static String waitForEvent();
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
691f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    private native static boolean doBooleanCommand(String command);
705d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
711f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    private native static int doIntCommand(String command);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
731f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    private native static String doStringCommand(String command);
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
751f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean ping() {
761f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String pong = doStringCommand("PING");
771f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return (pong != null && pong.equals("PONG"));
781f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
801f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean scan() {
811f095869536472c178046bb63c59947508eac4a6Irfan Sheriff       return doBooleanCommand("SCAN");
821f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
841f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean setScanMode(boolean setActive) {
851f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (setActive) {
861f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER SCAN-ACTIVE");
871f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
881f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER SCAN-PASSIVE");
891f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
901f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
921f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /* Does a graceful shutdown of supplicant. Is a common stop function for both p2p and sta.
931f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
941f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * Note that underneath we use a harsh-sounding "terminate" supplicant command
951f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * for a graceful stop and a mild-sounding "stop" interface
961f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * to kill the process
971f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     */
981f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean stopSupplicant() {
991f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("TERMINATE");
1001f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1021f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static String listNetworks() {
1031f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("LIST_NETWORKS");
1041f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1055d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff
1061f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static int addNetwork() {
1071f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doIntCommand("ADD_NETWORK");
1081f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1101f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean setNetworkVariable(int netId, String name, String value) {
1111f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(value)) return false;
1121f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value);
1131f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1151f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static String getNetworkVariable(int netId, String name) {
1161f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (TextUtils.isEmpty(name)) return null;
1171f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("GET_NETWORK " + netId + " " + name);
1181f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1201f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean removeNetwork(int netId) {
1211f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("REMOVE_NETWORK " + netId);
1221f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
12396071a7031bac06e3f249610b010ad5651efe8aeIrfan Sheriff
1241f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean enableNetwork(int netId, boolean disableOthers) {
1251f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (disableOthers) {
1261f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("SELECT_NETWORK " + netId);
1271f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
1281f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("ENABLE_NETWORK " + netId);
1291f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
1301f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean disableNetwork(int netId) {
1331f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DISABLE_NETWORK " + netId);
1341f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1361f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean reconnect() {
1371f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("RECONNECT");
1381f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean reassociate() {
1411f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("REASSOCIATE");
1421f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1441f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean disconnect() {
1451f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DISCONNECT");
1461f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1471f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
1481f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static String status() {
1491f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("STATUS");
1501f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1511f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
1521f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static String getMacAddress() {
1531f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        //Macaddr = XX.XX.XX.XX.XX.XX
1541f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String ret = doStringCommand("DRIVER MACADDR");
1551f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (!TextUtils.isEmpty(ret)) {
1561f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            String[] tokens = ret.split(" = ");
1571f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            if (tokens.length == 2) return tokens[1];
1581f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
1591f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return null;
1601f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1611f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
1621f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static String scanResults() {
1631f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("SCAN_RESULTS");
1641f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1651f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
1661f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean startDriver() {
1671f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER START");
1681f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1691f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
1701f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean stopDriver() {
1711f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER STOP");
1721f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
174b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
175b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /**
176b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Start filtering out Multicast V4 packets
177b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * @return {@code true} if the operation succeeded, {@code false} otherwise
1781f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
1791f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * Multicast filtering rules work as follows:
1801f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
1811f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
1821f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * a power optimized mode (typically when screen goes off).
1831f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
1841f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
1851f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
1861f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
1871f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * DRIVER RXFILTER-ADD Num
1881f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
1891f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
1901f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * and DRIVER RXFILTER-START
1911f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * In order to stop the usage of these rules, we do
1921f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
1931f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * DRIVER RXFILTER-STOP
1941f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * DRIVER RXFILTER-REMOVE Num
1951f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *   where Num is as described for RXFILTER-ADD
1961f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     *
1971f095869536472c178046bb63c59947508eac4a6Irfan Sheriff     * The  SETSUSPENDOPT driver command overrides the filtering rules
198b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     */
1991f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean startFilteringMulticastV4Packets() {
2001f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2011f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-REMOVE 2")
2021f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2031f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
204b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
205b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff    /**
206b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Stop filtering out Multicast V4 packets.
207b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * @return {@code true} if the operation succeeded, {@code false} otherwise
208b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     */
2091f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean stopFilteringMulticastV4Packets() {
2101f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2111f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-ADD 2")
2121f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2131f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
214b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
216b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Start filtering out Multicast V6 packets
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} if the operation succeeded, {@code false} otherwise
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2191f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean startFilteringMulticastV6Packets() {
2201f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2211f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-REMOVE 3")
2221f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2231f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
226b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff     * Stop filtering out Multicast V6 packets.
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} if the operation succeeded, {@code false} otherwise
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2291f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean stopFilteringMulticastV6Packets() {
2301f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER RXFILTER-STOP")
2311f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-ADD 3")
2321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            && doBooleanCommand("DRIVER RXFILTER-START");
2331f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2351f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static int getPowerMode() {
2361f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String ret = doStringCommand("DRIVER GETPOWER");
2371f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (!TextUtils.isEmpty(ret)) {
2381f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            // reply comes back in the form "powermode = XX" where XX is the
2391f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            // number we're interested in.
2401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            String[] tokens = ret.split(" = ");
2411f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            try {
2421f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                if (tokens.length == 2) return Integer.parseInt(tokens[1]);
2431f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            } catch (NumberFormatException e) {
2441f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                return -1;
2451f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            }
2461f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
2471f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return -1;
2481f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2501f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean setPowerMode(int mode) {
2511f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER POWERMODE " + mode);
2521f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
25325c9bf2396ceb48fc5cfd5c1dd58aa4d4750d056Irfan Sheriff
2541f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static int getBand() {
2551f095869536472c178046bb63c59947508eac4a6Irfan Sheriff       String ret = doStringCommand("DRIVER GETBAND");
2561f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (!TextUtils.isEmpty(ret)) {
2571f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            //reply is "BAND X" where X is the band
2581f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            String[] tokens = ret.split(" ");
2591f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            try {
2601f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                if (tokens.length == 2) return Integer.parseInt(tokens[1]);
2611f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            } catch (NumberFormatException e) {
2621f095869536472c178046bb63c59947508eac4a6Irfan Sheriff                return -1;
2631f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            }
2641f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
2651f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return -1;
2661f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
26725c9bf2396ceb48fc5cfd5c1dd58aa4d4750d056Irfan Sheriff
2681f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean setBand(int band) {
2691f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER SETBAND " + band);
2701f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
271ea8bd1d1676dd96f8f9726bb8f67fa18dec7b9c1Mikael Kanstrup
2721f095869536472c178046bb63c59947508eac4a6Irfan Sheriff   /**
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the bluetooth coexistence mode.
2745d001ea0271eeedb05984ac00d5e41d767f0cb87Irfan Sheriff     *
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Whether the mode was successfully set.
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2801f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean setBluetoothCoexistenceMode(int mode) {
2811f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
2821f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
283b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project
284b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    /**
285b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
286b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * some of the low-level scan parameters used by the driver are changed to
287b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * reduce interference with A2DP streaming.
288b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     *
289b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * @param isSet whether to enable or disable this mode
290b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * @return {@code true} if the command succeeded, {@code false} otherwise.
291b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     */
2921f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
2931f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (setCoexScanMode) {
2941f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER BTCOEXSCAN-START");
2951f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
2961f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER BTCOEXSCAN-STOP");
2971f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
2981f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
2995ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
3001f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean saveConfig() {
3011f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        // Make sure we never write out a value for AP_SCAN other than 1
3021f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("AP_SCAN 1") && doBooleanCommand("SAVE_CONFIG");
3031f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3045876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff
3051f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean setScanResultHandling(int mode) {
3061f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("AP_SCAN " + mode);
3071f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
308ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff
3091f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean addToBlacklist(String bssid) {
3101f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (TextUtils.isEmpty(bssid)) return false;
3111f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("BLACKLIST " + bssid);
3121f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
313fcc0845cf9990470d498dcaa036f0ae6487ddf34Irfan Sheriff
3141f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean clearBlacklist() {
3151f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("BLACKLIST clear");
3161f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3172b7f63887e39079a52592fb4507d8daaf90e8afaIrfan Sheriff
3181f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean setSuspendOptimizations(boolean enabled) {
3191f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (enabled) {
3201f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER SETSUSPENDOPT 0");
3211f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
3221f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            return doBooleanCommand("DRIVER SETSUSPENDOPT 1");
3231f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
3241f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
32555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
3261f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean setCountryCode(String countryCode) {
3271f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("DRIVER COUNTRY " + countryCode);
3281f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
32955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
3301f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static void enableBackgroundScan(boolean enable) {
3311f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        //Note: BGSCAN-START and BGSCAN-STOP are documented in core/res/res/values/config.xml
3321f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        //and will need an update if the names are changed
3331f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        if (enable) {
3341f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            doBooleanCommand("DRIVER BGSCAN-START");
3351f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        } else {
3361f095869536472c178046bb63c59947508eac4a6Irfan Sheriff            doBooleanCommand("DRIVER BGSCAN-STOP");
3371f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        }
3381f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
33955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
3401f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static void setScanInterval(int scanInterval) {
3411f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        doBooleanCommand("SCAN_INTERVAL " + scanInterval);
3421f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
34355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
344921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff    /** Example output:
345921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * RSSI=-65
346921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * LINKSPEED=48
347921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * NOISE=9999
348921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     * FREQUENCY=0
349921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff     */
350921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff    public static String signalPoll() {
351921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff        return doStringCommand("SIGNAL_POLL");
352921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff    }
353921df5cbc44c00abe85f04093afe7692e73d490aIrfan Sheriff
3541f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean startWpsPbc() {
3552b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("WPS_PBC");
3562b8edd0c485f74067605c19983e3e7f44b20ec50repo sync    }
3572b8edd0c485f74067605c19983e3e7f44b20ec50repo sync
3581f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean startWpsPbc(String bssid) {
3591f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("WPS_PBC " + bssid);
3601f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3611f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
3621f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean startWpsPinKeypad(String pin) {
3632b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("WPS_PIN any " + pin);
3642b8edd0c485f74067605c19983e3e7f44b20ec50repo sync    }
3652b8edd0c485f74067605c19983e3e7f44b20ec50repo sync
3661f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static String startWpsPinDisplay(String bssid) {
3671f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doStringCommand("WPS_PIN " + bssid);
3681f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3691f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
3701f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    /* Configures an access point connection */
3711f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    public static boolean startWpsRegistrar(String bssid, String pin) {
3721f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("WPS_REG " + bssid + " " + pin);
3731f095869536472c178046bb63c59947508eac4a6Irfan Sheriff    }
3741f095869536472c178046bb63c59947508eac4a6Irfan Sheriff
3759322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    public static boolean setPersistentReconnect(boolean enabled) {
3769322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        int value = (enabled == true) ? 1 : 0;
3771f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET persistent_reconnect " + value);
3789322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
3799322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
3809322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    public static boolean setDeviceName(String name) {
3811f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET device_name " + name);
3829322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
3839322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
3849322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    public static boolean setDeviceType(String type) {
3851f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET device_type " + type);
3869322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
3879322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
388618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static boolean setConfigMethods(String cfg) {
3891f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET config_methods " + cfg);
390618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
391618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
392530040e0b9458994c02f4392765db168128d48daIrfan Sheriff    public static boolean setP2pSsidPostfix(String postfix) {
3931f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
394530040e0b9458994c02f4392765db168128d48daIrfan Sheriff    }
395530040e0b9458994c02f4392765db168128d48daIrfan Sheriff
39655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static boolean p2pFind() {
3972b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_FIND");
39855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
39955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
40055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static boolean p2pFind(int timeout) {
40155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (timeout <= 0) {
40255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return p2pFind();
40355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
4042b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_FIND " + timeout);
40555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
40655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
40755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static boolean p2pListen() {
4082b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_LISTEN");
40955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
41055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
41155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static boolean p2pListen(int timeout) {
41255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (timeout <= 0) {
41355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return p2pListen();
41455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
4152b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_LISTEN " + timeout);
41655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
41755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
41855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static boolean p2pFlush() {
4192b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_FLUSH");
42055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
42155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
42255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
42355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
424ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    public static String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
42555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (config == null) return null;
42655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        List<String> args = new ArrayList<String>();
427651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        WpsInfo wps = config.wps;
42855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        args.add(config.deviceAddress);
42955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
4306f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff        switch (wps.setup) {
431651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.PBC:
43255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("pbc");
43355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
434651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.DISPLAY:
435618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                if (TextUtils.isEmpty(wps.pin)) {
436618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    args.add("pin");
437618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                } else {
438618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    args.add(wps.pin);
439618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                }
44055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("display");
44155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
442651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.KEYPAD:
4436f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff                args.add(wps.pin);
44455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("keypad");
44555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
446651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            case WpsInfo.LABEL:
4476f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff                args.add(wps.pin);
44855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                args.add("label");
44955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            default:
45055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                break;
45155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
45255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
453f9cb1d7082870d9fc5f90290e717065441f611acIrfan Sheriff        //TODO: Add persist behavior once the supplicant interaction is fixed for both
454f9cb1d7082870d9fc5f90290e717065441f611acIrfan Sheriff        // group and client scenarios
455ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        /* Persist unless there is an explicit request to not do so*/
456f9cb1d7082870d9fc5f90290e717065441f611acIrfan Sheriff        //if (config.persist != WifiP2pConfig.Persist.NO) args.add("persistent");
457f9cb1d7082870d9fc5f90290e717065441f611acIrfan Sheriff
458ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (joinExistingGroup) args.add("join");
45955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
460bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        //TODO: This can be adapted based on device plugged in state and
461bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        //device battery state
4622b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        int groupOwnerIntent = config.groupOwnerIntent;
4632b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
464bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            groupOwnerIntent = 7; //default value
4652b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        }
4662b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        args.add("go_intent=" + groupOwnerIntent);
46755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
4682b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        String command = "P2P_CONNECT ";
46955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        for (String s : args) command += s + " ";
47055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
4712b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doStringCommand(command);
47255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
47355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
474651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    public static boolean p2pCancelConnect() {
475651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        return doBooleanCommand("P2P_CANCEL");
476651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
477651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
478618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static boolean p2pProvisionDiscovery(WifiP2pConfig config) {
479618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        if (config == null) return false;
480618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
481618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        switch (config.wps.setup) {
482618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.PBC:
483618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " pbc");
484618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.DISPLAY:
485618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                //We are doing display, so provision discovery is keypad
486618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " keypad");
487618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.KEYPAD:
488618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                //We are doing keypad, so provision discovery is display
489618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " display");
490618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            default:
491618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
492618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
493618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        return false;
494618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
495618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
49655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static boolean p2pGroupAdd() {
4972b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_GROUP_ADD");
49855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
49955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
50055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static boolean p2pGroupRemove(String iface) {
50155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (iface == null) return false;
5022b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
50355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
50455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
50555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static boolean p2pReject(String deviceAddress) {
5062b8edd0c485f74067605c19983e3e7f44b20ec50repo sync        return doBooleanCommand("P2P_REJECT " + deviceAddress);
50755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
50855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
50955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Invite a peer to a group */
51055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
511ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (deviceAddress == null) return false;
512ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
513ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (group == null) {
514ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            return doBooleanCommand("P2P_INVITE peer=" + deviceAddress);
515ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        } else {
516ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
517ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
518ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        }
519ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
520ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
521ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /* Reinvoke a persistent connection */
522ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    public static boolean p2pReinvoke(int netId, String deviceAddress) {
523ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (deviceAddress == null || netId < 0) return false;
524ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
525ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
52655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
5278c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
528ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
5298c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    public static String p2pGetInterfaceAddress(String deviceAddress) {
5308c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        if (deviceAddress == null) return null;
5318c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
5328c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        //  "p2p_peer deviceAddress" returns a multi-line result containing
5338c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        //      intended_addr=fa:7b:7a:42:82:13
5348c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        String peerInfo = p2pPeer(deviceAddress);
5358c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        if (peerInfo == null) return null;
5368c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        String[] tokens= peerInfo.split("\n");
5378c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
5388c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        for (String token : tokens) {
5398c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            //TODO: update from interface_addr when wpa_supplicant implementation is fixed
5408c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            if (token.startsWith("intended_addr=")) {
5418c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                String[] nameValue = token.split("=");
5428c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                if (nameValue.length != 2) break;
5438c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                return nameValue[1];
5448c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            }
5458c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        }
5468c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        return null;
5478c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    }
5488c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
5494be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    public static String p2pGetDeviceAddress() {
5501f095869536472c178046bb63c59947508eac4a6Irfan Sheriff        String status = status();
5514be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        if (status == null) return "";
5524be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
5534be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        String[] tokens = status.split("\n");
5544be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        for (String token : tokens) {
5554be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            if (token.startsWith("p2p_device_address=")) {
5564be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                String[] nameValue = token.split("=");
5574be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                if (nameValue.length != 2) break;
5584be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                return nameValue[1];
5594be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            }
5604be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        }
5614be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        return "";
5624be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    }
5634be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
5648c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    public static String p2pPeer(String deviceAddress) {
5658c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        return doStringCommand("P2P_PEER " + deviceAddress);
5668c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    }
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
568