android_net_wifi_Wifi.cpp revision dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4
1/*
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"
20#include <utils/misc.h>
21#include <android_runtime/AndroidRuntime.h>
22#include <utils/Log.h>
23#include <utils/String16.h>
24
25#include "wifi.h"
26
27#define WIFI_PKG_NAME "android/net/wifi/WifiNative"
28#define BUF_SIZE 256
29
30namespace android {
31
32static jboolean sScanModeActive = false;
33
34static int doCommand(const char *cmd, char *replybuf, int replybuflen)
35{
36    size_t reply_len = replybuflen - 1;
37
38    if (::wifi_command(cmd, replybuf, &reply_len) != 0)
39        return -1;
40    else {
41        // Strip off trailing newline
42        if (reply_len > 0 && replybuf[reply_len-1] == '\n')
43            replybuf[reply_len-1] = '\0';
44        else
45            replybuf[reply_len] = '\0';
46        return 0;
47    }
48}
49
50static jint doIntCommand(const char *cmd)
51{
52    char reply[BUF_SIZE];
53
54    if (doCommand(cmd, reply, sizeof(reply)) != 0) {
55        return (jint)-1;
56    } else {
57        return (jint)atoi(reply);
58    }
59}
60
61static jboolean doBooleanCommand(const char *cmd, const char *expect)
62{
63    char reply[BUF_SIZE];
64
65    if (doCommand(cmd, reply, sizeof(reply)) != 0) {
66        return (jboolean)JNI_FALSE;
67    } else {
68        return (jboolean)(strcmp(reply, expect) == 0);
69    }
70}
71
72// Send a command to the supplicant, and return the reply as a String
73static jstring doStringCommand(JNIEnv *env, const char *cmd)
74{
75    char reply[4096];
76
77    if (doCommand(cmd, reply, sizeof(reply)) != 0) {
78        return env->NewStringUTF(NULL);
79    } else {
80        String16 str((char *)reply);
81        return env->NewString((const jchar *)str.string(), str.size());
82    }
83}
84
85static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject clazz)
86{
87    return (jboolean)(::is_wifi_driver_loaded() == 1);
88}
89
90static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject clazz)
91{
92    return (jboolean)(::wifi_load_driver() == 0);
93}
94
95static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject clazz)
96{
97    return (jboolean)(::wifi_unload_driver() == 0);
98}
99
100static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject clazz)
101{
102    return (jboolean)(::wifi_start_supplicant() == 0);
103}
104
105static jboolean android_net_wifi_stopSupplicant(JNIEnv* env, jobject clazz)
106{
107    return doBooleanCommand("TERMINATE", "OK");
108}
109
110static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject clazz)
111{
112    return (jboolean)(::wifi_stop_supplicant() == 0);
113}
114
115static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject clazz)
116{
117    return (jboolean)(::wifi_connect_to_supplicant() == 0);
118}
119
120static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject clazz)
121{
122    ::wifi_close_supplicant_connection();
123}
124
125static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject clazz)
126{
127    char buf[BUF_SIZE];
128
129    int nread = ::wifi_wait_for_event(buf, sizeof buf);
130    if (nread > 0) {
131        return env->NewStringUTF(buf);
132    } else {
133        return  env->NewStringUTF(NULL);
134    }
135}
136
137static jstring android_net_wifi_listNetworksCommand(JNIEnv* env, jobject clazz)
138{
139    return doStringCommand(env, "LIST_NETWORKS");
140}
141
142static jint android_net_wifi_addNetworkCommand(JNIEnv* env, jobject clazz)
143{
144    return doIntCommand("ADD_NETWORK");
145}
146
147static jboolean android_net_wifi_wpsPbcCommand(JNIEnv* env, jobject clazz, jstring bssid)
148{
149    char cmdstr[BUF_SIZE];
150    jboolean isCopy;
151
152    const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
153    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "WPS_PBC %s", bssidStr);
154    env->ReleaseStringUTFChars(bssid, bssidStr);
155
156    if ((numWritten == -1) || (numWritten >= sizeof(cmdstr))) {
157        return false;
158    }
159    return doBooleanCommand(cmdstr, "OK");
160}
161
162static jboolean android_net_wifi_wpsPinFromAccessPointCommand(JNIEnv* env, jobject clazz,
163        jstring bssid, jstring apPin)
164{
165    char cmdstr[BUF_SIZE];
166    jboolean isCopy;
167
168    const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
169    const char *apPinStr = env->GetStringUTFChars(apPin, &isCopy);
170    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "WPS_REG %s %s", bssidStr, apPinStr);
171    env->ReleaseStringUTFChars(bssid, bssidStr);
172    env->ReleaseStringUTFChars(apPin, apPinStr);
173
174    if ((numWritten == -1) || (numWritten >= (int)sizeof(cmdstr))) {
175        return false;
176    }
177    return doBooleanCommand(cmdstr, "OK");
178}
179
180static jstring android_net_wifi_wpsPinFromDeviceCommand(JNIEnv* env, jobject clazz, jstring bssid)
181{
182    char cmdstr[BUF_SIZE];
183    jboolean isCopy;
184
185    const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
186    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "WPS_PIN %s", bssidStr);
187    env->ReleaseStringUTFChars(bssid, bssidStr);
188
189    if ((numWritten == -1) || (numWritten >= (int)sizeof(cmdstr))) {
190        return NULL;
191    }
192    return doStringCommand(env, cmdstr);
193}
194
195static jboolean android_net_wifi_setCountryCodeCommand(JNIEnv* env, jobject clazz, jstring country)
196{
197    char cmdstr[BUF_SIZE];
198    jboolean isCopy;
199
200    const char *countryStr = env->GetStringUTFChars(country, &isCopy);
201    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER COUNTRY %s", countryStr);
202    env->ReleaseStringUTFChars(country, countryStr);
203
204    if ((numWritten == -1) || (numWritten >= (int)sizeof(cmdstr))) {
205        return false;
206    }
207    return doBooleanCommand(cmdstr, "OK");
208}
209
210static jboolean android_net_wifi_setNetworkVariableCommand(JNIEnv* env,
211                                                           jobject clazz,
212                                                           jint netId,
213                                                           jstring name,
214                                                           jstring value)
215{
216    char cmdstr[BUF_SIZE];
217    jboolean isCopy;
218
219    const char *nameStr = env->GetStringUTFChars(name, &isCopy);
220    const char *valueStr = env->GetStringUTFChars(value, &isCopy);
221
222    if (nameStr == NULL || valueStr == NULL)
223        return JNI_FALSE;
224
225    int cmdTooLong = snprintf(cmdstr, sizeof(cmdstr), "SET_NETWORK %d %s %s",
226                 netId, nameStr, valueStr) >= (int)sizeof(cmdstr);
227
228    env->ReleaseStringUTFChars(name, nameStr);
229    env->ReleaseStringUTFChars(value, valueStr);
230
231    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
232}
233
234static jstring android_net_wifi_getNetworkVariableCommand(JNIEnv* env,
235                                                          jobject clazz,
236                                                          jint netId,
237                                                          jstring name)
238{
239    char cmdstr[BUF_SIZE];
240    jboolean isCopy;
241
242    const char *nameStr = env->GetStringUTFChars(name, &isCopy);
243
244    if (nameStr == NULL)
245        return env->NewStringUTF(NULL);
246
247    int cmdTooLong = snprintf(cmdstr, sizeof(cmdstr), "GET_NETWORK %d %s",
248                             netId, nameStr) >= (int)sizeof(cmdstr);
249
250    env->ReleaseStringUTFChars(name, nameStr);
251
252    return cmdTooLong ? env->NewStringUTF(NULL) : doStringCommand(env, cmdstr);
253}
254
255static jboolean android_net_wifi_removeNetworkCommand(JNIEnv* env, jobject clazz, jint netId)
256{
257    char cmdstr[BUF_SIZE];
258
259    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "REMOVE_NETWORK %d", netId);
260    int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
261
262    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
263}
264
265static jboolean android_net_wifi_enableNetworkCommand(JNIEnv* env,
266                                                  jobject clazz,
267                                                  jint netId,
268                                                  jboolean disableOthers)
269{
270    char cmdstr[BUF_SIZE];
271    const char *cmd = disableOthers ? "SELECT_NETWORK" : "ENABLE_NETWORK";
272
273    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "%s %d", cmd, netId);
274    int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
275
276    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
277}
278
279static jboolean android_net_wifi_disableNetworkCommand(JNIEnv* env, jobject clazz, jint netId)
280{
281    char cmdstr[BUF_SIZE];
282
283    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DISABLE_NETWORK %d", netId);
284    int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
285
286    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
287}
288
289static jstring android_net_wifi_statusCommand(JNIEnv* env, jobject clazz)
290{
291    return doStringCommand(env, "STATUS");
292}
293
294static jboolean android_net_wifi_pingCommand(JNIEnv* env, jobject clazz)
295{
296    return doBooleanCommand("PING", "PONG");
297}
298
299static jstring android_net_wifi_scanResultsCommand(JNIEnv* env, jobject clazz)
300{
301    return doStringCommand(env, "SCAN_RESULTS");
302}
303
304static jboolean android_net_wifi_disconnectCommand(JNIEnv* env, jobject clazz)
305{
306    return doBooleanCommand("DISCONNECT", "OK");
307}
308
309static jboolean android_net_wifi_reconnectCommand(JNIEnv* env, jobject clazz)
310{
311    return doBooleanCommand("RECONNECT", "OK");
312}
313static jboolean android_net_wifi_reassociateCommand(JNIEnv* env, jobject clazz)
314{
315    return doBooleanCommand("REASSOCIATE", "OK");
316}
317
318static jboolean doSetScanMode(jboolean setActive)
319{
320    return doBooleanCommand((setActive ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE"), "OK");
321}
322
323static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject clazz, jboolean forceActive)
324{
325    jboolean result;
326
327    // Ignore any error from setting the scan mode.
328    // The scan will still work.
329    if (forceActive && !sScanModeActive)
330        doSetScanMode(true);
331    result = doBooleanCommand("SCAN", "OK");
332    if (forceActive && !sScanModeActive)
333        doSetScanMode(sScanModeActive);
334    return result;
335}
336
337static jboolean android_net_wifi_setScanModeCommand(JNIEnv* env, jobject clazz, jboolean setActive)
338{
339    sScanModeActive = setActive;
340    return doSetScanMode(setActive);
341}
342
343static jboolean android_net_wifi_startDriverCommand(JNIEnv* env, jobject clazz)
344{
345    return doBooleanCommand("DRIVER START", "OK");
346}
347
348static jboolean android_net_wifi_stopDriverCommand(JNIEnv* env, jobject clazz)
349{
350    return doBooleanCommand("DRIVER STOP", "OK");
351}
352
353static jboolean android_net_wifi_startPacketFiltering(JNIEnv* env, jobject clazz)
354{
355    return doBooleanCommand("DRIVER RXFILTER-ADD 0", "OK")
356	&& doBooleanCommand("DRIVER RXFILTER-ADD 1", "OK")
357	&& doBooleanCommand("DRIVER RXFILTER-ADD 3", "OK")
358	&& doBooleanCommand("DRIVER RXFILTER-START", "OK");
359}
360
361static jboolean android_net_wifi_stopPacketFiltering(JNIEnv* env, jobject clazz)
362{
363    jboolean result = doBooleanCommand("DRIVER RXFILTER-STOP", "OK");
364    if (result) {
365	(void)doBooleanCommand("DRIVER RXFILTER-REMOVE 3", "OK");
366	(void)doBooleanCommand("DRIVER RXFILTER-REMOVE 1", "OK");
367	(void)doBooleanCommand("DRIVER RXFILTER-REMOVE 0", "OK");
368    }
369
370    return result;
371}
372
373static jint android_net_wifi_getRssiHelper(const char *cmd)
374{
375    char reply[BUF_SIZE];
376    int rssi = -200;
377
378    if (doCommand(cmd, reply, sizeof(reply)) != 0) {
379        return (jint)-1;
380    }
381
382    // reply comes back in the form "<SSID> rssi XX" where XX is the
383    // number we're interested in.  if we're associating, it returns "OK".
384    // beware - <SSID> can contain spaces.
385    if (strcmp(reply, "OK") != 0) {
386        // beware of trailing spaces
387        char* end = reply + strlen(reply);
388        while (end > reply && end[-1] == ' ') {
389            end--;
390        }
391        *end = 0;
392
393        char* lastSpace = strrchr(reply, ' ');
394        // lastSpace should be preceded by "rssi" and followed by the value
395        if (lastSpace && !strncasecmp(lastSpace - 4, "rssi", 4)) {
396            sscanf(lastSpace + 1, "%d", &rssi);
397        }
398    }
399    return (jint)rssi;
400}
401
402static jint android_net_wifi_getRssiCommand(JNIEnv* env, jobject clazz)
403{
404    return android_net_wifi_getRssiHelper("DRIVER RSSI");
405}
406
407static jint android_net_wifi_getRssiApproxCommand(JNIEnv* env, jobject clazz)
408{
409    return android_net_wifi_getRssiHelper("DRIVER RSSI-APPROX");
410}
411
412static jint android_net_wifi_getLinkSpeedCommand(JNIEnv* env, jobject clazz)
413{
414    char reply[BUF_SIZE];
415    int linkspeed;
416
417    if (doCommand("DRIVER LINKSPEED", reply, sizeof(reply)) != 0) {
418        return (jint)-1;
419    }
420    // reply comes back in the form "LinkSpeed XX" where XX is the
421    // number we're interested in.
422    sscanf(reply, "%*s %u", &linkspeed);
423    return (jint)linkspeed;
424}
425
426static jstring android_net_wifi_getMacAddressCommand(JNIEnv* env, jobject clazz)
427{
428    char reply[BUF_SIZE];
429    char buf[BUF_SIZE];
430
431    if (doCommand("DRIVER MACADDR", reply, sizeof(reply)) != 0) {
432        return env->NewStringUTF(NULL);
433    }
434    // reply comes back in the form "Macaddr = XX.XX.XX.XX.XX.XX" where XX
435    // is the part of the string we're interested in.
436    if (sscanf(reply, "%*s = %255s", buf) == 1)
437        return env->NewStringUTF(buf);
438    else
439        return env->NewStringUTF(NULL);
440}
441
442static jboolean android_net_wifi_setPowerModeCommand(JNIEnv* env, jobject clazz, jint mode)
443{
444    char cmdstr[BUF_SIZE];
445
446    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER POWERMODE %d", mode);
447    int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
448
449    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
450}
451
452static jint android_net_wifi_getPowerModeCommand(JNIEnv* env, jobject clazz)
453{
454    char reply[BUF_SIZE];
455    int power;
456
457    if (doCommand("DRIVER GETPOWER", reply, sizeof(reply)) != 0) {
458        return (jint)-1;
459    }
460    // reply comes back in the form "powermode = XX" where XX is the
461    // number we're interested in.
462    sscanf(reply, "%*s = %u", &power);
463    return (jint)power;
464}
465
466static jboolean android_net_wifi_setBandCommand(JNIEnv* env, jobject clazz, jint band)
467{
468    char cmdstr[25];
469
470    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER SETBAND %d", band);
471    int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
472
473    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
474}
475
476static jint android_net_wifi_getBandCommand(JNIEnv* env, jobject clazz)
477{
478    char reply[25];
479    int band;
480
481    if (doCommand("DRIVER GETBAND", reply, sizeof(reply)) != 0) {
482        return (jint)-1;
483    }
484    // reply comes back in the form "Band X" where X is the
485    // number we're interested in.
486    sscanf(reply, "%*s %u", &band);
487    return (jint)band;
488}
489
490static jboolean android_net_wifi_setBluetoothCoexistenceModeCommand(JNIEnv* env, jobject clazz, jint mode)
491{
492    char cmdstr[BUF_SIZE];
493
494    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER BTCOEXMODE %d", mode);
495    int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
496
497    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
498}
499
500static jboolean android_net_wifi_setBluetoothCoexistenceScanModeCommand(JNIEnv* env, jobject clazz, jboolean setCoexScanMode)
501{
502    char cmdstr[BUF_SIZE];
503
504    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER BTCOEXSCAN-%s", setCoexScanMode ? "START" : "STOP");
505    int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
506
507    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
508}
509
510static jboolean android_net_wifi_saveConfigCommand(JNIEnv* env, jobject clazz)
511{
512    // Make sure we never write out a value for AP_SCAN other than 1
513    (void)doBooleanCommand("AP_SCAN 1", "OK");
514    return doBooleanCommand("SAVE_CONFIG", "OK");
515}
516
517static jboolean android_net_wifi_reloadConfigCommand(JNIEnv* env, jobject clazz)
518{
519    return doBooleanCommand("RECONFIGURE", "OK");
520}
521
522static jboolean android_net_wifi_setScanResultHandlingCommand(JNIEnv* env, jobject clazz, jint mode)
523{
524    char cmdstr[BUF_SIZE];
525
526    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "AP_SCAN %d", mode);
527    int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
528
529    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
530}
531
532static jboolean android_net_wifi_addToBlacklistCommand(JNIEnv* env, jobject clazz, jstring bssid)
533{
534    char cmdstr[BUF_SIZE];
535    jboolean isCopy;
536
537    const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
538
539    int cmdTooLong = snprintf(cmdstr, sizeof(cmdstr), "BLACKLIST %s", bssidStr) >= (int)sizeof(cmdstr);
540
541    env->ReleaseStringUTFChars(bssid, bssidStr);
542
543    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
544}
545
546static jboolean android_net_wifi_clearBlacklistCommand(JNIEnv* env, jobject clazz)
547{
548    return doBooleanCommand("BLACKLIST clear", "OK");
549}
550
551static jboolean android_net_wifi_setSuspendOptimizationsCommand(JNIEnv* env, jobject clazz, jboolean enabled)
552{
553    char cmdstr[BUF_SIZE];
554
555    snprintf(cmdstr, sizeof(cmdstr), "DRIVER SETSUSPENDOPT %d", enabled ? 0 : 1);
556    return doBooleanCommand(cmdstr, "OK");
557}
558
559static void android_net_wifi_enableBackgroundScanCommand(JNIEnv* env, jobject clazz, jboolean enable)
560{
561    //Note: BGSCAN-START and BGSCAN-STOP are documented in core/res/res/values/config.xml
562    //and will need an update if the names are changed
563    if (enable) {
564        doBooleanCommand("DRIVER BGSCAN-START", "OK");
565    }
566    else {
567        doBooleanCommand("DRIVER BGSCAN-STOP", "OK");
568    }
569}
570
571static void android_net_wifi_setScanIntervalCommand(JNIEnv* env, jobject clazz, jint scanInterval)
572{
573    char cmdstr[BUF_SIZE];
574
575    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "SCAN_INTERVAL %d", scanInterval);
576
577    if(numWritten < (int)sizeof(cmdstr)) doBooleanCommand(cmdstr, "OK");
578}
579
580
581// ----------------------------------------------------------------------------
582
583/*
584 * JNI registration.
585 */
586static JNINativeMethod gWifiMethods[] = {
587    /* name, signature, funcPtr */
588
589    { "loadDriver", "()Z",  (void *)android_net_wifi_loadDriver },
590    { "isDriverLoaded", "()Z",  (void *)android_net_wifi_isDriverLoaded},
591    { "unloadDriver", "()Z",  (void *)android_net_wifi_unloadDriver },
592    { "startSupplicant", "()Z",  (void *)android_net_wifi_startSupplicant },
593    { "stopSupplicant", "()Z", (void*) android_net_wifi_stopSupplicant },
594    { "killSupplicant", "()Z",  (void *)android_net_wifi_killSupplicant },
595    { "connectToSupplicant", "()Z",  (void *)android_net_wifi_connectToSupplicant },
596    { "closeSupplicantConnection", "()V",  (void *)android_net_wifi_closeSupplicantConnection },
597
598    { "listNetworksCommand", "()Ljava/lang/String;",
599        (void*) android_net_wifi_listNetworksCommand },
600    { "addNetworkCommand", "()I", (void*) android_net_wifi_addNetworkCommand },
601    { "setNetworkVariableCommand", "(ILjava/lang/String;Ljava/lang/String;)Z",
602        (void*) android_net_wifi_setNetworkVariableCommand },
603    { "getNetworkVariableCommand", "(ILjava/lang/String;)Ljava/lang/String;",
604        (void*) android_net_wifi_getNetworkVariableCommand },
605    { "removeNetworkCommand", "(I)Z", (void*) android_net_wifi_removeNetworkCommand },
606    { "enableNetworkCommand", "(IZ)Z", (void*) android_net_wifi_enableNetworkCommand },
607    { "disableNetworkCommand", "(I)Z", (void*) android_net_wifi_disableNetworkCommand },
608    { "waitForEvent", "()Ljava/lang/String;", (void*) android_net_wifi_waitForEvent },
609    { "statusCommand", "()Ljava/lang/String;", (void*) android_net_wifi_statusCommand },
610    { "scanResultsCommand", "()Ljava/lang/String;", (void*) android_net_wifi_scanResultsCommand },
611    { "pingCommand", "()Z",  (void *)android_net_wifi_pingCommand },
612    { "disconnectCommand", "()Z",  (void *)android_net_wifi_disconnectCommand },
613    { "reconnectCommand", "()Z",  (void *)android_net_wifi_reconnectCommand },
614    { "reassociateCommand", "()Z",  (void *)android_net_wifi_reassociateCommand },
615    { "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
616    { "setScanModeCommand", "(Z)Z", (void*) android_net_wifi_setScanModeCommand },
617    { "startDriverCommand", "()Z", (void*) android_net_wifi_startDriverCommand },
618    { "stopDriverCommand", "()Z", (void*) android_net_wifi_stopDriverCommand },
619    { "startPacketFiltering", "()Z", (void*) android_net_wifi_startPacketFiltering },
620    { "stopPacketFiltering", "()Z", (void*) android_net_wifi_stopPacketFiltering },
621    { "setPowerModeCommand", "(I)Z", (void*) android_net_wifi_setPowerModeCommand },
622    { "getPowerModeCommand", "()I", (void*) android_net_wifi_getPowerModeCommand },
623    { "setBandCommand", "(I)Z", (void*) android_net_wifi_setBandCommand},
624    { "getBandCommand", "()I", (void*) android_net_wifi_getBandCommand},
625    { "setBluetoothCoexistenceModeCommand", "(I)Z",
626    		(void*) android_net_wifi_setBluetoothCoexistenceModeCommand },
627    { "setBluetoothCoexistenceScanModeCommand", "(Z)Z",
628    		(void*) android_net_wifi_setBluetoothCoexistenceScanModeCommand },
629    { "getRssiCommand", "()I", (void*) android_net_wifi_getRssiCommand },
630    { "getRssiApproxCommand", "()I",
631            (void*) android_net_wifi_getRssiApproxCommand},
632    { "getLinkSpeedCommand", "()I", (void*) android_net_wifi_getLinkSpeedCommand },
633    { "getMacAddressCommand", "()Ljava/lang/String;", (void*) android_net_wifi_getMacAddressCommand },
634    { "saveConfigCommand", "()Z", (void*) android_net_wifi_saveConfigCommand },
635    { "reloadConfigCommand", "()Z", (void*) android_net_wifi_reloadConfigCommand },
636    { "setScanResultHandlingCommand", "(I)Z", (void*) android_net_wifi_setScanResultHandlingCommand },
637    { "addToBlacklistCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_addToBlacklistCommand },
638    { "clearBlacklistCommand", "()Z", (void*) android_net_wifi_clearBlacklistCommand },
639    { "startWpsPbcCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_wpsPbcCommand },
640    { "startWpsWithPinFromAccessPointCommand", "(Ljava/lang/String;Ljava/lang/String;)Z",
641        (void*) android_net_wifi_wpsPinFromAccessPointCommand },
642    { "startWpsWithPinFromDeviceCommand", "(Ljava/lang/String;)Ljava/lang/String;",
643        (void*) android_net_wifi_wpsPinFromDeviceCommand },
644    { "setSuspendOptimizationsCommand", "(Z)Z",
645        (void*) android_net_wifi_setSuspendOptimizationsCommand},
646    { "setCountryCodeCommand", "(Ljava/lang/String;)Z",
647        (void*) android_net_wifi_setCountryCodeCommand},
648    { "enableBackgroundScanCommand", "(Z)V", (void*) android_net_wifi_enableBackgroundScanCommand},
649    { "setScanIntervalCommand", "(I)V", (void*) android_net_wifi_setScanIntervalCommand},
650};
651
652int register_android_net_wifi_WifiManager(JNIEnv* env)
653{
654    return AndroidRuntime::registerNativeMethods(env,
655            WIFI_PKG_NAME, gWifiMethods, NELEM(gWifiMethods));
656}
657
658}; // namespace android
659