• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 #include "wifi.h"
25 
26 #define WIFI_PKG_NAME "android/net/wifi/WifiNative"
27 
28 namespace android {
29 
30 static jboolean sScanModeActive = false;
31 
32 /*
33  * The following remembers the jfieldID's of the fields
34  * of the DhcpInfo Java object, so that we don't have
35  * to look them up every time.
36  */
37 static struct fieldIds {
38     jclass dhcpInfoClass;
39     jmethodID constructorId;
40     jfieldID ipaddress;
41     jfieldID gateway;
42     jfieldID netmask;
43     jfieldID dns1;
44     jfieldID dns2;
45     jfieldID serverAddress;
46     jfieldID leaseDuration;
47 } dhcpInfoFieldIds;
48 
doCommand(const char * cmd,char * replybuf,int replybuflen)49 static int doCommand(const char *cmd, char *replybuf, int replybuflen)
50 {
51     size_t reply_len = replybuflen - 1;
52 
53     if (::wifi_command(cmd, replybuf, &reply_len) != 0)
54         return -1;
55     else {
56         // Strip off trailing newline
57         if (reply_len > 0 && replybuf[reply_len-1] == '\n')
58             replybuf[reply_len-1] = '\0';
59         else
60             replybuf[reply_len] = '\0';
61         return 0;
62     }
63 }
64 
doIntCommand(const char * cmd)65 static jint doIntCommand(const char *cmd)
66 {
67     char reply[256];
68 
69     if (doCommand(cmd, reply, sizeof(reply)) != 0) {
70         return (jint)-1;
71     } else {
72         return (jint)atoi(reply);
73     }
74 }
75 
doBooleanCommand(const char * cmd,const char * expect)76 static jboolean doBooleanCommand(const char *cmd, const char *expect)
77 {
78     char reply[256];
79 
80     if (doCommand(cmd, reply, sizeof(reply)) != 0) {
81         return (jboolean)JNI_FALSE;
82     } else {
83         return (jboolean)(strcmp(reply, expect) == 0);
84     }
85 }
86 
87 // Send a command to the supplicant, and return the reply as a String
doStringCommand(JNIEnv * env,const char * cmd)88 static jstring doStringCommand(JNIEnv *env, const char *cmd)
89 {
90     char reply[4096];
91 
92     if (doCommand(cmd, reply, sizeof(reply)) != 0) {
93         return env->NewStringUTF(NULL);
94     } else {
95         return env->NewStringUTF(reply);
96     }
97 }
98 
android_net_wifi_loadDriver(JNIEnv * env,jobject clazz)99 static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject clazz)
100 {
101     return (jboolean)(::wifi_load_driver() == 0);
102 }
103 
android_net_wifi_unloadDriver(JNIEnv * env,jobject clazz)104 static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject clazz)
105 {
106     return (jboolean)(::wifi_unload_driver() == 0);
107 }
108 
android_net_wifi_startSupplicant(JNIEnv * env,jobject clazz)109 static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject clazz)
110 {
111     return (jboolean)(::wifi_start_supplicant() == 0);
112 }
113 
android_net_wifi_stopSupplicant(JNIEnv * env,jobject clazz)114 static jboolean android_net_wifi_stopSupplicant(JNIEnv* env, jobject clazz)
115 {
116     return (jboolean)(::wifi_stop_supplicant() == 0);
117 }
118 
android_net_wifi_connectToSupplicant(JNIEnv * env,jobject clazz)119 static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject clazz)
120 {
121     return (jboolean)(::wifi_connect_to_supplicant() == 0);
122 }
123 
android_net_wifi_closeSupplicantConnection(JNIEnv * env,jobject clazz)124 static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject clazz)
125 {
126     ::wifi_close_supplicant_connection();
127 }
128 
android_net_wifi_waitForEvent(JNIEnv * env,jobject clazz)129 static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject clazz)
130 {
131     char buf[256];
132 
133     int nread = ::wifi_wait_for_event(buf, sizeof buf);
134     if (nread > 0) {
135         return env->NewStringUTF(buf);
136     } else {
137         return  env->NewStringUTF(NULL);
138     }
139 }
140 
android_net_wifi_listNetworksCommand(JNIEnv * env,jobject clazz)141 static jstring android_net_wifi_listNetworksCommand(JNIEnv* env, jobject clazz)
142 {
143     return doStringCommand(env, "LIST_NETWORKS");
144 }
145 
android_net_wifi_addNetworkCommand(JNIEnv * env,jobject clazz)146 static jint android_net_wifi_addNetworkCommand(JNIEnv* env, jobject clazz)
147 {
148     return doIntCommand("ADD_NETWORK");
149 }
150 
android_net_wifi_setNetworkVariableCommand(JNIEnv * env,jobject clazz,jint netId,jstring name,jstring value)151 static jboolean android_net_wifi_setNetworkVariableCommand(JNIEnv* env,
152                                                            jobject clazz,
153                                                            jint netId,
154                                                            jstring name,
155                                                            jstring value)
156 {
157     char cmdstr[256];
158     jboolean isCopy;
159 
160     const char *nameStr = env->GetStringUTFChars(name, &isCopy);
161     const char *valueStr = env->GetStringUTFChars(value, &isCopy);
162 
163     if (nameStr == NULL || valueStr == NULL)
164         return JNI_FALSE;
165 
166     int cmdTooLong = snprintf(cmdstr, sizeof(cmdstr), "SET_NETWORK %d %s %s",
167                  netId, nameStr, valueStr) >= (int)sizeof(cmdstr);
168 
169     env->ReleaseStringUTFChars(name, nameStr);
170     env->ReleaseStringUTFChars(value, valueStr);
171 
172     return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
173 }
174 
android_net_wifi_getNetworkVariableCommand(JNIEnv * env,jobject clazz,jint netId,jstring name)175 static jstring android_net_wifi_getNetworkVariableCommand(JNIEnv* env,
176                                                           jobject clazz,
177                                                           jint netId,
178                                                           jstring name)
179 {
180     char cmdstr[256];
181     jboolean isCopy;
182 
183     const char *nameStr = env->GetStringUTFChars(name, &isCopy);
184 
185     if (nameStr == NULL)
186         return env->NewStringUTF(NULL);
187 
188     int cmdTooLong = snprintf(cmdstr, sizeof(cmdstr), "GET_NETWORK %d %s",
189                              netId, nameStr) >= (int)sizeof(cmdstr);
190 
191     env->ReleaseStringUTFChars(name, nameStr);
192 
193     return cmdTooLong ? env->NewStringUTF(NULL) : doStringCommand(env, cmdstr);
194 }
195 
android_net_wifi_removeNetworkCommand(JNIEnv * env,jobject clazz,jint netId)196 static jboolean android_net_wifi_removeNetworkCommand(JNIEnv* env, jobject clazz, jint netId)
197 {
198     char cmdstr[256];
199 
200     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "REMOVE_NETWORK %d", netId);
201     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
202 
203     return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
204 }
205 
android_net_wifi_enableNetworkCommand(JNIEnv * env,jobject clazz,jint netId,jboolean disableOthers)206 static jboolean android_net_wifi_enableNetworkCommand(JNIEnv* env,
207                                                   jobject clazz,
208                                                   jint netId,
209                                                   jboolean disableOthers)
210 {
211     char cmdstr[256];
212     const char *cmd = disableOthers ? "SELECT_NETWORK" : "ENABLE_NETWORK";
213 
214     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "%s %d", cmd, netId);
215     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
216 
217     return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
218 }
219 
android_net_wifi_disableNetworkCommand(JNIEnv * env,jobject clazz,jint netId)220 static jboolean android_net_wifi_disableNetworkCommand(JNIEnv* env, jobject clazz, jint netId)
221 {
222     char cmdstr[256];
223 
224     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DISABLE_NETWORK %d", netId);
225     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
226 
227     return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
228 }
229 
android_net_wifi_statusCommand(JNIEnv * env,jobject clazz)230 static jstring android_net_wifi_statusCommand(JNIEnv* env, jobject clazz)
231 {
232     return doStringCommand(env, "STATUS");
233 }
234 
android_net_wifi_pingCommand(JNIEnv * env,jobject clazz)235 static jboolean android_net_wifi_pingCommand(JNIEnv* env, jobject clazz)
236 {
237     return doBooleanCommand("PING", "PONG");
238 }
239 
android_net_wifi_scanResultsCommand(JNIEnv * env,jobject clazz)240 static jstring android_net_wifi_scanResultsCommand(JNIEnv* env, jobject clazz)
241 {
242     return doStringCommand(env, "SCAN_RESULTS");
243 }
244 
android_net_wifi_disconnectCommand(JNIEnv * env,jobject clazz)245 static jboolean android_net_wifi_disconnectCommand(JNIEnv* env, jobject clazz)
246 {
247     return doBooleanCommand("DISCONNECT", "OK");
248 }
249 
android_net_wifi_reconnectCommand(JNIEnv * env,jobject clazz)250 static jboolean android_net_wifi_reconnectCommand(JNIEnv* env, jobject clazz)
251 {
252     return doBooleanCommand("RECONNECT", "OK");
253 }
android_net_wifi_reassociateCommand(JNIEnv * env,jobject clazz)254 static jboolean android_net_wifi_reassociateCommand(JNIEnv* env, jobject clazz)
255 {
256     return doBooleanCommand("REASSOCIATE", "OK");
257 }
258 
doSetScanMode(jboolean setActive)259 static jboolean doSetScanMode(jboolean setActive)
260 {
261     return doBooleanCommand((setActive ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE"), "OK");
262 }
263 
android_net_wifi_scanCommand(JNIEnv * env,jobject clazz,jboolean forceActive)264 static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject clazz, jboolean forceActive)
265 {
266     jboolean result;
267 
268     // Ignore any error from setting the scan mode.
269     // The scan will still work.
270     if (forceActive && !sScanModeActive)
271         doSetScanMode(true);
272     result = doBooleanCommand("SCAN", "OK");
273     if (forceActive && !sScanModeActive)
274         doSetScanMode(sScanModeActive);
275     return result;
276 }
277 
android_net_wifi_setScanModeCommand(JNIEnv * env,jobject clazz,jboolean setActive)278 static jboolean android_net_wifi_setScanModeCommand(JNIEnv* env, jobject clazz, jboolean setActive)
279 {
280     sScanModeActive = setActive;
281     return doSetScanMode(setActive);
282 }
283 
android_net_wifi_startDriverCommand(JNIEnv * env,jobject clazz)284 static jboolean android_net_wifi_startDriverCommand(JNIEnv* env, jobject clazz)
285 {
286     return doBooleanCommand("DRIVER START", "OK");
287 }
288 
android_net_wifi_stopDriverCommand(JNIEnv * env,jobject clazz)289 static jboolean android_net_wifi_stopDriverCommand(JNIEnv* env, jobject clazz)
290 {
291     return doBooleanCommand("DRIVER STOP", "OK");
292 }
293 
android_net_wifi_startPacketFiltering(JNIEnv * env,jobject clazz)294 static jboolean android_net_wifi_startPacketFiltering(JNIEnv* env, jobject clazz)
295 {
296     return doBooleanCommand("DRIVER RXFILTER-ADD 0", "OK")
297 	&& doBooleanCommand("DRIVER RXFILTER-ADD 1", "OK")
298 	&& doBooleanCommand("DRIVER RXFILTER-ADD 3", "OK")
299 	&& doBooleanCommand("DRIVER RXFILTER-START", "OK");
300 }
301 
android_net_wifi_stopPacketFiltering(JNIEnv * env,jobject clazz)302 static jboolean android_net_wifi_stopPacketFiltering(JNIEnv* env, jobject clazz)
303 {
304     jboolean result = doBooleanCommand("DRIVER RXFILTER-STOP", "OK");
305     if (result) {
306 	(void)doBooleanCommand("DRIVER RXFILTER-REMOVE 3", "OK");
307 	(void)doBooleanCommand("DRIVER RXFILTER-REMOVE 1", "OK");
308 	(void)doBooleanCommand("DRIVER RXFILTER-REMOVE 0", "OK");
309     }
310 
311     return result;
312 }
313 
android_net_wifi_getRssiHelper(const char * cmd)314 static jint android_net_wifi_getRssiHelper(const char *cmd)
315 {
316     char reply[256];
317     int rssi = -200;
318 
319     if (doCommand(cmd, reply, sizeof(reply)) != 0) {
320         return (jint)-1;
321     }
322 
323     // reply comes back in the form "<SSID> rssi XX" where XX is the
324     // number we're interested in.  if we're associating, it returns "OK".
325     // beware - <SSID> can contain spaces.
326     if (strcmp(reply, "OK") != 0) {
327         // beware of trailing spaces
328         char* end = reply + strlen(reply);
329         while (end > reply && end[-1] == ' ') {
330             end--;
331         }
332         *end = 0;
333 
334         char* lastSpace = strrchr(reply, ' ');
335         // lastSpace should be preceded by "rssi" and followed by the value
336         if (lastSpace && !strncmp(lastSpace - 4, "rssi", 4)) {
337             sscanf(lastSpace + 1, "%d", &rssi);
338         }
339     }
340     return (jint)rssi;
341 }
342 
android_net_wifi_getRssiCommand(JNIEnv * env,jobject clazz)343 static jint android_net_wifi_getRssiCommand(JNIEnv* env, jobject clazz)
344 {
345     return android_net_wifi_getRssiHelper("DRIVER RSSI");
346 }
347 
android_net_wifi_getRssiApproxCommand(JNIEnv * env,jobject clazz)348 static jint android_net_wifi_getRssiApproxCommand(JNIEnv* env, jobject clazz)
349 {
350     return android_net_wifi_getRssiHelper("DRIVER RSSI-APPROX");
351 }
352 
android_net_wifi_getLinkSpeedCommand(JNIEnv * env,jobject clazz)353 static jint android_net_wifi_getLinkSpeedCommand(JNIEnv* env, jobject clazz)
354 {
355     char reply[256];
356     int linkspeed;
357 
358     if (doCommand("DRIVER LINKSPEED", reply, sizeof(reply)) != 0) {
359         return (jint)-1;
360     }
361     // reply comes back in the form "LinkSpeed XX" where XX is the
362     // number we're interested in.
363     sscanf(reply, "%*s %u", &linkspeed);
364     return (jint)linkspeed;
365 }
366 
android_net_wifi_getMacAddressCommand(JNIEnv * env,jobject clazz)367 static jstring android_net_wifi_getMacAddressCommand(JNIEnv* env, jobject clazz)
368 {
369     char reply[256];
370     char buf[256];
371 
372     if (doCommand("DRIVER MACADDR", reply, sizeof(reply)) != 0) {
373         return env->NewStringUTF(NULL);
374     }
375     // reply comes back in the form "Macaddr = XX.XX.XX.XX.XX.XX" where XX
376     // is the part of the string we're interested in.
377     if (sscanf(reply, "%*s = %255s", buf) == 1)
378         return env->NewStringUTF(buf);
379     else
380         return env->NewStringUTF(NULL);
381 }
382 
android_net_wifi_setPowerModeCommand(JNIEnv * env,jobject clazz,jint mode)383 static jboolean android_net_wifi_setPowerModeCommand(JNIEnv* env, jobject clazz, jint mode)
384 {
385     char cmdstr[256];
386 
387     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER POWERMODE %d", mode);
388     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
389 
390     return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
391 }
392 
android_net_wifi_setNumAllowedChannelsCommand(JNIEnv * env,jobject clazz,jint numChannels)393 static jboolean android_net_wifi_setNumAllowedChannelsCommand(JNIEnv* env, jobject clazz, jint numChannels)
394 {
395     char cmdstr[256];
396 
397     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER SCAN-CHANNELS %u", numChannels);
398     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
399 
400     return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
401 }
402 
android_net_wifi_getNumAllowedChannelsCommand(JNIEnv * env,jobject clazz)403 static jint android_net_wifi_getNumAllowedChannelsCommand(JNIEnv* env, jobject clazz)
404 {
405     char reply[256];
406     int numChannels;
407 
408     if (doCommand("DRIVER SCAN-CHANNELS", reply, sizeof(reply)) != 0) {
409         return -1;
410     }
411     // reply comes back in the form "Scan-Channels = X" where X is the
412     // number of channels
413     if (sscanf(reply, "%*s = %u", &numChannels) == 1)
414         return numChannels;
415     else
416         return -1;
417 }
418 
android_net_wifi_setBluetoothCoexistenceModeCommand(JNIEnv * env,jobject clazz,jint mode)419 static jboolean android_net_wifi_setBluetoothCoexistenceModeCommand(JNIEnv* env, jobject clazz, jint mode)
420 {
421     char cmdstr[256];
422 
423     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER BTCOEXMODE %d", mode);
424     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
425 
426     return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
427 }
428 
android_net_wifi_setBluetoothCoexistenceScanModeCommand(JNIEnv * env,jobject clazz,jboolean setCoexScanMode)429 static jboolean android_net_wifi_setBluetoothCoexistenceScanModeCommand(JNIEnv* env, jobject clazz, jboolean setCoexScanMode)
430 {
431     char cmdstr[256];
432 
433     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER BTCOEXSCAN-%s", setCoexScanMode ? "START" : "STOP");
434     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
435 
436     return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
437 }
438 
android_net_wifi_saveConfigCommand(JNIEnv * env,jobject clazz)439 static jboolean android_net_wifi_saveConfigCommand(JNIEnv* env, jobject clazz)
440 {
441     // Make sure we never write out a value for AP_SCAN other than 1
442     (void)doBooleanCommand("AP_SCAN 1", "OK");
443     return doBooleanCommand("SAVE_CONFIG", "OK");
444 }
445 
android_net_wifi_reloadConfigCommand(JNIEnv * env,jobject clazz)446 static jboolean android_net_wifi_reloadConfigCommand(JNIEnv* env, jobject clazz)
447 {
448     return doBooleanCommand("RECONFIGURE", "OK");
449 }
450 
android_net_wifi_setScanResultHandlingCommand(JNIEnv * env,jobject clazz,jint mode)451 static jboolean android_net_wifi_setScanResultHandlingCommand(JNIEnv* env, jobject clazz, jint mode)
452 {
453     char cmdstr[256];
454 
455     int numWritten = snprintf(cmdstr, sizeof(cmdstr), "AP_SCAN %d", mode);
456     int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
457 
458     return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
459 }
460 
android_net_wifi_addToBlacklistCommand(JNIEnv * env,jobject clazz,jstring bssid)461 static jboolean android_net_wifi_addToBlacklistCommand(JNIEnv* env, jobject clazz, jstring bssid)
462 {
463     char cmdstr[256];
464     jboolean isCopy;
465 
466     const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
467 
468     int cmdTooLong = snprintf(cmdstr, sizeof(cmdstr), "BLACKLIST %s", bssidStr) >= (int)sizeof(cmdstr);
469 
470     env->ReleaseStringUTFChars(bssid, bssidStr);
471 
472     return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
473 }
474 
android_net_wifi_clearBlacklistCommand(JNIEnv * env,jobject clazz)475 static jboolean android_net_wifi_clearBlacklistCommand(JNIEnv* env, jobject clazz)
476 {
477     return doBooleanCommand("BLACKLIST clear", "OK");
478 }
479 
android_net_wifi_doDhcpRequest(JNIEnv * env,jobject clazz,jobject info)480 static jboolean android_net_wifi_doDhcpRequest(JNIEnv* env, jobject clazz, jobject info)
481 {
482     jint ipaddr, gateway, mask, dns1, dns2, server, lease;
483     jboolean succeeded = ((jboolean)::do_dhcp_request(&ipaddr, &gateway, &mask,
484                                         &dns1, &dns2, &server, &lease) == 0);
485     if (succeeded && dhcpInfoFieldIds.dhcpInfoClass != NULL) {
486         env->SetIntField(info, dhcpInfoFieldIds.ipaddress, ipaddr);
487         env->SetIntField(info, dhcpInfoFieldIds.gateway, gateway);
488         env->SetIntField(info, dhcpInfoFieldIds.netmask, mask);
489         env->SetIntField(info, dhcpInfoFieldIds.dns1, dns1);
490         env->SetIntField(info, dhcpInfoFieldIds.dns2, dns2);
491         env->SetIntField(info, dhcpInfoFieldIds.serverAddress, server);
492         env->SetIntField(info, dhcpInfoFieldIds.leaseDuration, lease);
493     }
494     return succeeded;
495 }
496 
android_net_wifi_getDhcpError(JNIEnv * env,jobject clazz)497 static jstring android_net_wifi_getDhcpError(JNIEnv* env, jobject clazz)
498 {
499     return env->NewStringUTF(::get_dhcp_error_string());
500 }
501 
502 // ----------------------------------------------------------------------------
503 
504 /*
505  * JNI registration.
506  */
507 static JNINativeMethod gWifiMethods[] = {
508     /* name, signature, funcPtr */
509 
510     { "loadDriver", "()Z",  (void *)android_net_wifi_loadDriver },
511     { "unloadDriver", "()Z",  (void *)android_net_wifi_unloadDriver },
512     { "startSupplicant", "()Z",  (void *)android_net_wifi_startSupplicant },
513     { "stopSupplicant", "()Z",  (void *)android_net_wifi_stopSupplicant },
514     { "connectToSupplicant", "()Z",  (void *)android_net_wifi_connectToSupplicant },
515     { "closeSupplicantConnection", "()V",  (void *)android_net_wifi_closeSupplicantConnection },
516 
517     { "listNetworksCommand", "()Ljava/lang/String;",
518         (void*) android_net_wifi_listNetworksCommand },
519     { "addNetworkCommand", "()I", (void*) android_net_wifi_addNetworkCommand },
520     { "setNetworkVariableCommand", "(ILjava/lang/String;Ljava/lang/String;)Z",
521         (void*) android_net_wifi_setNetworkVariableCommand },
522     { "getNetworkVariableCommand", "(ILjava/lang/String;)Ljava/lang/String;",
523         (void*) android_net_wifi_getNetworkVariableCommand },
524     { "removeNetworkCommand", "(I)Z", (void*) android_net_wifi_removeNetworkCommand },
525     { "enableNetworkCommand", "(IZ)Z", (void*) android_net_wifi_enableNetworkCommand },
526     { "disableNetworkCommand", "(I)Z", (void*) android_net_wifi_disableNetworkCommand },
527     { "waitForEvent", "()Ljava/lang/String;", (void*) android_net_wifi_waitForEvent },
528     { "statusCommand", "()Ljava/lang/String;", (void*) android_net_wifi_statusCommand },
529     { "scanResultsCommand", "()Ljava/lang/String;", (void*) android_net_wifi_scanResultsCommand },
530     { "pingCommand", "()Z",  (void *)android_net_wifi_pingCommand },
531     { "disconnectCommand", "()Z",  (void *)android_net_wifi_disconnectCommand },
532     { "reconnectCommand", "()Z",  (void *)android_net_wifi_reconnectCommand },
533     { "reassociateCommand", "()Z",  (void *)android_net_wifi_reassociateCommand },
534     { "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
535     { "setScanModeCommand", "(Z)Z", (void*) android_net_wifi_setScanModeCommand },
536     { "startDriverCommand", "()Z", (void*) android_net_wifi_startDriverCommand },
537     { "stopDriverCommand", "()Z", (void*) android_net_wifi_stopDriverCommand },
538     { "startPacketFiltering", "()Z", (void*) android_net_wifi_startPacketFiltering },
539     { "stopPacketFiltering", "()Z", (void*) android_net_wifi_stopPacketFiltering },
540     { "setPowerModeCommand", "(I)Z", (void*) android_net_wifi_setPowerModeCommand },
541     { "setNumAllowedChannelsCommand", "(I)Z", (void*) android_net_wifi_setNumAllowedChannelsCommand },
542     { "getNumAllowedChannelsCommand", "()I", (void*) android_net_wifi_getNumAllowedChannelsCommand },
543     { "setBluetoothCoexistenceModeCommand", "(I)Z",
544     		(void*) android_net_wifi_setBluetoothCoexistenceModeCommand },
545     { "setBluetoothCoexistenceScanModeCommand", "(Z)Z",
546     		(void*) android_net_wifi_setBluetoothCoexistenceScanModeCommand },
547     { "getRssiCommand", "()I", (void*) android_net_wifi_getRssiCommand },
548     { "getRssiApproxCommand", "()I",
549             (void*) android_net_wifi_getRssiApproxCommand},
550     { "getLinkSpeedCommand", "()I", (void*) android_net_wifi_getLinkSpeedCommand },
551     { "getMacAddressCommand", "()Ljava/lang/String;", (void*) android_net_wifi_getMacAddressCommand },
552     { "saveConfigCommand", "()Z", (void*) android_net_wifi_saveConfigCommand },
553     { "reloadConfigCommand", "()Z", (void*) android_net_wifi_reloadConfigCommand },
554     { "setScanResultHandlingCommand", "(I)Z", (void*) android_net_wifi_setScanResultHandlingCommand },
555     { "addToBlacklistCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_addToBlacklistCommand },
556     { "clearBlacklistCommand", "()Z", (void*) android_net_wifi_clearBlacklistCommand },
557 
558     { "doDhcpRequest", "(Landroid/net/DhcpInfo;)Z", (void*) android_net_wifi_doDhcpRequest },
559     { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_wifi_getDhcpError },
560 };
561 
register_android_net_wifi_WifiManager(JNIEnv * env)562 int register_android_net_wifi_WifiManager(JNIEnv* env)
563 {
564     jclass wifi = env->FindClass(WIFI_PKG_NAME);
565     LOG_FATAL_IF(wifi == NULL, "Unable to find class " WIFI_PKG_NAME);
566 
567     dhcpInfoFieldIds.dhcpInfoClass = env->FindClass("android/net/DhcpInfo");
568     if (dhcpInfoFieldIds.dhcpInfoClass != NULL) {
569         dhcpInfoFieldIds.constructorId = env->GetMethodID(dhcpInfoFieldIds.dhcpInfoClass, "<init>", "()V");
570         dhcpInfoFieldIds.ipaddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "ipAddress", "I");
571         dhcpInfoFieldIds.gateway = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "gateway", "I");
572         dhcpInfoFieldIds.netmask = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "netmask", "I");
573         dhcpInfoFieldIds.dns1 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns1", "I");
574         dhcpInfoFieldIds.dns2 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns2", "I");
575         dhcpInfoFieldIds.serverAddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "serverAddress", "I");
576         dhcpInfoFieldIds.leaseDuration = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "leaseDuration", "I");
577     }
578 
579     return AndroidRuntime::registerNativeMethods(env,
580             WIFI_PKG_NAME, gWifiMethods, NELEM(gWifiMethods));
581 }
582 
583 }; // namespace android
584