blob: 49c6d7df5c7e30bcc0a2fd5c818c7ab55c95020d [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Vinit Deshapndeffadfb92013-12-06 15:12:41 -080017package com.android.server.wifi;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Vinit Deshapndeffadfb92013-12-06 15:12:41 -080019import android.net.wifi.BatchedScanSettings;
20import android.net.wifi.WpsInfo;
repo sync55bc5f32011-06-24 14:23:07 -070021import android.net.wifi.p2p.WifiP2pConfig;
22import android.net.wifi.p2p.WifiP2pGroup;
Irfan Sheriff618455f2011-11-18 14:33:09 -080023import android.text.TextUtils;
Irfan Sheriff21ba8152012-04-04 16:22:21 -070024import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
Vinit Deshapndee8fabf92013-08-23 11:53:40 -070025import android.util.LocalLog;
repo sync55bc5f32011-06-24 14:23:07 -070026import android.util.Log;
27
repo sync55bc5f32011-06-24 14:23:07 -070028import java.util.ArrayList;
29import java.util.List;
Vinit Deshapnde2c385ec2013-09-09 16:28:31 -070030import java.util.Locale;
repo sync55bc5f32011-06-24 14:23:07 -070031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032/**
Irfan Sheriff1f095862011-12-21 12:14:05 -080033 * Native calls for bring up/shut down of the supplicant daemon and for
34 * sending requests to the supplicant daemon
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035 *
Irfan Sheriff1f095862011-12-21 12:14:05 -080036 * waitForEvent() is called on the monitor thread for events. All other methods
37 * must be serialized from the framework.
repo sync55bc5f32011-06-24 14:23:07 -070038 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039 * {@hide}
40 */
41public class WifiNative {
42
Irfan Sheriff7d6d9c02012-01-10 15:50:45 -080043 private static final boolean DBG = false;
44 private final String mTAG;
Irfan Sheriffbcc97ca2013-02-21 14:15:18 -080045 private static final int DEFAULT_GROUP_OWNER_INTENT = 6;
Irfan Sherifffc7f95a2012-01-04 14:50:09 -080046
Irfan Sheriffbcc97ca2013-02-21 14:15:18 -080047 static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED = 0;
48 static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
49 static final int BLUETOOTH_COEXISTENCE_MODE_SENSE = 2;
50
51 static final int SCAN_WITHOUT_CONNECTION_SETUP = 1;
52 static final int SCAN_WITH_CONNECTION_SETUP = 2;
Irfan Sheriff5d001ea2010-12-15 10:29:49 -080053
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -070054 // Hold this lock before calling supplicant - it is required to
55 // mutually exclude access from Wifi and P2p state machines
56 static final Object mLock = new Object();
57
Vinit Deshapndec249c2c2013-08-08 10:38:53 -070058 public final String mInterfaceName;
59 public final String mInterfacePrefix;
60
Irfan Sheriff633fe602012-09-14 14:35:44 -070061 private boolean mSuspendOptEnabled = false;
Irfan Sheriff44b330d2011-12-28 13:00:28 -080062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 public native static boolean loadDriver();
Irfan Sheriffa2a1b912010-06-07 09:03:04 -070064
65 public native static boolean isDriverLoaded();
Irfan Sheriff5d001ea2010-12-15 10:29:49 -080066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 public native static boolean unloadDriver();
68
Irfan Sheriff7d6d9c02012-01-10 15:50:45 -080069 public native static boolean startSupplicant(boolean p2pSupported);
Irfan Sherifff42c39b2011-08-26 14:45:23 -070070
Irfan Sheriff5d001ea2010-12-15 10:29:49 -080071 /* Sends a kill signal to supplicant. To be used when we have lost connection
72 or when the supplicant is hung */
Irfan Sheriff511d5342012-11-03 23:20:38 -070073 public native static boolean killSupplicant(boolean p2pSupported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
Vinit Deshapndec249c2c2013-08-08 10:38:53 -070075 private native boolean connectToSupplicantNative();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
Vinit Deshapndec249c2c2013-08-08 10:38:53 -070077 private native void closeSupplicantConnectionNative();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078
Irfan Sheriff1f095862011-12-21 12:14:05 -080079 /**
80 * Wait for the supplicant to send an event, returning the event string.
81 * @return the event string sent by the supplicant.
82 */
Vinit Deshapndec249c2c2013-08-08 10:38:53 -070083 private native String waitForEventNative();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084
Vinit Deshapndec249c2c2013-08-08 10:38:53 -070085 private native boolean doBooleanCommandNative(String command);
Irfan Sheriff5d001ea2010-12-15 10:29:49 -080086
Vinit Deshapndec249c2c2013-08-08 10:38:53 -070087 private native int doIntCommandNative(String command);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
Vinit Deshapndec249c2c2013-08-08 10:38:53 -070089 private native String doStringCommandNative(String command);
Irfan Sheriff44b330d2011-12-28 13:00:28 -080090
Vinit Deshapndec249c2c2013-08-08 10:38:53 -070091 public WifiNative(String interfaceName) {
92 mInterfaceName = interfaceName;
Vinit Deshapndec249c2c2013-08-08 10:38:53 -070093 mTAG = "WifiNative-" + interfaceName;
Dmitry Shmidt2de3a572013-08-14 12:59:23 -070094 if (!interfaceName.equals("p2p0")) {
95 mInterfacePrefix = "IFNAME=" + interfaceName + " ";
96 } else {
97 // commands for p2p0 interface don't need prefix
98 mInterfacePrefix = "";
99 }
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800100 }
101
Vinit Deshapnde48c47472013-08-28 13:13:40 -0700102 private static final LocalLog mLocalLog = new LocalLog(1024);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700103
104 // hold mLock before accessing mCmdIdLock
Vinit Deshapnde48c47472013-08-28 13:13:40 -0700105 private int mCmdId;
Vinit Deshapndee8fabf92013-08-23 11:53:40 -0700106
Vinit Deshapnde48c47472013-08-28 13:13:40 -0700107 public LocalLog getLocalLog() {
108 return mLocalLog;
109 }
110
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700111 private int getNewCmdIdLocked() {
112 return mCmdId++;
Vinit Deshapndee8fabf92013-08-23 11:53:40 -0700113 }
114
115 private void localLog(String s) {
116 if (mLocalLog != null)
117 mLocalLog.log(mInterfaceName + ": " + s);
118 }
119
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800120 public boolean connectToSupplicant() {
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700121 // No synchronization necessary .. it is implemented in WifiMonitor
Robert Greenwalta029ea12013-09-25 16:38:12 -0700122 localLog(mInterfacePrefix + "connectToSupplicant");
Vinit Deshapndec249c2c2013-08-08 10:38:53 -0700123 return connectToSupplicantNative();
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800124 }
125
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800126 public void closeSupplicantConnection() {
Robert Greenwalta029ea12013-09-25 16:38:12 -0700127 localLog(mInterfacePrefix + "closeSupplicantConnection");
Vinit Deshapndec249c2c2013-08-08 10:38:53 -0700128 closeSupplicantConnectionNative();
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800129 }
130
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800131 public String waitForEvent() {
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700132 // No synchronization necessary .. it is implemented in WifiMonitor
Vinit Deshapndec249c2c2013-08-08 10:38:53 -0700133 return waitForEventNative();
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800134 }
135
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800136 private boolean doBooleanCommand(String command) {
Irfan Sheriff7d6d9c02012-01-10 15:50:45 -0800137 if (DBG) Log.d(mTAG, "doBoolean: " + command);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700138 synchronized (mLock) {
139 int cmdId = getNewCmdIdLocked();
Robert Greenwalta029ea12013-09-25 16:38:12 -0700140 localLog(cmdId + "->" + mInterfacePrefix + command);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700141 boolean result = doBooleanCommandNative(mInterfacePrefix + command);
Robert Greenwalta029ea12013-09-25 16:38:12 -0700142 localLog(cmdId + "<-" + result);
Robert Greenwalt126755c2013-09-05 18:32:12 -0700143 if (DBG) Log.d(mTAG, " returned " + result);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700144 return result;
145 }
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800146 }
147
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800148 private int doIntCommand(String command) {
Irfan Sheriff7d6d9c02012-01-10 15:50:45 -0800149 if (DBG) Log.d(mTAG, "doInt: " + command);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700150 synchronized (mLock) {
151 int cmdId = getNewCmdIdLocked();
Robert Greenwalta029ea12013-09-25 16:38:12 -0700152 localLog(cmdId + "->" + mInterfacePrefix + command);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700153 int result = doIntCommandNative(mInterfacePrefix + command);
Robert Greenwalta029ea12013-09-25 16:38:12 -0700154 localLog(cmdId + "<-" + result);
Robert Greenwalt126755c2013-09-05 18:32:12 -0700155 if (DBG) Log.d(mTAG, " returned " + result);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700156 return result;
157 }
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800158 }
159
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800160 private String doStringCommand(String command) {
Irfan Sheriff7d6d9c02012-01-10 15:50:45 -0800161 if (DBG) Log.d(mTAG, "doString: " + command);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700162 synchronized (mLock) {
163 int cmdId = getNewCmdIdLocked();
Robert Greenwalta029ea12013-09-25 16:38:12 -0700164 localLog(cmdId + "->" + mInterfacePrefix + command);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700165 String result = doStringCommandNative(mInterfacePrefix + command);
Robert Greenwalta029ea12013-09-25 16:38:12 -0700166 localLog(cmdId + "<-" + result);
Robert Greenwalt126755c2013-09-05 18:32:12 -0700167 if (DBG) Log.d(mTAG, " returned " + result);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700168 return result;
169 }
Vinit Deshapnde48c47472013-08-28 13:13:40 -0700170 }
171
172 private String doStringCommandWithoutLogging(String command) {
173 if (DBG) Log.d(mTAG, "doString: " + command);
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700174 synchronized (mLock) {
175 return doStringCommandNative(mInterfacePrefix + command);
176 }
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800179 public boolean ping() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800180 String pong = doStringCommand("PING");
181 return (pong != null && pong.equals("PONG"));
182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183
Irfan Sheriffbcc97ca2013-02-21 14:15:18 -0800184 public boolean scan(int type) {
185 if (type == SCAN_WITHOUT_CONNECTION_SETUP) {
186 return doBooleanCommand("SCAN TYPE=ONLY");
187 } else if (type == SCAN_WITH_CONNECTION_SETUP) {
188 return doBooleanCommand("SCAN");
Irfan Sheriff1f095862011-12-21 12:14:05 -0800189 } else {
Irfan Sheriffbcc97ca2013-02-21 14:15:18 -0800190 throw new IllegalArgumentException("Invalid scan type");
Irfan Sheriff1f095862011-12-21 12:14:05 -0800191 }
192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
Irfan Sheriff1f095862011-12-21 12:14:05 -0800194 /* Does a graceful shutdown of supplicant. Is a common stop function for both p2p and sta.
195 *
196 * Note that underneath we use a harsh-sounding "terminate" supplicant command
197 * for a graceful stop and a mild-sounding "stop" interface
198 * to kill the process
199 */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800200 public boolean stopSupplicant() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800201 return doBooleanCommand("TERMINATE");
202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800204 public String listNetworks() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800205 return doStringCommand("LIST_NETWORKS");
206 }
Irfan Sheriff5d001ea2010-12-15 10:29:49 -0800207
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800208 public int addNetwork() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800209 return doIntCommand("ADD_NETWORK");
210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800212 public boolean setNetworkVariable(int netId, String name, String value) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800213 if (TextUtils.isEmpty(name) || TextUtils.isEmpty(value)) return false;
214 return doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value);
215 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800217 public String getNetworkVariable(int netId, String name) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800218 if (TextUtils.isEmpty(name)) return null;
Vinit Deshapnde48c47472013-08-28 13:13:40 -0700219
220 // GET_NETWORK will likely flood the logs ...
221 return doStringCommandWithoutLogging("GET_NETWORK " + netId + " " + name);
Irfan Sheriff1f095862011-12-21 12:14:05 -0800222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800224 public boolean removeNetwork(int netId) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800225 return doBooleanCommand("REMOVE_NETWORK " + netId);
226 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800228 public boolean enableNetwork(int netId, boolean disableOthers) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800229 if (disableOthers) {
230 return doBooleanCommand("SELECT_NETWORK " + netId);
231 } else {
232 return doBooleanCommand("ENABLE_NETWORK " + netId);
233 }
234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800236 public boolean disableNetwork(int netId) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800237 return doBooleanCommand("DISABLE_NETWORK " + netId);
238 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800240 public boolean reconnect() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800241 return doBooleanCommand("RECONNECT");
242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800244 public boolean reassociate() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800245 return doBooleanCommand("REASSOCIATE");
246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800248 public boolean disconnect() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800249 return doBooleanCommand("DISCONNECT");
250 }
251
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800252 public String status() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800253 return doStringCommand("STATUS");
254 }
255
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800256 public String getMacAddress() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800257 //Macaddr = XX.XX.XX.XX.XX.XX
258 String ret = doStringCommand("DRIVER MACADDR");
259 if (!TextUtils.isEmpty(ret)) {
260 String[] tokens = ret.split(" = ");
261 if (tokens.length == 2) return tokens[1];
262 }
263 return null;
264 }
265
Iliyan Malchev06c43d52012-08-20 12:52:35 -0700266 /**
267 * Format of results:
268 * =================
Iliyan Malchev9233fc02013-06-21 03:09:44 +0000269 * id=1
Iliyan Malchev06c43d52012-08-20 12:52:35 -0700270 * bssid=68:7f:74:d7:1b:6e
271 * freq=2412
272 * level=-43
273 * tsf=1344621975160944
274 * age=2623
275 * flags=[WPA2-PSK-CCMP][WPS][ESS]
276 * ssid=zubyb
Dmitry Shmidt14b628a2013-03-01 09:37:00 -0800277 * ====
Iliyan Malchev06c43d52012-08-20 12:52:35 -0700278 *
279 * RANGE=ALL gets all scan results
Iliyan Malchev9233fc02013-06-21 03:09:44 +0000280 * RANGE=ID- gets results from ID
Iliyan Malchev06c43d52012-08-20 12:52:35 -0700281 * MASK=<N> see wpa_supplicant/src/common/wpa_ctrl.h for details
282 */
Iliyan Malchev9233fc02013-06-21 03:09:44 +0000283 public String scanResults(int sid) {
Vinit Deshapnde48c47472013-08-28 13:13:40 -0700284 return doStringCommandWithoutLogging("BSS RANGE=" + sid + "- MASK=0x21987");
Irfan Sheriff1f095862011-12-21 12:14:05 -0800285 }
286
Robert Greenwalt0451d592013-08-01 18:24:13 -0700287 /**
288 * Format of command
Robert Greenwalt126755c2013-09-05 18:32:12 -0700289 * DRIVER WLS_BATCHING SET SCANFREQ=x MSCAN=r BESTN=y CHANNEL=<z, w, t> RTT=s
Robert Greenwalt0451d592013-08-01 18:24:13 -0700290 * where x is an ascii representation of an integer number of seconds between scans
Robert Greenwalt8e628da2013-08-14 16:07:44 -0700291 * r is an ascii representation of an integer number of scans per batch
Robert Greenwalt0451d592013-08-01 18:24:13 -0700292 * y is an ascii representation of an integer number of the max AP to remember per scan
293 * z, w, t represent a 1..n size list of channel numbers and/or 'A', 'B' values
294 * indicating entire ranges of channels
295 * s is an ascii representation of an integer number of highest-strength AP
296 * for which we'd like approximate distance reported
297 *
298 * The return value is an ascii integer representing a guess of the number of scans
299 * the firmware can remember before it runs out of buffer space or -1 on error
300 */
301 public String setBatchedScanSettings(BatchedScanSettings settings) {
Robert Greenwalta029ea12013-09-25 16:38:12 -0700302 if (settings == null) {
303 return doStringCommand("DRIVER WLS_BATCHING STOP");
304 }
Robert Greenwalt126755c2013-09-05 18:32:12 -0700305 String cmd = "DRIVER WLS_BATCHING SET SCANFREQ=" + settings.scanIntervalSec;
Robert Greenwalt8e628da2013-08-14 16:07:44 -0700306 cmd += " MSCAN=" + settings.maxScansPerBatch;
Robert Greenwalt0451d592013-08-01 18:24:13 -0700307 if (settings.maxApPerScan != BatchedScanSettings.UNSPECIFIED) {
Robert Greenwalt8e628da2013-08-14 16:07:44 -0700308 cmd += " BESTN=" + settings.maxApPerScan;
Robert Greenwalt0451d592013-08-01 18:24:13 -0700309 }
310 if (settings.channelSet != null && !settings.channelSet.isEmpty()) {
311 cmd += " CHANNEL=<";
Sreeram Ramachandran268f3292013-08-27 14:49:23 -0700312 int i = 0;
313 for (String channel : settings.channelSet) {
314 cmd += (i > 0 ? "," : "") + channel;
315 ++i;
316 }
Robert Greenwalt0451d592013-08-01 18:24:13 -0700317 cmd += ">";
318 }
319 if (settings.maxApForDistance != BatchedScanSettings.UNSPECIFIED) {
320 cmd += " RTT=" + settings.maxApForDistance;
321 }
322 return doStringCommand(cmd);
323 }
324
325 public String getBatchedScanResults() {
326 return doStringCommand("DRIVER WLS_BATCHING GET");
327 }
328
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800329 public boolean startDriver() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800330 return doBooleanCommand("DRIVER START");
331 }
332
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800333 public boolean stopDriver() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800334 return doBooleanCommand("DRIVER STOP");
335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337
338 /**
Irfan Sheriffb0c1b80f2011-07-19 15:44:25 -0700339 * Start filtering out Multicast V4 packets
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 * @return {@code true} if the operation succeeded, {@code false} otherwise
Irfan Sheriff1f095862011-12-21 12:14:05 -0800341 *
342 * Multicast filtering rules work as follows:
343 *
344 * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
345 * a power optimized mode (typically when screen goes off).
346 *
347 * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
348 * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
349 *
350 * DRIVER RXFILTER-ADD Num
351 * where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
352 *
353 * and DRIVER RXFILTER-START
354 * In order to stop the usage of these rules, we do
355 *
356 * DRIVER RXFILTER-STOP
357 * DRIVER RXFILTER-REMOVE Num
358 * where Num is as described for RXFILTER-ADD
359 *
360 * The SETSUSPENDOPT driver command overrides the filtering rules
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800362 public boolean startFilteringMulticastV4Packets() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800363 return doBooleanCommand("DRIVER RXFILTER-STOP")
364 && doBooleanCommand("DRIVER RXFILTER-REMOVE 2")
365 && doBooleanCommand("DRIVER RXFILTER-START");
366 }
Irfan Sheriffb0c1b80f2011-07-19 15:44:25 -0700367
368 /**
369 * Stop filtering out Multicast V4 packets.
370 * @return {@code true} if the operation succeeded, {@code false} otherwise
371 */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800372 public boolean stopFilteringMulticastV4Packets() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800373 return doBooleanCommand("DRIVER RXFILTER-STOP")
374 && doBooleanCommand("DRIVER RXFILTER-ADD 2")
375 && doBooleanCommand("DRIVER RXFILTER-START");
376 }
Irfan Sheriffb0c1b80f2011-07-19 15:44:25 -0700377
378 /**
379 * Start filtering out Multicast V6 packets
380 * @return {@code true} if the operation succeeded, {@code false} otherwise
381 */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800382 public boolean startFilteringMulticastV6Packets() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800383 return doBooleanCommand("DRIVER RXFILTER-STOP")
384 && doBooleanCommand("DRIVER RXFILTER-REMOVE 3")
385 && doBooleanCommand("DRIVER RXFILTER-START");
386 }
Irfan Sheriffb0c1b80f2011-07-19 15:44:25 -0700387
388 /**
389 * Stop filtering out Multicast V6 packets.
390 * @return {@code true} if the operation succeeded, {@code false} otherwise
391 */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800392 public boolean stopFilteringMulticastV6Packets() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800393 return doBooleanCommand("DRIVER RXFILTER-STOP")
394 && doBooleanCommand("DRIVER RXFILTER-ADD 3")
395 && doBooleanCommand("DRIVER RXFILTER-START");
396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800398 public int getBand() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800399 String ret = doStringCommand("DRIVER GETBAND");
400 if (!TextUtils.isEmpty(ret)) {
401 //reply is "BAND X" where X is the band
402 String[] tokens = ret.split(" ");
403 try {
404 if (tokens.length == 2) return Integer.parseInt(tokens[1]);
405 } catch (NumberFormatException e) {
406 return -1;
407 }
408 }
409 return -1;
410 }
Irfan Sheriff25c9bf22010-09-02 12:48:20 -0700411
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800412 public boolean setBand(int band) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800413 return doBooleanCommand("DRIVER SETBAND " + band);
414 }
Mikael Kanstrupea8bd1d2010-04-07 16:45:58 +0200415
Irfan Sheriff1f095862011-12-21 12:14:05 -0800416 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 * Sets the bluetooth coexistence mode.
Irfan Sheriff5d001ea2010-12-15 10:29:49 -0800418 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
420 * {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
421 * {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
422 * @return Whether the mode was successfully set.
423 */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800424 public boolean setBluetoothCoexistenceMode(int mode) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800425 return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
426 }
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700427
428 /**
429 * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
430 * some of the low-level scan parameters used by the driver are changed to
431 * reduce interference with A2DP streaming.
432 *
433 * @param isSet whether to enable or disable this mode
434 * @return {@code true} if the command succeeded, {@code false} otherwise.
435 */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800436 public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800437 if (setCoexScanMode) {
438 return doBooleanCommand("DRIVER BTCOEXSCAN-START");
439 } else {
440 return doBooleanCommand("DRIVER BTCOEXSCAN-STOP");
441 }
442 }
Irfan Sheriff5d001ea2010-12-15 10:29:49 -0800443
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800444 public boolean saveConfig() {
Irfan Sheriffbcc97ca2013-02-21 14:15:18 -0800445 return doBooleanCommand("SAVE_CONFIG");
Irfan Sheriff1f095862011-12-21 12:14:05 -0800446 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800448 public boolean addToBlacklist(String bssid) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800449 if (TextUtils.isEmpty(bssid)) return false;
450 return doBooleanCommand("BLACKLIST " + bssid);
451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800453 public boolean clearBlacklist() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800454 return doBooleanCommand("BLACKLIST clear");
455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800457 public boolean setSuspendOptimizations(boolean enabled) {
Irfan Sheriff633fe602012-09-14 14:35:44 -0700458 if (mSuspendOptEnabled == enabled) return true;
459 mSuspendOptEnabled = enabled;
Irfan Sheriff1f095862011-12-21 12:14:05 -0800460 if (enabled) {
Irfan Sheriff262f7662012-03-26 23:48:53 -0700461 return doBooleanCommand("DRIVER SETSUSPENDMODE 1");
Irfan Sheriff1f095862011-12-21 12:14:05 -0800462 } else {
Irfan Sheriff262f7662012-03-26 23:48:53 -0700463 return doBooleanCommand("DRIVER SETSUSPENDMODE 0");
Irfan Sheriff1f095862011-12-21 12:14:05 -0800464 }
465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800467 public boolean setCountryCode(String countryCode) {
Vinit Deshapnde2c385ec2013-09-09 16:28:31 -0700468 return doBooleanCommand("DRIVER COUNTRY " + countryCode.toUpperCase(Locale.ROOT));
Irfan Sheriff1f095862011-12-21 12:14:05 -0800469 }
Irfan Sheriff5ee89802010-09-16 17:53:34 -0700470
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800471 public void enableBackgroundScan(boolean enable) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800472 if (enable) {
Irfan Sheriffe2639d72012-04-27 12:20:00 -0700473 doBooleanCommand("SET pno 1");
Irfan Sheriff1f095862011-12-21 12:14:05 -0800474 } else {
Irfan Sheriffe2639d72012-04-27 12:20:00 -0700475 doBooleanCommand("SET pno 0");
Irfan Sheriff1f095862011-12-21 12:14:05 -0800476 }
477 }
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700478
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800479 public void setScanInterval(int scanInterval) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800480 doBooleanCommand("SCAN_INTERVAL " + scanInterval);
481 }
repo sync55bc5f32011-06-24 14:23:07 -0700482
Vinit Deshapnde64f0d5b2013-07-11 15:12:44 -0700483 public void startTdls(String macAddr, boolean enable) {
Dmitry Shmidt5ab422b2013-07-16 12:41:22 -0700484 if (enable) {
485 doBooleanCommand("TDLS_DISCOVER " + macAddr);
Vinit Deshapnde64f0d5b2013-07-11 15:12:44 -0700486 doBooleanCommand("TDLS_SETUP " + macAddr);
Dmitry Shmidt5ab422b2013-07-16 12:41:22 -0700487 } else {
Vinit Deshapnde64f0d5b2013-07-11 15:12:44 -0700488 doBooleanCommand("TDLS_TEARDOWN " + macAddr);
Dmitry Shmidt5ab422b2013-07-16 12:41:22 -0700489 }
Vinit Deshapnde64f0d5b2013-07-11 15:12:44 -0700490 }
491
Irfan Sheriff921df5c2011-09-26 16:30:15 -0700492 /** Example output:
493 * RSSI=-65
494 * LINKSPEED=48
495 * NOISE=9999
496 * FREQUENCY=0
497 */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800498 public String signalPoll() {
Vinit Deshapnde48c47472013-08-28 13:13:40 -0700499 return doStringCommandWithoutLogging("SIGNAL_POLL");
Irfan Sheriff921df5c2011-09-26 16:30:15 -0700500 }
501
Yuhao Zhengb33227d2012-07-20 10:55:17 -0700502 /** Example outout:
503 * TXGOOD=396
504 * TXBAD=1
505 */
506 public String pktcntPoll() {
507 return doStringCommand("PKTCNT_POLL");
508 }
509
Vinit Deshapndeb8d116a2013-07-09 10:42:38 -0700510 public void bssFlush() {
Dmitry Shmidt8e7c1b12013-09-06 14:25:14 -0700511 doBooleanCommand("BSS_FLUSH 0");
Vinit Deshapndeb8d116a2013-07-09 10:42:38 -0700512 }
513
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800514 public boolean startWpsPbc(String bssid) {
Irfan Sheriff86a5f5b2012-02-28 17:03:56 -0800515 if (TextUtils.isEmpty(bssid)) {
516 return doBooleanCommand("WPS_PBC");
517 } else {
518 return doBooleanCommand("WPS_PBC " + bssid);
519 }
Irfan Sheriff1f095862011-12-21 12:14:05 -0800520 }
521
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700522 public boolean startWpsPbc(String iface, String bssid) {
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700523 synchronized (mLock) {
524 if (TextUtils.isEmpty(bssid)) {
525 return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC");
526 } else {
527 return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC " + bssid);
528 }
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700529 }
530 }
531
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800532 public boolean startWpsPinKeypad(String pin) {
Irfan Sheriff86a5f5b2012-02-28 17:03:56 -0800533 if (TextUtils.isEmpty(pin)) return false;
repo sync2b8edd02011-08-16 21:39:24 -0700534 return doBooleanCommand("WPS_PIN any " + pin);
535 }
536
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700537 public boolean startWpsPinKeypad(String iface, String pin) {
538 if (TextUtils.isEmpty(pin)) return false;
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700539 synchronized (mLock) {
540 return doBooleanCommandNative("IFNAME=" + iface + " WPS_PIN any " + pin);
541 }
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700542 }
543
544
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800545 public String startWpsPinDisplay(String bssid) {
Irfan Sheriff86a5f5b2012-02-28 17:03:56 -0800546 if (TextUtils.isEmpty(bssid)) {
547 return doStringCommand("WPS_PIN any");
548 } else {
549 return doStringCommand("WPS_PIN " + bssid);
550 }
Irfan Sheriff1f095862011-12-21 12:14:05 -0800551 }
552
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700553 public String startWpsPinDisplay(String iface, String bssid) {
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700554 synchronized (mLock) {
555 if (TextUtils.isEmpty(bssid)) {
556 return doStringCommandNative("IFNAME=" + iface + " WPS_PIN any");
557 } else {
558 return doStringCommandNative("IFNAME=" + iface + " WPS_PIN " + bssid);
559 }
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700560 }
561 }
562
Irfan Sheriff1f095862011-12-21 12:14:05 -0800563 /* Configures an access point connection */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800564 public boolean startWpsRegistrar(String bssid, String pin) {
Irfan Sheriff86a5f5b2012-02-28 17:03:56 -0800565 if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false;
Irfan Sheriff1f095862011-12-21 12:14:05 -0800566 return doBooleanCommand("WPS_REG " + bssid + " " + pin);
567 }
568
Irfan Sheriff86a5f5b2012-02-28 17:03:56 -0800569 public boolean cancelWps() {
570 return doBooleanCommand("WPS_CANCEL");
571 }
572
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800573 public boolean setPersistentReconnect(boolean enabled) {
Irfan Sheriff93226872011-08-29 10:36:05 -0700574 int value = (enabled == true) ? 1 : 0;
Irfan Sheriff1f095862011-12-21 12:14:05 -0800575 return doBooleanCommand("SET persistent_reconnect " + value);
Irfan Sheriff93226872011-08-29 10:36:05 -0700576 }
577
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800578 public boolean setDeviceName(String name) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800579 return doBooleanCommand("SET device_name " + name);
Irfan Sheriff93226872011-08-29 10:36:05 -0700580 }
581
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800582 public boolean setDeviceType(String type) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800583 return doBooleanCommand("SET device_type " + type);
Irfan Sheriff93226872011-08-29 10:36:05 -0700584 }
585
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800586 public boolean setConfigMethods(String cfg) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800587 return doBooleanCommand("SET config_methods " + cfg);
Irfan Sheriff618455f2011-11-18 14:33:09 -0800588 }
589
Irfan Sheriff4dd5a252012-05-22 12:53:47 -0700590 public boolean setManufacturer(String value) {
591 return doBooleanCommand("SET manufacturer " + value);
592 }
593
594 public boolean setModelName(String value) {
595 return doBooleanCommand("SET model_name " + value);
596 }
597
598 public boolean setModelNumber(String value) {
599 return doBooleanCommand("SET model_number " + value);
600 }
601
602 public boolean setSerialNumber(String value) {
603 return doBooleanCommand("SET serial_number " + value);
604 }
605
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800606 public boolean setP2pSsidPostfix(String postfix) {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800607 return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
Irfan Sheriff530040e2011-11-30 17:20:47 -0800608 }
609
Irfan Sheriff10ca8702012-05-10 16:52:49 -0700610 public boolean setP2pGroupIdle(String iface, int time) {
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700611 synchronized (mLock) {
612 return doBooleanCommandNative("IFNAME=" + iface + " SET p2p_group_idle " + time);
613 }
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700614 }
615
Irfan Sheriffe2639d72012-04-27 12:20:00 -0700616 public void setPowerSave(boolean enabled) {
617 if (enabled) {
618 doBooleanCommand("SET ps 1");
619 } else {
620 doBooleanCommand("SET ps 0");
621 }
622 }
623
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700624 public boolean setP2pPowerSave(String iface, boolean enabled) {
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700625 synchronized (mLock) {
626 if (enabled) {
627 return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 1");
628 } else {
629 return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 0");
630 }
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700631 }
632 }
633
Andreas Huberab4cd452012-08-15 16:16:31 -0700634 public boolean setWfdEnable(boolean enable) {
635 return doBooleanCommand("SET wifi_display " + (enable ? "1" : "0"));
636 }
637
638 public boolean setWfdDeviceInfo(String hex) {
639 return doBooleanCommand("WFD_SUBELEM_SET 0 " + hex);
640 }
641
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700642 /**
643 * "sta" prioritizes STA connection over P2P and "p2p" prioritizes
644 * P2P connection over STA
645 */
646 public boolean setConcurrencyPriority(String s) {
Irfan Sheriffde1e9fa92012-05-01 16:15:23 -0700647 return doBooleanCommand("P2P_SET conc_pref " + s);
Irfan Sheriff55bfa422012-04-06 15:25:41 -0700648 }
649
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800650 public boolean p2pFind() {
repo sync2b8edd02011-08-16 21:39:24 -0700651 return doBooleanCommand("P2P_FIND");
repo sync55bc5f32011-06-24 14:23:07 -0700652 }
653
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800654 public boolean p2pFind(int timeout) {
repo sync55bc5f32011-06-24 14:23:07 -0700655 if (timeout <= 0) {
656 return p2pFind();
657 }
repo sync2b8edd02011-08-16 21:39:24 -0700658 return doBooleanCommand("P2P_FIND " + timeout);
repo sync55bc5f32011-06-24 14:23:07 -0700659 }
660
Irfan Sheriff7d6d9c02012-01-10 15:50:45 -0800661 public boolean p2pStopFind() {
662 return doBooleanCommand("P2P_STOP_FIND");
663 }
664
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800665 public boolean p2pListen() {
repo sync2b8edd02011-08-16 21:39:24 -0700666 return doBooleanCommand("P2P_LISTEN");
repo sync55bc5f32011-06-24 14:23:07 -0700667 }
668
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800669 public boolean p2pListen(int timeout) {
repo sync55bc5f32011-06-24 14:23:07 -0700670 if (timeout <= 0) {
671 return p2pListen();
672 }
repo sync2b8edd02011-08-16 21:39:24 -0700673 return doBooleanCommand("P2P_LISTEN " + timeout);
repo sync55bc5f32011-06-24 14:23:07 -0700674 }
675
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700676 public boolean p2pExtListen(boolean enable, int period, int interval) {
677 if (enable && interval < period) {
678 return false;
679 }
680 return doBooleanCommand("P2P_EXT_LISTEN"
681 + (enable ? (" " + period + " " + interval) : ""));
682 }
683
684 public boolean p2pSetChannel(int lc, int oc) {
685 if (DBG) Log.d(mTAG, "p2pSetChannel: lc="+lc+", oc="+oc);
686
687 if (lc >=1 && lc <= 11) {
688 if (!doBooleanCommand("P2P_SET listen_channel " + lc)) {
689 return false;
690 }
691 } else if (lc != 0) {
692 return false;
693 }
694
695 if (oc >= 1 && oc <= 165 ) {
696 int freq = (oc <= 14 ? 2407 : 5000) + oc * 5;
697 return doBooleanCommand("P2P_SET disallow_freq 1000-"
698 + (freq - 5) + "," + (freq + 5) + "-6000");
699 } else if (oc == 0) {
700 /* oc==0 disables "P2P_SET disallow_freq" (enables all freqs) */
701 return doBooleanCommand("P2P_SET disallow_freq \"\"");
702 }
703
704 return false;
705 }
706
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800707 public boolean p2pFlush() {
repo sync2b8edd02011-08-16 21:39:24 -0700708 return doBooleanCommand("P2P_FLUSH");
repo sync55bc5f32011-06-24 14:23:07 -0700709 }
710
711 /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
712 [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800713 public String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
repo sync55bc5f32011-06-24 14:23:07 -0700714 if (config == null) return null;
715 List<String> args = new ArrayList<String>();
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700716 WpsInfo wps = config.wps;
repo sync55bc5f32011-06-24 14:23:07 -0700717 args.add(config.deviceAddress);
718
Irfan Sheriff6f7d3852011-09-06 21:48:04 -0700719 switch (wps.setup) {
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700720 case WpsInfo.PBC:
repo sync55bc5f32011-06-24 14:23:07 -0700721 args.add("pbc");
722 break;
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700723 case WpsInfo.DISPLAY:
Irfan Sheriff618455f2011-11-18 14:33:09 -0800724 if (TextUtils.isEmpty(wps.pin)) {
725 args.add("pin");
726 } else {
727 args.add(wps.pin);
728 }
repo sync55bc5f32011-06-24 14:23:07 -0700729 args.add("display");
730 break;
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700731 case WpsInfo.KEYPAD:
Irfan Sheriff6f7d3852011-09-06 21:48:04 -0700732 args.add(wps.pin);
repo sync55bc5f32011-06-24 14:23:07 -0700733 args.add("keypad");
734 break;
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700735 case WpsInfo.LABEL:
Irfan Sheriff6f7d3852011-09-06 21:48:04 -0700736 args.add(wps.pin);
repo sync55bc5f32011-06-24 14:23:07 -0700737 args.add("label");
738 default:
739 break;
740 }
741
Yoshihiko Ikenaga0879d032012-08-16 23:37:36 +0900742 if (config.netId == WifiP2pGroup.PERSISTENT_NET_ID) {
743 args.add("persistent");
744 }
Irfan Sherifff9cb1d72011-08-29 17:01:33 -0700745
Irfan Sheriffde1e9fa92012-05-01 16:15:23 -0700746 if (joinExistingGroup) {
747 args.add("join");
748 } else {
749 //TODO: This can be adapted based on device plugged in state and
750 //device battery state
751 int groupOwnerIntent = config.groupOwnerIntent;
752 if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
753 groupOwnerIntent = DEFAULT_GROUP_OWNER_INTENT;
754 }
755 args.add("go_intent=" + groupOwnerIntent);
repo sync2b8edd02011-08-16 21:39:24 -0700756 }
repo sync55bc5f32011-06-24 14:23:07 -0700757
repo sync2b8edd02011-08-16 21:39:24 -0700758 String command = "P2P_CONNECT ";
repo sync55bc5f32011-06-24 14:23:07 -0700759 for (String s : args) command += s + " ";
760
repo sync2b8edd02011-08-16 21:39:24 -0700761 return doStringCommand(command);
repo sync55bc5f32011-06-24 14:23:07 -0700762 }
763
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800764 public boolean p2pCancelConnect() {
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700765 return doBooleanCommand("P2P_CANCEL");
766 }
767
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800768 public boolean p2pProvisionDiscovery(WifiP2pConfig config) {
Irfan Sheriff618455f2011-11-18 14:33:09 -0800769 if (config == null) return false;
770
771 switch (config.wps.setup) {
772 case WpsInfo.PBC:
773 return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " pbc");
774 case WpsInfo.DISPLAY:
775 //We are doing display, so provision discovery is keypad
776 return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " keypad");
777 case WpsInfo.KEYPAD:
778 //We are doing keypad, so provision discovery is display
779 return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " display");
780 default:
781 break;
782 }
783 return false;
784 }
785
Yoshihiko Ikenaga0879d032012-08-16 23:37:36 +0900786 public boolean p2pGroupAdd(boolean persistent) {
787 if (persistent) {
788 return doBooleanCommand("P2P_GROUP_ADD persistent");
789 }
repo sync2b8edd02011-08-16 21:39:24 -0700790 return doBooleanCommand("P2P_GROUP_ADD");
repo sync55bc5f32011-06-24 14:23:07 -0700791 }
792
Yoshihiko Ikenaga0879d032012-08-16 23:37:36 +0900793 public boolean p2pGroupAdd(int netId) {
794 return doBooleanCommand("P2P_GROUP_ADD persistent=" + netId);
795 }
796
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800797 public boolean p2pGroupRemove(String iface) {
Irfan Sheriff86a5f5b2012-02-28 17:03:56 -0800798 if (TextUtils.isEmpty(iface)) return false;
Vinit Deshapndefab5c2b2013-08-30 12:31:25 -0700799 synchronized (mLock) {
800 return doBooleanCommandNative("IFNAME=" + iface + " P2P_GROUP_REMOVE " + iface);
801 }
repo sync55bc5f32011-06-24 14:23:07 -0700802 }
803
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800804 public boolean p2pReject(String deviceAddress) {
repo sync2b8edd02011-08-16 21:39:24 -0700805 return doBooleanCommand("P2P_REJECT " + deviceAddress);
repo sync55bc5f32011-06-24 14:23:07 -0700806 }
807
808 /* Invite a peer to a group */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800809 public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
Irfan Sheriff86a5f5b2012-02-28 17:03:56 -0800810 if (TextUtils.isEmpty(deviceAddress)) return false;
Irfan Sheriffea5b16a2011-08-24 12:30:20 -0700811
812 if (group == null) {
813 return doBooleanCommand("P2P_INVITE peer=" + deviceAddress);
814 } else {
815 return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
816 + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
817 }
repo sync55bc5f32011-06-24 14:23:07 -0700818 }
repo sync8c57bcd2011-08-18 16:56:36 -0700819
Irfan Sheriffea5b16a2011-08-24 12:30:20 -0700820 /* Reinvoke a persistent connection */
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800821 public boolean p2pReinvoke(int netId, String deviceAddress) {
Irfan Sheriff86a5f5b2012-02-28 17:03:56 -0800822 if (TextUtils.isEmpty(deviceAddress) || netId < 0) return false;
Irfan Sheriffea5b16a2011-08-24 12:30:20 -0700823
824 return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
825 }
826
Yoshihiko Ikenaga0879d032012-08-16 23:37:36 +0900827 public String p2pGetSsid(String deviceAddress) {
828 return p2pGetParam(deviceAddress, "oper_ssid");
829 }
Irfan Sheriffea5b16a2011-08-24 12:30:20 -0700830
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800831 public String p2pGetDeviceAddress() {
Irfan Sheriff1f095862011-12-21 12:14:05 -0800832 String status = status();
Irfan Sheriff4be4d312011-09-03 11:03:23 -0700833 if (status == null) return "";
834
835 String[] tokens = status.split("\n");
836 for (String token : tokens) {
837 if (token.startsWith("p2p_device_address=")) {
838 String[] nameValue = token.split("=");
839 if (nameValue.length != 2) break;
840 return nameValue[1];
841 }
842 }
843 return "";
844 }
845
Irfan Sheriff57e42f42012-06-06 12:03:33 -0700846 public int getGroupCapability(String deviceAddress) {
847 int gc = 0;
848 if (TextUtils.isEmpty(deviceAddress)) return gc;
849 String peerInfo = p2pPeer(deviceAddress);
850 if (TextUtils.isEmpty(peerInfo)) return gc;
851
852 String[] tokens = peerInfo.split("\n");
853 for (String token : tokens) {
854 if (token.startsWith("group_capab=")) {
855 String[] nameValue = token.split("=");
856 if (nameValue.length != 2) break;
857 try {
858 return Integer.decode(nameValue[1]);
859 } catch(NumberFormatException e) {
860 return gc;
861 }
862 }
863 }
864 return gc;
865 }
866
Irfan Sherifffc7f95a2012-01-04 14:50:09 -0800867 public String p2pPeer(String deviceAddress) {
repo sync8c57bcd2011-08-18 16:56:36 -0700868 return doStringCommand("P2P_PEER " + deviceAddress);
869 }
Irfan Sheriff21ba8152012-04-04 16:22:21 -0700870
Yoshihiko Ikenaga0879d032012-08-16 23:37:36 +0900871 private String p2pGetParam(String deviceAddress, String key) {
872 if (deviceAddress == null) return null;
873
874 String peerInfo = p2pPeer(deviceAddress);
875 if (peerInfo == null) return null;
876 String[] tokens= peerInfo.split("\n");
877
878 key += "=";
879 for (String token : tokens) {
880 if (token.startsWith(key)) {
881 String[] nameValue = token.split("=");
882 if (nameValue.length != 2) break;
883 return nameValue[1];
884 }
885 }
886 return null;
887 }
888
Irfan Sheriff21ba8152012-04-04 16:22:21 -0700889 public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) {
890 /*
891 * P2P_SERVICE_ADD bonjour <query hexdump> <RDATA hexdump>
892 * P2P_SERVICE_ADD upnp <version hex> <service>
893 *
894 * e.g)
895 * [Bonjour]
896 * # IP Printing over TCP (PTR) (RDATA=MyPrinter._ipp._tcp.local.)
897 * P2P_SERVICE_ADD bonjour 045f697070c00c000c01 094d795072696e746572c027
898 * # IP Printing over TCP (TXT) (RDATA=txtvers=1,pdl=application/postscript)
899 * P2P_SERVICE_ADD bonjour 096d797072696e746572045f697070c00c001001
900 * 09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074
901 *
902 * [UPnP]
903 * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012
904 * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice
905 * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp
906 * -org:device:InternetGatewayDevice:1
907 * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9322-123456789012::urn:schemas-upnp
908 * -org:service:ContentDirectory:2
909 */
910 for (String s : servInfo.getSupplicantQueryList()) {
911 String command = "P2P_SERVICE_ADD";
912 command += (" " + s);
913 if (!doBooleanCommand(command)) {
914 return false;
915 }
916 }
917 return true;
918 }
919
920 public boolean p2pServiceDel(WifiP2pServiceInfo servInfo) {
921 /*
922 * P2P_SERVICE_DEL bonjour <query hexdump>
923 * P2P_SERVICE_DEL upnp <version hex> <service>
924 */
925 for (String s : servInfo.getSupplicantQueryList()) {
926 String command = "P2P_SERVICE_DEL ";
927
928 String[] data = s.split(" ");
929 if (data.length < 2) {
930 return false;
931 }
932 if ("upnp".equals(data[0])) {
933 command += s;
934 } else if ("bonjour".equals(data[0])) {
935 command += data[0];
936 command += (" " + data[1]);
937 } else {
938 return false;
939 }
940 if (!doBooleanCommand(command)) {
941 return false;
942 }
943 }
944 return true;
945 }
946
947 public boolean p2pServiceFlush() {
948 return doBooleanCommand("P2P_SERVICE_FLUSH");
949 }
950
951 public String p2pServDiscReq(String addr, String query) {
952 String command = "P2P_SERV_DISC_REQ";
953 command += (" " + addr);
954 command += (" " + query);
955
956 return doStringCommand(command);
957 }
958
959 public boolean p2pServDiscCancelReq(String id) {
960 return doBooleanCommand("P2P_SERV_DISC_CANCEL_REQ " + id);
961 }
Irfan Sheriff8b485ad2013-03-28 10:15:44 -0700962
963 /* Set the current mode of miracast operation.
964 * 0 = disabled
965 * 1 = operating as source
966 * 2 = operating as sink
967 */
968 public void setMiracastMode(int mode) {
969 // Note: optional feature on the driver. It is ok for this to fail.
970 doBooleanCommand("DRIVER MIRACAST " + mode);
971 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800972}