blob: 6ff1bc248cf93b3f458f50fa1cf663f1572143c2 [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
17package android.net.wifi;
18
repo sync55bc5f32011-06-24 14:23:07 -070019import android.net.wifi.p2p.WifiP2pConfig;
20import android.net.wifi.p2p.WifiP2pGroup;
21import android.net.wifi.p2p.WifiP2pDevice;
22import android.util.Log;
23
24import java.io.InputStream;
25import java.lang.Process;
26import java.util.ArrayList;
27import java.util.List;
28
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029/**
30 * Native calls for sending requests to the supplicant daemon, and for
31 * receiving asynchronous events. All methods of the form "xxxxCommand()"
32 * must be single-threaded, to avoid requests and responses initiated
33 * from multiple threads from being intermingled.
34 * <p/>
35 * Note that methods whose names are not of the form "xxxCommand()" do
36 * not talk to the supplicant daemon.
Irfan Sheriffa8fbe1f2010-03-09 09:13:58 -080037 * Also, note that all WifiNative calls should happen in the
38 * WifiStateTracker class except for waitForEvent() call which is
39 * on a separate monitor channel for WifiMonitor
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 *
repo sync55bc5f32011-06-24 14:23:07 -070041 * TODO: clean up the API and move the functionality from JNI to here. We should
42 * be able to get everything done with doBooleanCommand, doIntCommand and
43 * doStringCommand native commands
44 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 * {@hide}
46 */
47public class WifiNative {
48
49 static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED = 0;
50 static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
51 static final int BLUETOOTH_COEXISTENCE_MODE_SENSE = 2;
Irfan Sheriff5d001ea2010-12-15 10:29:49 -080052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053 public native static String getErrorString(int errorCode);
54
55 public native static boolean loadDriver();
Irfan Sheriffa2a1b912010-06-07 09:03:04 -070056
57 public native static boolean isDriverLoaded();
Irfan Sheriff5d001ea2010-12-15 10:29:49 -080058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 public native static boolean unloadDriver();
60
61 public native static boolean startSupplicant();
Irfan Sheriff5d001ea2010-12-15 10:29:49 -080062
Irfan Sherifff42c39b2011-08-26 14:45:23 -070063 public native static boolean startP2pSupplicant();
64
65 /* Does a graceful shutdown of supplicant. Is a common stop function for both p2p and sta.
Irfan Sheriff5d001ea2010-12-15 10:29:49 -080066 *
67 * Note that underneath we use a harsh-sounding "terminate" supplicant command
68 * for a graceful stop and a mild-sounding "stop" interface
69 * to kill the process
70 */
71 public native static boolean stopSupplicant();
72
73 /* Sends a kill signal to supplicant. To be used when we have lost connection
74 or when the supplicant is hung */
Irfan Sheriff96071a72010-12-14 11:29:23 -080075 public native static boolean killSupplicant();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
77 public native static boolean connectToSupplicant();
78
79 public native static void closeSupplicantConnection();
80
81 public native static boolean pingCommand();
82
Mike Lockwooda5ec95c2009-07-08 17:11:17 -040083 public native static boolean scanCommand(boolean forceActive);
Irfan Sheriff5d001ea2010-12-15 10:29:49 -080084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 public native static boolean setScanModeCommand(boolean setActive);
86
87 public native static String listNetworksCommand();
88
89 public native static int addNetworkCommand();
90
91 public native static boolean setNetworkVariableCommand(int netId, String name, String value);
92
93 public native static String getNetworkVariableCommand(int netId, String name);
94
95 public native static boolean removeNetworkCommand(int netId);
96
97 public native static boolean enableNetworkCommand(int netId, boolean disableOthers);
Irfan Sheriff5d001ea2010-12-15 10:29:49 -080098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 public native static boolean disableNetworkCommand(int netId);
100
101 public native static boolean reconnectCommand();
102
103 public native static boolean reassociateCommand();
104
105 public native static boolean disconnectCommand();
106
107 public native static String statusCommand();
108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 public native static String getMacAddressCommand();
110
111 public native static String scanResultsCommand();
112
113 public native static boolean startDriverCommand();
114
115 public native static boolean stopDriverCommand();
116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117
118 /**
Irfan Sheriffb0c1b80f2011-07-19 15:44:25 -0700119 * Start filtering out Multicast V4 packets
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 * @return {@code true} if the operation succeeded, {@code false} otherwise
121 */
Irfan Sheriffb0c1b80f2011-07-19 15:44:25 -0700122 public native static boolean startFilteringMulticastV4Packets();
123
124 /**
125 * Stop filtering out Multicast V4 packets.
126 * @return {@code true} if the operation succeeded, {@code false} otherwise
127 */
128 public native static boolean stopFilteringMulticastV4Packets();
129
130 /**
131 * Start filtering out Multicast V6 packets
132 * @return {@code true} if the operation succeeded, {@code false} otherwise
133 */
134 public native static boolean startFilteringMulticastV6Packets();
135
136 /**
137 * Stop filtering out Multicast V6 packets.
138 * @return {@code true} if the operation succeeded, {@code false} otherwise
139 */
140 public native static boolean stopFilteringMulticastV6Packets();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141
142 public native static boolean setPowerModeCommand(int mode);
143
Irfan Sheriff25c9bf22010-09-02 12:48:20 -0700144 public native static int getBandCommand();
145
146 public native static boolean setBandCommand(int band);
147
Mikael Kanstrupea8bd1d2010-04-07 16:45:58 +0200148 public native static int getPowerModeCommand();
149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 /**
151 * Sets the bluetooth coexistence mode.
Irfan Sheriff5d001ea2010-12-15 10:29:49 -0800152 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
154 * {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
155 * {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
156 * @return Whether the mode was successfully set.
157 */
158 public native static boolean setBluetoothCoexistenceModeCommand(int mode);
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700159
160 /**
161 * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
162 * some of the low-level scan parameters used by the driver are changed to
163 * reduce interference with A2DP streaming.
164 *
165 * @param isSet whether to enable or disable this mode
166 * @return {@code true} if the command succeeded, {@code false} otherwise.
167 */
168 public native static boolean setBluetoothCoexistenceScanModeCommand(boolean setCoexScanMode);
Irfan Sheriff5d001ea2010-12-15 10:29:49 -0800169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 public native static boolean saveConfigCommand();
171
172 public native static boolean reloadConfigCommand();
173
174 public native static boolean setScanResultHandlingCommand(int mode);
175
176 public native static boolean addToBlacklistCommand(String bssid);
177
178 public native static boolean clearBlacklistCommand();
179
Irfan Sheriff5ee89802010-09-16 17:53:34 -0700180 public native static boolean startWpsPbcCommand(String bssid);
181
Irfan Sheriff02fb46a2010-12-08 11:27:37 -0800182 public native static boolean startWpsWithPinFromAccessPointCommand(String bssid, String apPin);
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700183
Irfan Sheriff02fb46a2010-12-08 11:27:37 -0800184 public native static String startWpsWithPinFromDeviceCommand(String bssid);
Irfan Sheriff5ee89802010-09-16 17:53:34 -0700185
Irfan Sheriff5876a422010-08-12 20:26:23 -0700186 public native static boolean setSuspendOptimizationsCommand(boolean enabled);
187
Irfan Sheriffed4f28b2010-10-29 15:32:10 -0700188 public native static boolean setCountryCodeCommand(String countryCode);
189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 /**
191 * Wait for the supplicant to send an event, returning the event string.
192 * @return the event string sent by the supplicant.
193 */
194 public native static String waitForEvent();
Irfan Sherifffcc08452011-02-17 16:44:54 -0800195
Irfan Sheriff2b7f6382011-03-25 14:29:19 -0700196 public native static void enableBackgroundScanCommand(boolean enable);
197
198 public native static void setScanIntervalCommand(int scanInterval);
repo sync55bc5f32011-06-24 14:23:07 -0700199
200 private native static boolean doBooleanCommand(String command);
201
repo sync55bc5f32011-06-24 14:23:07 -0700202 private native static int doIntCommand(String command);
203
204 private native static String doStringCommand(String command);
205
Irfan Sheriff921df5c2011-09-26 16:30:15 -0700206 /** Example output:
207 * RSSI=-65
208 * LINKSPEED=48
209 * NOISE=9999
210 * FREQUENCY=0
211 */
212 public static String signalPoll() {
213 return doStringCommand("SIGNAL_POLL");
214 }
215
repo sync2b8edd02011-08-16 21:39:24 -0700216 public static boolean wpsPbc() {
217 return doBooleanCommand("WPS_PBC");
218 }
219
220 public static boolean wpsPin(String pin) {
221 return doBooleanCommand("WPS_PIN any " + pin);
222 }
223
Irfan Sheriff93226872011-08-29 10:36:05 -0700224 public static boolean setPersistentReconnect(boolean enabled) {
225 int value = (enabled == true) ? 1 : 0;
226 return WifiNative.doBooleanCommand("SET persistent_reconnect " + value);
227 }
228
229 public static boolean setDeviceName(String name) {
230 return WifiNative.doBooleanCommand("SET device_name " + name);
231 }
232
233 public static boolean setDeviceType(String type) {
234 return WifiNative.doBooleanCommand("SET device_type " + type);
235 }
236
repo sync55bc5f32011-06-24 14:23:07 -0700237 public static boolean p2pFind() {
repo sync2b8edd02011-08-16 21:39:24 -0700238 return doBooleanCommand("P2P_FIND");
repo sync55bc5f32011-06-24 14:23:07 -0700239 }
240
241 public static boolean p2pFind(int timeout) {
242 if (timeout <= 0) {
243 return p2pFind();
244 }
repo sync2b8edd02011-08-16 21:39:24 -0700245 return doBooleanCommand("P2P_FIND " + timeout);
repo sync55bc5f32011-06-24 14:23:07 -0700246 }
247
248 public static boolean p2pListen() {
repo sync2b8edd02011-08-16 21:39:24 -0700249 return doBooleanCommand("P2P_LISTEN");
repo sync55bc5f32011-06-24 14:23:07 -0700250 }
251
252 public static boolean p2pListen(int timeout) {
253 if (timeout <= 0) {
254 return p2pListen();
255 }
repo sync2b8edd02011-08-16 21:39:24 -0700256 return doBooleanCommand("P2P_LISTEN " + timeout);
repo sync55bc5f32011-06-24 14:23:07 -0700257 }
258
259 public static boolean p2pFlush() {
repo sync2b8edd02011-08-16 21:39:24 -0700260 return doBooleanCommand("P2P_FLUSH");
repo sync55bc5f32011-06-24 14:23:07 -0700261 }
262
263 /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
264 [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
Irfan Sheriffea5b16a2011-08-24 12:30:20 -0700265 public static String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
repo sync55bc5f32011-06-24 14:23:07 -0700266 if (config == null) return null;
267 List<String> args = new ArrayList<String>();
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700268 WpsInfo wps = config.wps;
repo sync55bc5f32011-06-24 14:23:07 -0700269 args.add(config.deviceAddress);
270
Irfan Sheriff6f7d3852011-09-06 21:48:04 -0700271 switch (wps.setup) {
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700272 case WpsInfo.PBC:
repo sync55bc5f32011-06-24 14:23:07 -0700273 args.add("pbc");
274 break;
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700275 case WpsInfo.DISPLAY:
repo sync55bc5f32011-06-24 14:23:07 -0700276 //TODO: pass the pin back for display
277 args.add("pin");
278 args.add("display");
279 break;
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700280 case WpsInfo.KEYPAD:
Irfan Sheriff6f7d3852011-09-06 21:48:04 -0700281 args.add(wps.pin);
repo sync55bc5f32011-06-24 14:23:07 -0700282 args.add("keypad");
283 break;
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700284 case WpsInfo.LABEL:
Irfan Sheriff6f7d3852011-09-06 21:48:04 -0700285 args.add(wps.pin);
repo sync55bc5f32011-06-24 14:23:07 -0700286 args.add("label");
287 default:
288 break;
289 }
290
Irfan Sherifff9cb1d72011-08-29 17:01:33 -0700291 //TODO: Add persist behavior once the supplicant interaction is fixed for both
292 // group and client scenarios
Irfan Sheriffea5b16a2011-08-24 12:30:20 -0700293 /* Persist unless there is an explicit request to not do so*/
Irfan Sherifff9cb1d72011-08-29 17:01:33 -0700294 //if (config.persist != WifiP2pConfig.Persist.NO) args.add("persistent");
295
Irfan Sheriffea5b16a2011-08-24 12:30:20 -0700296 if (joinExistingGroup) args.add("join");
repo sync55bc5f32011-06-24 14:23:07 -0700297
repo sync2b8edd02011-08-16 21:39:24 -0700298 int groupOwnerIntent = config.groupOwnerIntent;
299 if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
300 groupOwnerIntent = 3; //default value
301 }
302 args.add("go_intent=" + groupOwnerIntent);
repo sync55bc5f32011-06-24 14:23:07 -0700303
repo sync2b8edd02011-08-16 21:39:24 -0700304 String command = "P2P_CONNECT ";
repo sync55bc5f32011-06-24 14:23:07 -0700305 for (String s : args) command += s + " ";
306
repo sync2b8edd02011-08-16 21:39:24 -0700307 return doStringCommand(command);
repo sync55bc5f32011-06-24 14:23:07 -0700308 }
309
Irfan Sheriff651cdfc2011-09-07 00:31:20 -0700310 public static boolean p2pCancelConnect() {
311 return doBooleanCommand("P2P_CANCEL");
312 }
313
repo sync55bc5f32011-06-24 14:23:07 -0700314 public static boolean p2pGroupAdd() {
repo sync2b8edd02011-08-16 21:39:24 -0700315 return doBooleanCommand("P2P_GROUP_ADD");
repo sync55bc5f32011-06-24 14:23:07 -0700316 }
317
318 public static boolean p2pGroupRemove(String iface) {
319 if (iface == null) return false;
repo sync2b8edd02011-08-16 21:39:24 -0700320 return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
repo sync55bc5f32011-06-24 14:23:07 -0700321 }
322
323 public static boolean p2pReject(String deviceAddress) {
repo sync2b8edd02011-08-16 21:39:24 -0700324 return doBooleanCommand("P2P_REJECT " + deviceAddress);
repo sync55bc5f32011-06-24 14:23:07 -0700325 }
326
327 /* Invite a peer to a group */
328 public static boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
Irfan Sheriffea5b16a2011-08-24 12:30:20 -0700329 if (deviceAddress == null) return false;
330
331 if (group == null) {
332 return doBooleanCommand("P2P_INVITE peer=" + deviceAddress);
333 } else {
334 return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
335 + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
336 }
repo sync55bc5f32011-06-24 14:23:07 -0700337 }
repo sync8c57bcd2011-08-18 16:56:36 -0700338
Irfan Sheriffea5b16a2011-08-24 12:30:20 -0700339 /* Reinvoke a persistent connection */
340 public static boolean p2pReinvoke(int netId, String deviceAddress) {
341 if (deviceAddress == null || netId < 0) return false;
342
343 return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
344 }
345
346
repo sync8c57bcd2011-08-18 16:56:36 -0700347 public static String p2pGetInterfaceAddress(String deviceAddress) {
348 if (deviceAddress == null) return null;
349
350 // "p2p_peer deviceAddress" returns a multi-line result containing
351 // intended_addr=fa:7b:7a:42:82:13
352 String peerInfo = p2pPeer(deviceAddress);
353 if (peerInfo == null) return null;
354 String[] tokens= peerInfo.split("\n");
355
356 for (String token : tokens) {
357 //TODO: update from interface_addr when wpa_supplicant implementation is fixed
358 if (token.startsWith("intended_addr=")) {
359 String[] nameValue = token.split("=");
360 if (nameValue.length != 2) break;
361 return nameValue[1];
362 }
363 }
364 return null;
365 }
366
Irfan Sheriff4be4d312011-09-03 11:03:23 -0700367 public static String p2pGetDeviceAddress() {
368 String status = statusCommand();
369 if (status == null) return "";
370
371 String[] tokens = status.split("\n");
372 for (String token : tokens) {
373 if (token.startsWith("p2p_device_address=")) {
374 String[] nameValue = token.split("=");
375 if (nameValue.length != 2) break;
376 return nameValue[1];
377 }
378 }
379 return "";
380 }
381
repo sync8c57bcd2011-08-18 16:56:36 -0700382 public static String p2pPeer(String deviceAddress) {
383 return doStringCommand("P2P_PEER " + deviceAddress);
384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385}