blob: e930c5c37638f09346abcffc0a6ab041d8fb5bc2 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright 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
17#define LOG_TAG "wifi"
18
19#include "jni.h"
Elliott Hughesf17b9712011-04-12 16:12:09 -070020#include <ScopedUtfChars.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021#include <utils/misc.h>
22#include <android_runtime/AndroidRuntime.h>
23#include <utils/Log.h>
Zheng BaoZhong038e3152009-10-10 08:07:44 -040024#include <utils/String16.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025
26#include "wifi.h"
27
28#define WIFI_PKG_NAME "android/net/wifi/WifiNative"
Irfan Sherifff235c5a2010-10-21 16:44:48 -070029#define BUF_SIZE 256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
31namespace android {
32
Mike Lockwooda5ec95c2009-07-08 17:11:17 -040033static jboolean sScanModeActive = false;
34
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035static int doCommand(const char *cmd, char *replybuf, int replybuflen)
36{
37 size_t reply_len = replybuflen - 1;
38
39 if (::wifi_command(cmd, replybuf, &reply_len) != 0)
40 return -1;
41 else {
42 // Strip off trailing newline
43 if (reply_len > 0 && replybuf[reply_len-1] == '\n')
44 replybuf[reply_len-1] = '\0';
45 else
46 replybuf[reply_len] = '\0';
47 return 0;
48 }
49}
50
Elliott Hughesf17b9712011-04-12 16:12:09 -070051static jint doIntCommand(const char* fmt, ...)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052{
Elliott Hughesf17b9712011-04-12 16:12:09 -070053 char buf[BUF_SIZE];
54 va_list args;
55 va_start(args, fmt);
56 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
57 va_end(args);
58 if (byteCount < 0 || byteCount >= BUF_SIZE) {
59 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 }
Elliott Hughesf17b9712011-04-12 16:12:09 -070061 char reply[BUF_SIZE];
62 if (doCommand(buf, reply, sizeof(reply)) != 0) {
63 return -1;
64 }
65 return static_cast<jint>(atoi(reply));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066}
67
Elliott Hughesf17b9712011-04-12 16:12:09 -070068static jboolean doBooleanCommand(const char* expect, const char* fmt, ...)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069{
Elliott Hughesf17b9712011-04-12 16:12:09 -070070 char buf[BUF_SIZE];
71 va_list args;
72 va_start(args, fmt);
73 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
74 va_end(args);
75 if (byteCount < 0 || byteCount >= BUF_SIZE) {
76 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 }
Elliott Hughesf17b9712011-04-12 16:12:09 -070078 char reply[BUF_SIZE];
79 if (doCommand(buf, reply, sizeof(reply)) != 0) {
80 return JNI_FALSE;
81 }
82 return (strcmp(reply, expect) == 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083}
84
85// Send a command to the supplicant, and return the reply as a String
Elliott Hughesf17b9712011-04-12 16:12:09 -070086static jstring doStringCommand(JNIEnv* env, const char* fmt, ...) {
87 char buf[BUF_SIZE];
88 va_list args;
89 va_start(args, fmt);
90 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
91 va_end(args);
92 if (byteCount < 0 || byteCount >= BUF_SIZE) {
93 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 }
Elliott Hughesf17b9712011-04-12 16:12:09 -070095 char reply[4096];
96 if (doCommand(buf, reply, sizeof(reply)) != 0) {
97 return NULL;
98 }
99 // TODO: why not just NewStringUTF?
100 String16 str((char *)reply);
101 return env->NewString((const jchar *)str.string(), str.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102}
103
Elliott Hughesf17b9712011-04-12 16:12:09 -0700104static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject)
Irfan Sheriffa2a1b912010-06-07 09:03:04 -0700105{
106 return (jboolean)(::is_wifi_driver_loaded() == 1);
107}
108
Elliott Hughesf17b9712011-04-12 16:12:09 -0700109static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110{
111 return (jboolean)(::wifi_load_driver() == 0);
112}
113
Elliott Hughesf17b9712011-04-12 16:12:09 -0700114static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115{
116 return (jboolean)(::wifi_unload_driver() == 0);
117}
118
Elliott Hughesf17b9712011-04-12 16:12:09 -0700119static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120{
121 return (jboolean)(::wifi_start_supplicant() == 0);
122}
123
Elliott Hughesf17b9712011-04-12 16:12:09 -0700124static jboolean android_net_wifi_stopSupplicant(JNIEnv* env, jobject)
Irfan Sheriff5d001ea2010-12-15 10:29:49 -0800125{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700126 return doBooleanCommand("OK", "TERMINATE");
Irfan Sheriff5d001ea2010-12-15 10:29:49 -0800127}
128
Elliott Hughesf17b9712011-04-12 16:12:09 -0700129static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130{
131 return (jboolean)(::wifi_stop_supplicant() == 0);
132}
133
Elliott Hughesf17b9712011-04-12 16:12:09 -0700134static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135{
136 return (jboolean)(::wifi_connect_to_supplicant() == 0);
137}
138
Elliott Hughesf17b9712011-04-12 16:12:09 -0700139static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140{
141 ::wifi_close_supplicant_connection();
142}
143
Elliott Hughesf17b9712011-04-12 16:12:09 -0700144static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145{
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700146 char buf[BUF_SIZE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
148 int nread = ::wifi_wait_for_event(buf, sizeof buf);
149 if (nread > 0) {
150 return env->NewStringUTF(buf);
151 } else {
Elliott Hughesf17b9712011-04-12 16:12:09 -0700152 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 }
154}
155
Elliott Hughesf17b9712011-04-12 16:12:09 -0700156static jstring android_net_wifi_listNetworksCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157{
158 return doStringCommand(env, "LIST_NETWORKS");
159}
160
Elliott Hughesf17b9712011-04-12 16:12:09 -0700161static jint android_net_wifi_addNetworkCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162{
163 return doIntCommand("ADD_NETWORK");
164}
165
Elliott Hughesf17b9712011-04-12 16:12:09 -0700166static jboolean android_net_wifi_wpsPbcCommand(JNIEnv* env, jobject, jstring javaBssid)
Irfan Sheriff5ee89802010-09-16 17:53:34 -0700167{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700168 ScopedUtfChars bssid(env, javaBssid);
169 if (bssid.c_str() == NULL) {
170 return JNI_FALSE;
Irfan Sheriff5ee89802010-09-16 17:53:34 -0700171 }
Elliott Hughesf17b9712011-04-12 16:12:09 -0700172 return doBooleanCommand("OK", "WPS_PBC %s", bssid.c_str());
Irfan Sheriff5ee89802010-09-16 17:53:34 -0700173}
174
Elliott Hughesf17b9712011-04-12 16:12:09 -0700175static jboolean android_net_wifi_wpsPinFromAccessPointCommand(JNIEnv* env, jobject,
176 jstring javaBssid, jstring javaApPin)
Irfan Sheriff5ee89802010-09-16 17:53:34 -0700177{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700178 ScopedUtfChars bssid(env, javaBssid);
179 if (bssid.c_str() == NULL) {
180 return JNI_FALSE;
Irfan Sheriff5ee89802010-09-16 17:53:34 -0700181 }
Elliott Hughesf17b9712011-04-12 16:12:09 -0700182 ScopedUtfChars apPin(env, javaApPin);
183 if (apPin.c_str() == NULL) {
184 return JNI_FALSE;
185 }
186 return doBooleanCommand("OK", "WPS_REG %s %s", bssid.c_str(), apPin.c_str());
Irfan Sheriff5ee89802010-09-16 17:53:34 -0700187}
188
Elliott Hughesf17b9712011-04-12 16:12:09 -0700189static jstring android_net_wifi_wpsPinFromDeviceCommand(JNIEnv* env, jobject, jstring javaBssid)
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700190{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700191 ScopedUtfChars bssid(env, javaBssid);
192 if (bssid.c_str() == NULL) {
Irfan Sheriff02fb46a2010-12-08 11:27:37 -0800193 return NULL;
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700194 }
Elliott Hughesf17b9712011-04-12 16:12:09 -0700195 return doStringCommand(env, "WPS_PIN %s", bssid.c_str());
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700196}
197
Elliott Hughesf17b9712011-04-12 16:12:09 -0700198static jboolean android_net_wifi_setCountryCodeCommand(JNIEnv* env, jobject, jstring javaCountry)
Irfan Sheriffed4f28b2010-10-29 15:32:10 -0700199{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700200 ScopedUtfChars country(env, javaCountry);
201 if (country.c_str() == NULL) {
202 return JNI_FALSE;
Irfan Sheriffed4f28b2010-10-29 15:32:10 -0700203 }
Elliott Hughesf17b9712011-04-12 16:12:09 -0700204 return doBooleanCommand("OK", "DRIVER COUNTRY %s", country.c_str());
Irfan Sheriffed4f28b2010-10-29 15:32:10 -0700205}
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207static jboolean android_net_wifi_setNetworkVariableCommand(JNIEnv* env,
Elliott Hughesf17b9712011-04-12 16:12:09 -0700208 jobject,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 jint netId,
Elliott Hughesf17b9712011-04-12 16:12:09 -0700210 jstring javaName,
211 jstring javaValue)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700213 ScopedUtfChars name(env, javaName);
214 if (name.c_str() == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 return JNI_FALSE;
Elliott Hughesf17b9712011-04-12 16:12:09 -0700216 }
217 ScopedUtfChars value(env, javaValue);
218 if (value.c_str() == NULL) {
219 return JNI_FALSE;
220 }
221 return doBooleanCommand("OK", "SET_NETWORK %d %s %s", netId, name.c_str(), value.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222}
223
224static jstring android_net_wifi_getNetworkVariableCommand(JNIEnv* env,
Elliott Hughesf17b9712011-04-12 16:12:09 -0700225 jobject,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 jint netId,
Elliott Hughesf17b9712011-04-12 16:12:09 -0700227 jstring javaName)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700229 ScopedUtfChars name(env, javaName);
230 if (name.c_str() == NULL) {
231 return NULL;
232 }
233 return doStringCommand(env, "GET_NETWORK %d %s", netId, name.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234}
235
Elliott Hughesf17b9712011-04-12 16:12:09 -0700236static jboolean android_net_wifi_removeNetworkCommand(JNIEnv* env, jobject, jint netId)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700238 return doBooleanCommand("OK", "REMOVE_NETWORK %d", netId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239}
240
241static jboolean android_net_wifi_enableNetworkCommand(JNIEnv* env,
Elliott Hughesf17b9712011-04-12 16:12:09 -0700242 jobject,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 jint netId,
244 jboolean disableOthers)
245{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700246 return doBooleanCommand("OK", "%s_NETWORK %d", disableOthers ? "SELECT" : "ENABLE", netId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247}
248
Elliott Hughesf17b9712011-04-12 16:12:09 -0700249static jboolean android_net_wifi_disableNetworkCommand(JNIEnv* env, jobject, jint netId)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700251 return doBooleanCommand("OK", "DISABLE_NETWORK %d", netId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252}
253
Elliott Hughesf17b9712011-04-12 16:12:09 -0700254static jstring android_net_wifi_statusCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255{
256 return doStringCommand(env, "STATUS");
257}
258
Elliott Hughesf17b9712011-04-12 16:12:09 -0700259static jboolean android_net_wifi_pingCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700261 return doBooleanCommand("PONG", "PING");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262}
263
Elliott Hughesf17b9712011-04-12 16:12:09 -0700264static jstring android_net_wifi_scanResultsCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265{
266 return doStringCommand(env, "SCAN_RESULTS");
267}
268
Elliott Hughesf17b9712011-04-12 16:12:09 -0700269static jboolean android_net_wifi_disconnectCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700271 return doBooleanCommand("OK", "DISCONNECT");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272}
273
Elliott Hughesf17b9712011-04-12 16:12:09 -0700274static jboolean android_net_wifi_reconnectCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700276 return doBooleanCommand("OK", "RECONNECT");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277}
Elliott Hughesf17b9712011-04-12 16:12:09 -0700278static jboolean android_net_wifi_reassociateCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700280 return doBooleanCommand("OK", "REASSOCIATE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281}
282
Mike Lockwooda5ec95c2009-07-08 17:11:17 -0400283static jboolean doSetScanMode(jboolean setActive)
284{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700285 return doBooleanCommand("OK", (setActive ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE"));
Mike Lockwooda5ec95c2009-07-08 17:11:17 -0400286}
287
Elliott Hughesf17b9712011-04-12 16:12:09 -0700288static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject, jboolean forceActive)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289{
290 jboolean result;
Mike Lockwooda5ec95c2009-07-08 17:11:17 -0400291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 // Ignore any error from setting the scan mode.
293 // The scan will still work.
Mike Lockwooda5ec95c2009-07-08 17:11:17 -0400294 if (forceActive && !sScanModeActive)
295 doSetScanMode(true);
Elliott Hughesf17b9712011-04-12 16:12:09 -0700296 result = doBooleanCommand("OK", "SCAN");
Mike Lockwooda5ec95c2009-07-08 17:11:17 -0400297 if (forceActive && !sScanModeActive)
298 doSetScanMode(sScanModeActive);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 return result;
300}
301
Elliott Hughesf17b9712011-04-12 16:12:09 -0700302static jboolean android_net_wifi_setScanModeCommand(JNIEnv* env, jobject, jboolean setActive)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303{
Mike Lockwooda5ec95c2009-07-08 17:11:17 -0400304 sScanModeActive = setActive;
305 return doSetScanMode(setActive);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306}
307
Elliott Hughesf17b9712011-04-12 16:12:09 -0700308static jboolean android_net_wifi_startDriverCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700310 return doBooleanCommand("OK", "DRIVER START");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311}
312
Elliott Hughesf17b9712011-04-12 16:12:09 -0700313static jboolean android_net_wifi_stopDriverCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700315 return doBooleanCommand("OK", "DRIVER STOP");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316}
317
Elliott Hughesf17b9712011-04-12 16:12:09 -0700318static jboolean android_net_wifi_startPacketFiltering(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700320 return doBooleanCommand("OK", "DRIVER RXFILTER-ADD 0")
321 && doBooleanCommand("OK", "DRIVER RXFILTER-ADD 1")
322 && doBooleanCommand("OK", "DRIVER RXFILTER-ADD 3")
323 && doBooleanCommand("OK", "DRIVER RXFILTER-START");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324}
325
Elliott Hughesf17b9712011-04-12 16:12:09 -0700326static jboolean android_net_wifi_stopPacketFiltering(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700328 jboolean result = doBooleanCommand("OK", "DRIVER RXFILTER-STOP");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 if (result) {
Elliott Hughesf17b9712011-04-12 16:12:09 -0700330 (void)doBooleanCommand("OK", "DRIVER RXFILTER-REMOVE 3");
331 (void)doBooleanCommand("OK", "DRIVER RXFILTER-REMOVE 1");
332 (void)doBooleanCommand("OK", "DRIVER RXFILTER-REMOVE 0");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 }
334
335 return result;
336}
337
Robert Greenwalt91f22f902009-06-08 18:15:21 -0700338static jint android_net_wifi_getRssiHelper(const char *cmd)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339{
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700340 char reply[BUF_SIZE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 int rssi = -200;
342
Robert Greenwalt91f22f902009-06-08 18:15:21 -0700343 if (doCommand(cmd, reply, sizeof(reply)) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 return (jint)-1;
345 }
Robert Greenwalt91f22f902009-06-08 18:15:21 -0700346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 // reply comes back in the form "<SSID> rssi XX" where XX is the
348 // number we're interested in. if we're associating, it returns "OK".
Mike Lockwoodc5ad0f42009-05-25 22:34:20 -0400349 // beware - <SSID> can contain spaces.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 if (strcmp(reply, "OK") != 0) {
Mike Lockwoodb20148b2009-08-04 11:32:52 -0400351 // beware of trailing spaces
352 char* end = reply + strlen(reply);
353 while (end > reply && end[-1] == ' ') {
354 end--;
355 }
356 *end = 0;
357
Mike Lockwoodc5ad0f42009-05-25 22:34:20 -0400358 char* lastSpace = strrchr(reply, ' ');
359 // lastSpace should be preceded by "rssi" and followed by the value
Stan Chesnutt320b56d2011-02-08 14:50:30 -0800360 if (lastSpace && !strncasecmp(lastSpace - 4, "rssi", 4)) {
Mike Lockwoodc5ad0f42009-05-25 22:34:20 -0400361 sscanf(lastSpace + 1, "%d", &rssi);
362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 }
364 return (jint)rssi;
365}
366
Elliott Hughesf17b9712011-04-12 16:12:09 -0700367static jint android_net_wifi_getRssiCommand(JNIEnv* env, jobject)
Robert Greenwalt91f22f902009-06-08 18:15:21 -0700368{
369 return android_net_wifi_getRssiHelper("DRIVER RSSI");
370}
371
Elliott Hughesf17b9712011-04-12 16:12:09 -0700372static jint android_net_wifi_getRssiApproxCommand(JNIEnv* env, jobject)
Robert Greenwalt91f22f902009-06-08 18:15:21 -0700373{
374 return android_net_wifi_getRssiHelper("DRIVER RSSI-APPROX");
375}
376
Elliott Hughesf17b9712011-04-12 16:12:09 -0700377static jint android_net_wifi_getLinkSpeedCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378{
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700379 char reply[BUF_SIZE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 int linkspeed;
381
382 if (doCommand("DRIVER LINKSPEED", reply, sizeof(reply)) != 0) {
383 return (jint)-1;
384 }
385 // reply comes back in the form "LinkSpeed XX" where XX is the
386 // number we're interested in.
387 sscanf(reply, "%*s %u", &linkspeed);
388 return (jint)linkspeed;
389}
390
Elliott Hughesf17b9712011-04-12 16:12:09 -0700391static jstring android_net_wifi_getMacAddressCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392{
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700393 char reply[BUF_SIZE];
394 char buf[BUF_SIZE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395
396 if (doCommand("DRIVER MACADDR", reply, sizeof(reply)) != 0) {
Elliott Hughesf17b9712011-04-12 16:12:09 -0700397 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 }
399 // reply comes back in the form "Macaddr = XX.XX.XX.XX.XX.XX" where XX
400 // is the part of the string we're interested in.
Elliott Hughesf17b9712011-04-12 16:12:09 -0700401 if (sscanf(reply, "%*s = %255s", buf) == 1) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 return env->NewStringUTF(buf);
Elliott Hughesf17b9712011-04-12 16:12:09 -0700403 }
404 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405}
406
Elliott Hughesf17b9712011-04-12 16:12:09 -0700407static jboolean android_net_wifi_setPowerModeCommand(JNIEnv* env, jobject, jint mode)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700409 return doBooleanCommand("OK", "DRIVER POWERMODE %d", mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410}
411
Elliott Hughesf17b9712011-04-12 16:12:09 -0700412static jint android_net_wifi_getPowerModeCommand(JNIEnv* env, jobject)
Mikael Kanstrupea8bd1d2010-04-07 16:45:58 +0200413{
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700414 char reply[BUF_SIZE];
Mikael Kanstrupea8bd1d2010-04-07 16:45:58 +0200415 int power;
416
417 if (doCommand("DRIVER GETPOWER", reply, sizeof(reply)) != 0) {
418 return (jint)-1;
419 }
420 // reply comes back in the form "powermode = XX" where XX is the
421 // number we're interested in.
Irfan Sheriff1a5b6092011-05-04 14:16:44 -0700422 if (sscanf(reply, "%*s = %u", &power) != 1) {
423 return (jint)-1;
424 }
Mikael Kanstrupea8bd1d2010-04-07 16:45:58 +0200425 return (jint)power;
426}
427
Elliott Hughesf17b9712011-04-12 16:12:09 -0700428static jboolean android_net_wifi_setBandCommand(JNIEnv* env, jobject, jint band)
Irfan Sheriff25c9bf22010-09-02 12:48:20 -0700429{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700430 return doBooleanCommand("OK", "DRIVER SETBAND %d", band);
Irfan Sheriff25c9bf22010-09-02 12:48:20 -0700431}
432
Elliott Hughesf17b9712011-04-12 16:12:09 -0700433static jint android_net_wifi_getBandCommand(JNIEnv* env, jobject)
Irfan Sheriff25c9bf22010-09-02 12:48:20 -0700434{
435 char reply[25];
436 int band;
437
438 if (doCommand("DRIVER GETBAND", reply, sizeof(reply)) != 0) {
439 return (jint)-1;
440 }
441 // reply comes back in the form "Band X" where X is the
442 // number we're interested in.
443 sscanf(reply, "%*s %u", &band);
444 return (jint)band;
445}
446
Elliott Hughesf17b9712011-04-12 16:12:09 -0700447static jboolean android_net_wifi_setBluetoothCoexistenceModeCommand(JNIEnv* env, jobject, jint mode)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700449 return doBooleanCommand("OK", "DRIVER BTCOEXMODE %d", mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450}
451
Elliott Hughesf17b9712011-04-12 16:12:09 -0700452static jboolean android_net_wifi_setBluetoothCoexistenceScanModeCommand(JNIEnv* env, jobject, jboolean setCoexScanMode)
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700453{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700454 return doBooleanCommand("OK", "DRIVER BTCOEXSCAN-%s", setCoexScanMode ? "START" : "STOP");
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700455}
456
Elliott Hughesf17b9712011-04-12 16:12:09 -0700457static jboolean android_net_wifi_saveConfigCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458{
459 // Make sure we never write out a value for AP_SCAN other than 1
Elliott Hughesf17b9712011-04-12 16:12:09 -0700460 (void)doBooleanCommand("OK", "AP_SCAN 1");
461 return doBooleanCommand("OK", "SAVE_CONFIG");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462}
463
Elliott Hughesf17b9712011-04-12 16:12:09 -0700464static jboolean android_net_wifi_reloadConfigCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700466 return doBooleanCommand("OK", "RECONFIGURE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467}
468
Elliott Hughesf17b9712011-04-12 16:12:09 -0700469static jboolean android_net_wifi_setScanResultHandlingCommand(JNIEnv* env, jobject, jint mode)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700471 return doBooleanCommand("OK", "AP_SCAN %d", mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472}
473
Elliott Hughesf17b9712011-04-12 16:12:09 -0700474static jboolean android_net_wifi_addToBlacklistCommand(JNIEnv* env, jobject, jstring javaBssid)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700476 ScopedUtfChars bssid(env, javaBssid);
477 if (bssid.c_str() == NULL) {
478 return JNI_FALSE;
479 }
480 return doBooleanCommand("OK", "BLACKLIST %s", bssid.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481}
482
Elliott Hughesf17b9712011-04-12 16:12:09 -0700483static jboolean android_net_wifi_clearBlacklistCommand(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700485 return doBooleanCommand("OK", "BLACKLIST clear");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486}
487
Elliott Hughesf17b9712011-04-12 16:12:09 -0700488static jboolean android_net_wifi_setSuspendOptimizationsCommand(JNIEnv* env, jobject, jboolean enabled)
Irfan Sheriff5876a422010-08-12 20:26:23 -0700489{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700490 return doBooleanCommand("OK", "DRIVER SETSUSPENDOPT %d", enabled ? 0 : 1);
Irfan Sheriff5876a422010-08-12 20:26:23 -0700491}
492
Elliott Hughesf17b9712011-04-12 16:12:09 -0700493static void android_net_wifi_enableBackgroundScanCommand(JNIEnv* env, jobject, jboolean enable)
Irfan Sherifffcc08452011-02-17 16:44:54 -0800494{
495 //Note: BGSCAN-START and BGSCAN-STOP are documented in core/res/res/values/config.xml
496 //and will need an update if the names are changed
497 if (enable) {
Elliott Hughesf17b9712011-04-12 16:12:09 -0700498 doBooleanCommand("OK", "DRIVER BGSCAN-START");
499 } else {
500 doBooleanCommand("OK", "DRIVER BGSCAN-STOP");
Irfan Sherifffcc08452011-02-17 16:44:54 -0800501 }
502}
503
Elliott Hughesf17b9712011-04-12 16:12:09 -0700504static void android_net_wifi_setScanIntervalCommand(JNIEnv* env, jobject, jint scanInterval)
Irfan Sheriff2b7f6382011-03-25 14:29:19 -0700505{
Elliott Hughesf17b9712011-04-12 16:12:09 -0700506 doBooleanCommand("OK", "SCAN_INTERVAL %d", scanInterval);
Irfan Sheriff2b7f6382011-03-25 14:29:19 -0700507}
508
509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510// ----------------------------------------------------------------------------
511
512/*
513 * JNI registration.
514 */
515static JNINativeMethod gWifiMethods[] = {
516 /* name, signature, funcPtr */
517
518 { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
Irfan Sheriffa2a1b912010-06-07 09:03:04 -0700519 { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
521 { "startSupplicant", "()Z", (void *)android_net_wifi_startSupplicant },
Irfan Sheriff5d001ea2010-12-15 10:29:49 -0800522 { "stopSupplicant", "()Z", (void*) android_net_wifi_stopSupplicant },
Irfan Sheriff96071a72010-12-14 11:29:23 -0800523 { "killSupplicant", "()Z", (void *)android_net_wifi_killSupplicant },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 { "connectToSupplicant", "()Z", (void *)android_net_wifi_connectToSupplicant },
525 { "closeSupplicantConnection", "()V", (void *)android_net_wifi_closeSupplicantConnection },
526
527 { "listNetworksCommand", "()Ljava/lang/String;",
528 (void*) android_net_wifi_listNetworksCommand },
529 { "addNetworkCommand", "()I", (void*) android_net_wifi_addNetworkCommand },
530 { "setNetworkVariableCommand", "(ILjava/lang/String;Ljava/lang/String;)Z",
531 (void*) android_net_wifi_setNetworkVariableCommand },
532 { "getNetworkVariableCommand", "(ILjava/lang/String;)Ljava/lang/String;",
533 (void*) android_net_wifi_getNetworkVariableCommand },
534 { "removeNetworkCommand", "(I)Z", (void*) android_net_wifi_removeNetworkCommand },
535 { "enableNetworkCommand", "(IZ)Z", (void*) android_net_wifi_enableNetworkCommand },
536 { "disableNetworkCommand", "(I)Z", (void*) android_net_wifi_disableNetworkCommand },
537 { "waitForEvent", "()Ljava/lang/String;", (void*) android_net_wifi_waitForEvent },
538 { "statusCommand", "()Ljava/lang/String;", (void*) android_net_wifi_statusCommand },
539 { "scanResultsCommand", "()Ljava/lang/String;", (void*) android_net_wifi_scanResultsCommand },
540 { "pingCommand", "()Z", (void *)android_net_wifi_pingCommand },
541 { "disconnectCommand", "()Z", (void *)android_net_wifi_disconnectCommand },
542 { "reconnectCommand", "()Z", (void *)android_net_wifi_reconnectCommand },
543 { "reassociateCommand", "()Z", (void *)android_net_wifi_reassociateCommand },
Mike Lockwooda5ec95c2009-07-08 17:11:17 -0400544 { "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 { "setScanModeCommand", "(Z)Z", (void*) android_net_wifi_setScanModeCommand },
546 { "startDriverCommand", "()Z", (void*) android_net_wifi_startDriverCommand },
547 { "stopDriverCommand", "()Z", (void*) android_net_wifi_stopDriverCommand },
548 { "startPacketFiltering", "()Z", (void*) android_net_wifi_startPacketFiltering },
549 { "stopPacketFiltering", "()Z", (void*) android_net_wifi_stopPacketFiltering },
550 { "setPowerModeCommand", "(I)Z", (void*) android_net_wifi_setPowerModeCommand },
Mikael Kanstrupea8bd1d2010-04-07 16:45:58 +0200551 { "getPowerModeCommand", "()I", (void*) android_net_wifi_getPowerModeCommand },
Irfan Sheriff25c9bf22010-09-02 12:48:20 -0700552 { "setBandCommand", "(I)Z", (void*) android_net_wifi_setBandCommand},
553 { "getBandCommand", "()I", (void*) android_net_wifi_getBandCommand},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 { "setBluetoothCoexistenceModeCommand", "(I)Z",
555 (void*) android_net_wifi_setBluetoothCoexistenceModeCommand },
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700556 { "setBluetoothCoexistenceScanModeCommand", "(Z)Z",
557 (void*) android_net_wifi_setBluetoothCoexistenceScanModeCommand },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 { "getRssiCommand", "()I", (void*) android_net_wifi_getRssiCommand },
Robert Greenwalt91f22f902009-06-08 18:15:21 -0700559 { "getRssiApproxCommand", "()I",
560 (void*) android_net_wifi_getRssiApproxCommand},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 { "getLinkSpeedCommand", "()I", (void*) android_net_wifi_getLinkSpeedCommand },
562 { "getMacAddressCommand", "()Ljava/lang/String;", (void*) android_net_wifi_getMacAddressCommand },
563 { "saveConfigCommand", "()Z", (void*) android_net_wifi_saveConfigCommand },
564 { "reloadConfigCommand", "()Z", (void*) android_net_wifi_reloadConfigCommand },
565 { "setScanResultHandlingCommand", "(I)Z", (void*) android_net_wifi_setScanResultHandlingCommand },
566 { "addToBlacklistCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_addToBlacklistCommand },
567 { "clearBlacklistCommand", "()Z", (void*) android_net_wifi_clearBlacklistCommand },
Irfan Sheriff5ee89802010-09-16 17:53:34 -0700568 { "startWpsPbcCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_wpsPbcCommand },
Irfan Sheriff02fb46a2010-12-08 11:27:37 -0800569 { "startWpsWithPinFromAccessPointCommand", "(Ljava/lang/String;Ljava/lang/String;)Z",
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700570 (void*) android_net_wifi_wpsPinFromAccessPointCommand },
Irfan Sheriff02fb46a2010-12-08 11:27:37 -0800571 { "startWpsWithPinFromDeviceCommand", "(Ljava/lang/String;)Ljava/lang/String;",
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700572 (void*) android_net_wifi_wpsPinFromDeviceCommand },
Irfan Sheriff5876a422010-08-12 20:26:23 -0700573 { "setSuspendOptimizationsCommand", "(Z)Z",
574 (void*) android_net_wifi_setSuspendOptimizationsCommand},
Irfan Sheriffed4f28b2010-10-29 15:32:10 -0700575 { "setCountryCodeCommand", "(Ljava/lang/String;)Z",
576 (void*) android_net_wifi_setCountryCodeCommand},
Irfan Sheriff2b7f6382011-03-25 14:29:19 -0700577 { "enableBackgroundScanCommand", "(Z)V", (void*) android_net_wifi_enableBackgroundScanCommand},
578 { "setScanIntervalCommand", "(I)V", (void*) android_net_wifi_setScanIntervalCommand},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579};
580
581int register_android_net_wifi_WifiManager(JNIEnv* env)
582{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 return AndroidRuntime::registerNativeMethods(env,
584 WIFI_PKG_NAME, gWifiMethods, NELEM(gWifiMethods));
585}
586
587}; // namespace android