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