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 "JniConstants.h" 21 #include <ScopedUtfChars.h> 22 #include <ScopedBytes.h> 23 #include <utils/misc.h> 24 #include <android_runtime/AndroidRuntime.h> 25 #include <utils/Log.h> 26 #include <utils/String16.h> 27 #include <ctype.h> 28 #include <sys/socket.h> 29 #include <linux/if.h> 30 #include "wifi.h" 31 #include "wifi_hal.h" 32 #include "jni_helper.h" 33 #include "rtt.h" 34 #include "wifi_hal_stub.h" 35 #define REPLY_BUF_SIZE 4096 // wpa_supplicant's maximum size. 36 #define EVENT_BUF_SIZE 2048 37 38 namespace android { 39 40 static jint DBG = false; 41 42 //Please put all HAL function call here and call from the function table instead of directly call 43 static wifi_hal_fn hal_fn; 44 int init_wifi_hal_func_table(wifi_hal_fn *hal_fn) { 45 if (hal_fn == NULL) { 46 return -1; 47 } 48 hal_fn->wifi_initialize = wifi_initialize_stub; 49 hal_fn->wifi_cleanup = wifi_cleanup_stub; 50 hal_fn->wifi_event_loop = wifi_event_loop_stub; 51 hal_fn->wifi_get_error_info = wifi_get_error_info_stub; 52 hal_fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set_stub; 53 hal_fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix_stub; 54 hal_fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui_stub; 55 hal_fn->wifi_get_supported_channels = wifi_get_supported_channels_stub; 56 hal_fn->wifi_is_epr_supported = wifi_is_epr_supported_stub; 57 hal_fn->wifi_get_ifaces = wifi_get_ifaces_stub; 58 hal_fn->wifi_get_iface_name = wifi_get_iface_name_stub; 59 hal_fn->wifi_reset_iface_event_handler = wifi_reset_iface_event_handler_stub; 60 hal_fn->wifi_start_gscan = wifi_start_gscan_stub; 61 hal_fn->wifi_stop_gscan = wifi_stop_gscan_stub; 62 hal_fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results_stub; 63 hal_fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist_stub; 64 hal_fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist_stub; 65 hal_fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler_stub; 66 hal_fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler_stub; 67 hal_fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities_stub; 68 hal_fn->wifi_set_link_stats = wifi_set_link_stats_stub; 69 hal_fn->wifi_get_link_stats = wifi_get_link_stats_stub; 70 hal_fn->wifi_clear_link_stats = wifi_clear_link_stats_stub; 71 hal_fn->wifi_get_valid_channels = wifi_get_valid_channels_stub; 72 hal_fn->wifi_rtt_range_request = wifi_rtt_range_request_stub; 73 hal_fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel_stub; 74 hal_fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities_stub; 75 hal_fn->wifi_start_logging = wifi_start_logging_stub; 76 hal_fn->wifi_set_epno_list = wifi_set_epno_list_stub; 77 hal_fn->wifi_set_country_code = wifi_set_country_code_stub; 78 hal_fn->wifi_enable_tdls = wifi_enable_tdls_stub; 79 hal_fn->wifi_disable_tdls = wifi_disable_tdls_stub; 80 hal_fn->wifi_get_tdls_status = wifi_get_tdls_status_stub; 81 hal_fn->wifi_get_tdls_capabilities = wifi_get_tdls_capabilities_stub; 82 hal_fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag_stub; 83 hal_fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump_stub; 84 hal_fn->wifi_set_log_handler = wifi_set_log_handler_stub; 85 hal_fn->wifi_reset_log_handler = wifi_reset_log_handler_stub; 86 hal_fn->wifi_set_alert_handler = wifi_set_alert_handler_stub; 87 hal_fn->wifi_reset_alert_handler = wifi_reset_alert_handler_stub; 88 hal_fn->wifi_get_firmware_version = wifi_get_firmware_version_stub; 89 hal_fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status_stub; 90 hal_fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set_stub; 91 hal_fn->wifi_get_ring_data = wifi_get_ring_data_stub; 92 hal_fn->wifi_get_driver_version = wifi_get_driver_version_stub; 93 hal_fn->wifi_set_ssid_white_list = wifi_set_ssid_white_list_stub; 94 hal_fn->wifi_set_gscan_roam_params = wifi_set_gscan_roam_params_stub; 95 hal_fn->wifi_set_bssid_preference = wifi_set_bssid_preference_stub; 96 hal_fn->wifi_enable_lazy_roam = wifi_enable_lazy_roam_stub; 97 hal_fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist_stub; 98 hal_fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet_stub; 99 hal_fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet_stub; 100 return 0; 101 } 102 103 static bool doCommand(JNIEnv* env, jstring javaCommand, 104 char* reply, size_t reply_len) { 105 ScopedUtfChars command(env, javaCommand); 106 if (command.c_str() == NULL) { 107 return false; // ScopedUtfChars already threw on error. 108 } 109 110 if (DBG) { 111 ALOGD("doCommand: %s", command.c_str()); 112 } 113 114 --reply_len; // Ensure we have room to add NUL termination. 115 if (::wifi_command(command.c_str(), reply, &reply_len) != 0) { 116 return false; 117 } 118 119 // Strip off trailing newline. 120 if (reply_len > 0 && reply[reply_len-1] == '\n') { 121 reply[reply_len-1] = '\0'; 122 } else { 123 reply[reply_len] = '\0'; 124 } 125 return true; 126 } 127 128 static jint doIntCommand(JNIEnv* env, jstring javaCommand) { 129 char reply[REPLY_BUF_SIZE]; 130 if (!doCommand(env, javaCommand, reply, sizeof(reply))) { 131 return -1; 132 } 133 return static_cast<jint>(atoi(reply)); 134 } 135 136 static jboolean doBooleanCommand(JNIEnv* env, jstring javaCommand) { 137 char reply[REPLY_BUF_SIZE]; 138 if (!doCommand(env, javaCommand, reply, sizeof(reply))) { 139 return JNI_FALSE; 140 } 141 return (strcmp(reply, "OK") == 0); 142 } 143 144 // Send a command to the supplicant, and return the reply as a String. 145 static jstring doStringCommand(JNIEnv* env, jstring javaCommand) { 146 char reply[REPLY_BUF_SIZE]; 147 if (!doCommand(env, javaCommand, reply, sizeof(reply))) { 148 return NULL; 149 } 150 return env->NewStringUTF(reply); 151 } 152 153 static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject) 154 { 155 return (::is_wifi_driver_loaded() == 1); 156 } 157 158 static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject) 159 { 160 return (::wifi_load_driver() == 0); 161 } 162 163 static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject) 164 { 165 return (::wifi_unload_driver() == 0); 166 } 167 168 static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) 169 { 170 return (::wifi_start_supplicant(p2pSupported) == 0); 171 } 172 173 static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) 174 { 175 return (::wifi_stop_supplicant(p2pSupported) == 0); 176 } 177 178 static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject) 179 { 180 return (::wifi_connect_to_supplicant() == 0); 181 } 182 183 static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject) 184 { 185 ::wifi_close_supplicant_connection(); 186 } 187 188 static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject) 189 { 190 char buf[EVENT_BUF_SIZE]; 191 int nread = ::wifi_wait_for_event(buf, sizeof buf); 192 if (nread > 0) { 193 return env->NewStringUTF(buf); 194 } else { 195 return NULL; 196 } 197 } 198 199 static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) { 200 return doBooleanCommand(env, javaCommand); 201 } 202 203 static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) { 204 return doIntCommand(env, javaCommand); 205 } 206 207 static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) { 208 return doStringCommand(env,javaCommand); 209 } 210 211 /* wifi_hal <==> WifiNative bridge */ 212 213 static jclass mCls; /* saved WifiNative object */ 214 static JavaVM *mVM; /* saved JVM pointer */ 215 216 static const char *WifiHandleVarName = "sWifiHalHandle"; 217 static const char *WifiIfaceHandleVarName = "sWifiIfaceHandles"; 218 static jmethodID OnScanResultsMethodID; 219 220 static wifi_handle getWifiHandle(JNIHelper &helper, jclass cls) { 221 return (wifi_handle) helper.getStaticLongField(cls, WifiHandleVarName); 222 } 223 224 static wifi_interface_handle getIfaceHandle(JNIHelper &helper, jclass cls, jint index) { 225 return (wifi_interface_handle) helper.getStaticLongArrayField(cls, WifiIfaceHandleVarName, index); 226 } 227 228 jboolean setSSIDField(JNIHelper helper, jobject scanResult, const char *rawSsid) { 229 230 int len = strlen(rawSsid); 231 232 if (len > 0) { 233 JNIObject<jbyteArray> ssidBytes = helper.newByteArray(len); 234 helper.setByteArrayRegion(ssidBytes, 0, len, (jbyte *) rawSsid); 235 jboolean ret = helper.callStaticMethod(mCls, 236 "setSsid", "([BLandroid/net/wifi/ScanResult;)Z", ssidBytes.get(), scanResult); 237 return ret; 238 } else { 239 //empty SSID or SSID start with \0 240 return true; 241 } 242 } 243 static JNIObject<jobject> createScanResult(JNIHelper &helper, wifi_scan_result *result) { 244 245 // ALOGD("creating scan result"); 246 247 JNIObject<jobject> scanResult = helper.createObject("android/net/wifi/ScanResult"); 248 if (scanResult == NULL) { 249 ALOGE("Error in creating scan result"); 250 return JNIObject<jobject>(helper, NULL); 251 } 252 253 ALOGV("setting SSID to %s", result->ssid); 254 255 if (!setSSIDField(helper, scanResult, result->ssid)) { 256 ALOGE("Error on set SSID"); 257 return JNIObject<jobject>(helper, NULL); 258 } 259 260 char bssid[32]; 261 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->bssid[0], result->bssid[1], 262 result->bssid[2], result->bssid[3], result->bssid[4], result->bssid[5]); 263 264 helper.setStringField(scanResult, "BSSID", bssid); 265 266 helper.setIntField(scanResult, "level", result->rssi); 267 helper.setIntField(scanResult, "frequency", result->channel); 268 helper.setLongField(scanResult, "timestamp", result->ts); 269 270 return scanResult; 271 } 272 273 int set_iface_flags(const char *ifname, int dev_up) { 274 struct ifreq ifr; 275 int ret; 276 int sock = socket(PF_INET, SOCK_DGRAM, 0); 277 if (sock < 0) { 278 ALOGD("Bad socket: %d\n", sock); 279 return -errno; 280 } 281 282 //ALOGD("setting interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN"); 283 284 memset(&ifr, 0, sizeof(ifr)); 285 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); 286 287 //ALOGD("reading old value\n"); 288 289 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) { 290 ret = errno ? -errno : -999; 291 ALOGE("Could not read interface %s flags: %d\n", ifname, errno); 292 close(sock); 293 return ret; 294 } else { 295 //ALOGD("writing new value\n"); 296 } 297 298 if (dev_up) { 299 if (ifr.ifr_flags & IFF_UP) { 300 // ALOGD("interface %s is already up\n", ifname); 301 close(sock); 302 return 0; 303 } 304 ifr.ifr_flags |= IFF_UP; 305 } else { 306 if (!(ifr.ifr_flags & IFF_UP)) { 307 // ALOGD("interface %s is already down\n", ifname); 308 close(sock); 309 return 0; 310 } 311 ifr.ifr_flags &= ~IFF_UP; 312 } 313 314 if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) { 315 ALOGE("Could not set interface %s flags: %d\n", ifname, errno); 316 ret = errno ? -errno : -999; 317 close(sock); 318 return ret; 319 } else { 320 ALOGD("set interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN"); 321 } 322 close(sock); 323 return 0; 324 } 325 326 static jboolean android_net_wifi_toggle_interface(JNIEnv* env, jclass cls, int toggle) { 327 return(set_iface_flags("wlan0", toggle) == 0); 328 } 329 330 static jboolean android_net_wifi_startHal(JNIEnv* env, jclass cls) { 331 JNIHelper helper(env); 332 wifi_handle halHandle = getWifiHandle(helper, cls); 333 if (halHandle == NULL) { 334 335 if(init_wifi_hal_func_table(&hal_fn) != 0 ) { 336 ALOGD("Can not initialize the basic function pointer table"); 337 return false; 338 } 339 340 wifi_error res = init_wifi_vendor_hal_func_table(&hal_fn); 341 if (res != WIFI_SUCCESS) { 342 ALOGD("Can not initialize the vendor function pointer table"); 343 return false; 344 } 345 346 int ret = set_iface_flags("wlan0", 1); 347 if(ret != 0) { 348 return false; 349 } 350 351 res = hal_fn.wifi_initialize(&halHandle); 352 if (res == WIFI_SUCCESS) { 353 helper.setStaticLongField(cls, WifiHandleVarName, (jlong)halHandle); 354 ALOGD("Did set static halHandle = %p", halHandle); 355 } 356 env->GetJavaVM(&mVM); 357 mCls = (jclass) env->NewGlobalRef(cls); 358 ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls); 359 return res == WIFI_SUCCESS; 360 } else { 361 return (set_iface_flags("wlan0", 1) == 0); 362 } 363 } 364 365 void android_net_wifi_hal_cleaned_up_handler(wifi_handle handle) { 366 ALOGD("In wifi cleaned up handler"); 367 368 JNIHelper helper(mVM); 369 helper.setStaticLongField(mCls, WifiHandleVarName, 0); 370 371 helper.deleteGlobalRef(mCls); 372 mCls = NULL; 373 mVM = NULL; 374 } 375 376 static void android_net_wifi_stopHal(JNIEnv* env, jclass cls) { 377 ALOGD("In wifi stop Hal"); 378 379 JNIHelper helper(env); 380 wifi_handle halHandle = getWifiHandle(helper, cls); 381 if (halHandle == NULL) 382 return; 383 384 ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls); 385 hal_fn.wifi_cleanup(halHandle, android_net_wifi_hal_cleaned_up_handler); 386 } 387 388 static void android_net_wifi_waitForHalEvents(JNIEnv* env, jclass cls) { 389 390 ALOGD("waitForHalEvents called, vm = %p, obj = %p, env = %p", mVM, mCls, env); 391 392 JNIHelper helper(env); 393 wifi_handle halHandle = getWifiHandle(helper, cls); 394 hal_fn.wifi_event_loop(halHandle); 395 set_iface_flags("wlan0", 0); 396 } 397 398 static int android_net_wifi_getInterfaces(JNIEnv *env, jclass cls) { 399 int n = 0; 400 401 JNIHelper helper(env); 402 403 wifi_handle halHandle = getWifiHandle(helper, cls); 404 wifi_interface_handle *ifaceHandles = NULL; 405 int result = hal_fn.wifi_get_ifaces(halHandle, &n, &ifaceHandles); 406 if (result < 0) { 407 return result; 408 } 409 410 if (n < 0) { 411 THROW(helper,"android_net_wifi_getInterfaces no interfaces"); 412 return 0; 413 } 414 415 if (ifaceHandles == NULL) { 416 THROW(helper,"android_net_wifi_getInterfaces null interface array"); 417 return 0; 418 } 419 420 if (n > 8) { 421 THROW(helper,"Too many interfaces"); 422 return 0; 423 } 424 425 jlongArray array = (env)->NewLongArray(n); 426 if (array == NULL) { 427 THROW(helper,"Error in accessing array"); 428 return 0; 429 } 430 431 jlong elems[8]; 432 for (int i = 0; i < n; i++) { 433 elems[i] = reinterpret_cast<jlong>(ifaceHandles[i]); 434 } 435 436 helper.setLongArrayRegion(array, 0, n, elems); 437 helper.setStaticLongArrayField(cls, WifiIfaceHandleVarName, array); 438 439 return (result < 0) ? result : n; 440 } 441 442 static jstring android_net_wifi_getInterfaceName(JNIEnv *env, jclass cls, jint i) { 443 444 char buf[EVENT_BUF_SIZE]; 445 446 JNIHelper helper(env); 447 448 jlong value = helper.getStaticLongArrayField(cls, WifiIfaceHandleVarName, i); 449 wifi_interface_handle handle = (wifi_interface_handle) value; 450 int result = hal_fn.wifi_get_iface_name(handle, buf, sizeof(buf)); 451 if (result < 0) { 452 return NULL; 453 } else { 454 JNIObject<jstring> name = helper.newStringUTF(buf); 455 return name.detach(); 456 } 457 } 458 459 460 static void onScanResultsAvailable(wifi_request_id id, unsigned num_results) { 461 462 JNIHelper helper(mVM); 463 464 // ALOGD("onScanResultsAvailable called, vm = %p, obj = %p, env = %p", mVM, mCls, env); 465 466 helper.reportEvent(mCls, "onScanResultsAvailable", "(I)V", id); 467 } 468 469 static void onScanEvent(wifi_scan_event event, unsigned status) { 470 471 JNIHelper helper(mVM); 472 473 // ALOGD("onScanStatus called, vm = %p, obj = %p, env = %p", mVM, mCls, env); 474 475 helper.reportEvent(mCls, "onScanStatus", "(I)V", event); 476 } 477 478 static void onFullScanResult(wifi_request_id id, wifi_scan_result *result) { 479 480 JNIHelper helper(mVM); 481 482 //ALOGD("onFullScanResult called, vm = %p, obj = %p, env = %p", mVM, mCls, env); 483 484 JNIObject<jobject> scanResult = createScanResult(helper, result); 485 486 //ALOGD("Creating a byte array of length %d", result->ie_length); 487 488 JNIObject<jbyteArray> elements = helper.newByteArray(result->ie_length); 489 if (elements == NULL) { 490 ALOGE("Error in allocating array"); 491 return; 492 } 493 494 // ALOGD("Setting byte array"); 495 496 jbyte *bytes = (jbyte *)&(result->ie_data[0]); 497 helper.setByteArrayRegion(elements, 0, result->ie_length, bytes); 498 499 // ALOGD("Returning result"); 500 501 helper.reportEvent(mCls, "onFullScanResult", "(ILandroid/net/wifi/ScanResult;[B)V", id, 502 scanResult.get(), elements.get()); 503 } 504 505 static jboolean android_net_wifi_startScan( 506 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) { 507 508 JNIHelper helper(env); 509 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 510 // ALOGD("starting scan on interface[%d] = %p", iface, handle); 511 512 wifi_scan_cmd_params params; 513 memset(¶ms, 0, sizeof(params)); 514 515 params.base_period = helper.getIntField(settings, "base_period_ms"); 516 params.max_ap_per_scan = helper.getIntField(settings, "max_ap_per_scan"); 517 params.report_threshold_percent = helper.getIntField(settings, "report_threshold_percent"); 518 params.report_threshold_num_scans = helper.getIntField(settings, "report_threshold_num_scans"); 519 520 ALOGD("Initialized common fields %d, %d, %d, %d", params.base_period, params.max_ap_per_scan, 521 params.report_threshold_percent, params.report_threshold_num_scans); 522 523 const char *bucket_array_type = "[Lcom/android/server/wifi/WifiNative$BucketSettings;"; 524 const char *channel_array_type = "[Lcom/android/server/wifi/WifiNative$ChannelSettings;"; 525 526 params.num_buckets = helper.getIntField(settings, "num_buckets"); 527 528 // ALOGD("Initialized num_buckets to %d", params.num_buckets); 529 530 for (int i = 0; i < params.num_buckets; i++) { 531 JNIObject<jobject> bucket = helper.getObjectArrayField( 532 settings, "buckets", bucket_array_type, i); 533 534 params.buckets[i].bucket = helper.getIntField(bucket, "bucket"); 535 params.buckets[i].band = (wifi_band) helper.getIntField(bucket, "band"); 536 params.buckets[i].period = helper.getIntField(bucket, "period_ms"); 537 538 int report_events = helper.getIntField(bucket, "report_events"); 539 params.buckets[i].report_events = report_events; 540 541 ALOGD("bucket[%d] = %d:%d:%d:%d", i, params.buckets[i].bucket, 542 params.buckets[i].band, params.buckets[i].period, report_events); 543 544 params.buckets[i].num_channels = helper.getIntField(bucket, "num_channels"); 545 // ALOGD("Initialized num_channels to %d", params.buckets[i].num_channels); 546 547 for (int j = 0; j < params.buckets[i].num_channels; j++) { 548 JNIObject<jobject> channel = helper.getObjectArrayField( 549 bucket, "channels", channel_array_type, j); 550 551 params.buckets[i].channels[j].channel = helper.getIntField(channel, "frequency"); 552 params.buckets[i].channels[j].dwellTimeMs = helper.getIntField(channel, "dwell_time_ms"); 553 554 bool passive = helper.getBoolField(channel, "passive"); 555 params.buckets[i].channels[j].passive = (passive ? 1 : 0); 556 557 // ALOGD("Initialized channel %d", params.buckets[i].channels[j].channel); 558 } 559 } 560 561 // ALOGD("Initialized all fields"); 562 563 wifi_scan_result_handler handler; 564 memset(&handler, 0, sizeof(handler)); 565 handler.on_scan_results_available = &onScanResultsAvailable; 566 handler.on_full_scan_result = &onFullScanResult; 567 handler.on_scan_event = &onScanEvent; 568 569 return hal_fn.wifi_start_gscan(id, handle, params, handler) == WIFI_SUCCESS; 570 } 571 572 static jboolean android_net_wifi_stopScan(JNIEnv *env, jclass cls, jint iface, jint id) { 573 574 JNIHelper helper(env); 575 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 576 // ALOGD("stopping scan on interface[%d] = %p", iface, handle); 577 578 return hal_fn.wifi_stop_gscan(id, handle) == WIFI_SUCCESS; 579 } 580 581 static int compare_scan_result_timestamp(const void *v1, const void *v2) { 582 const wifi_scan_result *result1 = static_cast<const wifi_scan_result *>(v1); 583 const wifi_scan_result *result2 = static_cast<const wifi_scan_result *>(v2); 584 return result1->ts - result2->ts; 585 } 586 587 static jobject android_net_wifi_getScanResults( 588 JNIEnv *env, jclass cls, jint iface, jboolean flush) { 589 590 JNIHelper helper(env); 591 wifi_cached_scan_results scan_data[64]; 592 int num_scan_data = 64; 593 594 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 595 // ALOGD("getting scan results on interface[%d] = %p", iface, handle); 596 597 byte b = flush ? 0xFF : 0; 598 int result = hal_fn.wifi_get_cached_gscan_results(handle, b, num_scan_data, scan_data, &num_scan_data); 599 if (result == WIFI_SUCCESS) { 600 JNIObject<jobjectArray> scanData = helper.createObjectArray( 601 "android/net/wifi/WifiScanner$ScanData", num_scan_data); 602 if (scanData == NULL) { 603 ALOGE("Error in allocating array of scanData"); 604 return NULL; 605 } 606 607 for (int i = 0; i < num_scan_data; i++) { 608 609 JNIObject<jobject> data = helper.createObject("android/net/wifi/WifiScanner$ScanData"); 610 if (data == NULL) { 611 ALOGE("Error in allocating scanData"); 612 return NULL; 613 } 614 615 helper.setIntField(data, "mId", scan_data[i].scan_id); 616 helper.setIntField(data, "mFlags", scan_data[i].flags); 617 618 /* sort all scan results by timestamp */ 619 qsort(scan_data[i].results, scan_data[i].num_results, 620 sizeof(wifi_scan_result), compare_scan_result_timestamp); 621 622 JNIObject<jobjectArray> scanResults = helper.createObjectArray( 623 "android/net/wifi/ScanResult", scan_data[i].num_results); 624 if (scanResults == NULL) { 625 ALOGE("Error in allocating scanResult array"); 626 return NULL; 627 } 628 629 wifi_scan_result *results = scan_data[i].results; 630 for (int j = 0; j < scan_data[i].num_results; j++) { 631 632 JNIObject<jobject> scanResult = createScanResult(helper, &results[j]); 633 if (scanResult == NULL) { 634 ALOGE("Error in creating scan result"); 635 return NULL; 636 } 637 638 helper.setObjectArrayElement(scanResults, j, scanResult); 639 } 640 641 helper.setObjectField(data, "mResults", "[Landroid/net/wifi/ScanResult;", scanResults); 642 helper.setObjectArrayElement(scanData, i, data); 643 } 644 645 // ALOGD("retrieved %d scan data from interface[%d] = %p", num_scan_data, iface, handle); 646 return scanData.detach(); 647 } else { 648 return NULL; 649 } 650 } 651 652 653 static jboolean android_net_wifi_getScanCapabilities( 654 JNIEnv *env, jclass cls, jint iface, jobject capabilities) { 655 656 JNIHelper helper(env); 657 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 658 // ALOGD("getting scan capabilities on interface[%d] = %p", iface, handle); 659 660 wifi_gscan_capabilities c; 661 memset(&c, 0, sizeof(c)); 662 int result = hal_fn.wifi_get_gscan_capabilities(handle, &c); 663 if (result != WIFI_SUCCESS) { 664 ALOGD("failed to get capabilities : %d", result); 665 return JNI_FALSE; 666 } 667 668 helper.setIntField(capabilities, "max_scan_cache_size", c.max_scan_cache_size); 669 helper.setIntField(capabilities, "max_scan_buckets", c.max_scan_buckets); 670 helper.setIntField(capabilities, "max_ap_cache_per_scan", c.max_ap_cache_per_scan); 671 helper.setIntField(capabilities, "max_rssi_sample_size", c.max_rssi_sample_size); 672 helper.setIntField(capabilities, "max_scan_reporting_threshold", c.max_scan_reporting_threshold); 673 helper.setIntField(capabilities, "max_hotlist_bssids", c.max_hotlist_bssids); 674 helper.setIntField(capabilities, "max_significant_wifi_change_aps", 675 c.max_significant_wifi_change_aps); 676 677 return JNI_TRUE; 678 } 679 680 681 static byte parseHexChar(char ch) { 682 if (isdigit(ch)) 683 return ch - '0'; 684 else if ('A' <= ch && ch <= 'F') 685 return ch - 'A' + 10; 686 else if ('a' <= ch && ch <= 'f') 687 return ch - 'a' + 10; 688 else { 689 ALOGE("invalid character in bssid %c", ch); 690 return 0; 691 } 692 } 693 694 static byte parseHexByte(const char * &str) { 695 byte b = parseHexChar(str[0]); 696 if (str[1] == ':' || str[1] == '\0') { 697 str += 2; 698 return b; 699 } else { 700 b = b << 4 | parseHexChar(str[1]); 701 str += 3; 702 return b; 703 } 704 } 705 706 static void parseMacAddress(const char *str, mac_addr addr) { 707 addr[0] = parseHexByte(str); 708 addr[1] = parseHexByte(str); 709 addr[2] = parseHexByte(str); 710 addr[3] = parseHexByte(str); 711 addr[4] = parseHexByte(str); 712 addr[5] = parseHexByte(str); 713 } 714 715 static bool parseMacAddress(JNIEnv *env, jobject obj, mac_addr addr) { 716 JNIHelper helper(env); 717 JNIObject<jstring> macAddrString = helper.getStringField(obj, "bssid"); 718 if (macAddrString == NULL) { 719 ALOGE("Error getting bssid field"); 720 return false; 721 } 722 723 ScopedUtfChars chars(env, macAddrString); 724 const char *bssid = chars.c_str(); 725 if (bssid == NULL) { 726 ALOGE("Error getting bssid"); 727 return false; 728 } 729 730 parseMacAddress(bssid, addr); 731 return true; 732 } 733 734 static void onHotlistApFound(wifi_request_id id, 735 unsigned num_results, wifi_scan_result *results) { 736 737 JNIHelper helper(mVM); 738 ALOGD("onHotlistApFound called, vm = %p, obj = %p, num_results = %d", mVM, mCls, num_results); 739 740 JNIObject<jobjectArray> scanResults = helper.newObjectArray(num_results, 741 "android/net/wifi/ScanResult", NULL); 742 if (scanResults == NULL) { 743 ALOGE("Error in allocating array"); 744 return; 745 } 746 747 for (unsigned i = 0; i < num_results; i++) { 748 749 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]); 750 if (scanResult == NULL) { 751 ALOGE("Error in creating scan result"); 752 return; 753 } 754 755 helper.setObjectArrayElement(scanResults, i, scanResult); 756 757 ALOGD("Found AP %32s", results[i].ssid); 758 } 759 760 helper.reportEvent(mCls, "onHotlistApFound", "(I[Landroid/net/wifi/ScanResult;)V", 761 id, scanResults.get()); 762 } 763 764 static void onHotlistApLost(wifi_request_id id, 765 unsigned num_results, wifi_scan_result *results) { 766 767 JNIHelper helper(mVM); 768 ALOGD("onHotlistApLost called, vm = %p, obj = %p, num_results = %d", mVM, mCls, num_results); 769 770 JNIObject<jobjectArray> scanResults = helper.newObjectArray(num_results, 771 "android/net/wifi/ScanResult", NULL); 772 if (scanResults == NULL) { 773 ALOGE("Error in allocating array"); 774 return; 775 } 776 777 for (unsigned i = 0; i < num_results; i++) { 778 779 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]); 780 if (scanResult == NULL) { 781 ALOGE("Error in creating scan result"); 782 return; 783 } 784 785 helper.setObjectArrayElement(scanResults, i, scanResult); 786 787 ALOGD("Lost AP %32s", results[i].ssid); 788 } 789 790 helper.reportEvent(mCls, "onHotlistApLost", "(I[Landroid/net/wifi/ScanResult;)V", 791 id, scanResults.get()); 792 } 793 794 795 static jboolean android_net_wifi_setHotlist( 796 JNIEnv *env, jclass cls, jint iface, jint id, jobject ap) { 797 798 JNIHelper helper(env); 799 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 800 ALOGD("setting hotlist on interface[%d] = %p", iface, handle); 801 802 wifi_bssid_hotlist_params params; 803 memset(¶ms, 0, sizeof(params)); 804 805 params.lost_ap_sample_size = helper.getIntField(ap, "apLostThreshold"); 806 807 JNIObject<jobjectArray> array = helper.getArrayField( 808 ap, "bssidInfos", "[Landroid/net/wifi/WifiScanner$BssidInfo;"); 809 params.num_bssid = helper.getArrayLength(array); 810 811 if (params.num_bssid == 0) { 812 ALOGE("Error in accesing array"); 813 return false; 814 } 815 816 for (int i = 0; i < params.num_bssid; i++) { 817 JNIObject<jobject> objAp = helper.getObjectArrayElement(array, i); 818 819 JNIObject<jstring> macAddrString = helper.getStringField(objAp, "bssid"); 820 if (macAddrString == NULL) { 821 ALOGE("Error getting bssid field"); 822 return false; 823 } 824 825 ScopedUtfChars chars(env, macAddrString); 826 const char *bssid = chars.c_str(); 827 if (bssid == NULL) { 828 ALOGE("Error getting bssid"); 829 return false; 830 } 831 parseMacAddress(bssid, params.ap[i].bssid); 832 833 mac_addr addr; 834 memcpy(addr, params.ap[i].bssid, sizeof(mac_addr)); 835 836 char bssidOut[32]; 837 sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1], 838 addr[2], addr[3], addr[4], addr[5]); 839 840 ALOGD("Added bssid %s", bssidOut); 841 842 params.ap[i].low = helper.getIntField(objAp, "low"); 843 params.ap[i].high = helper.getIntField(objAp, "high"); 844 } 845 846 wifi_hotlist_ap_found_handler handler; 847 memset(&handler, 0, sizeof(handler)); 848 849 handler.on_hotlist_ap_found = &onHotlistApFound; 850 handler.on_hotlist_ap_lost = &onHotlistApLost; 851 return hal_fn.wifi_set_bssid_hotlist(id, handle, params, handler) == WIFI_SUCCESS; 852 } 853 854 static jboolean android_net_wifi_resetHotlist(JNIEnv *env, jclass cls, jint iface, jint id) { 855 856 JNIHelper helper(env); 857 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 858 ALOGD("resetting hotlist on interface[%d] = %p", iface, handle); 859 860 return hal_fn.wifi_reset_bssid_hotlist(id, handle) == WIFI_SUCCESS; 861 } 862 863 void onSignificantWifiChange(wifi_request_id id, 864 unsigned num_results, wifi_significant_change_result **results) { 865 866 JNIHelper helper(mVM); 867 868 ALOGD("onSignificantWifiChange called, vm = %p, obj = %p", mVM, mCls); 869 870 JNIObject<jobjectArray> scanResults = helper.newObjectArray( 871 num_results, "android/net/wifi/ScanResult", NULL); 872 if (scanResults == NULL) { 873 ALOGE("Error in allocating array"); 874 return; 875 } 876 877 for (unsigned i = 0; i < num_results; i++) { 878 879 wifi_significant_change_result &result = *(results[i]); 880 881 JNIObject<jobject> scanResult = helper.createObject("android/net/wifi/ScanResult"); 882 if (scanResult == NULL) { 883 ALOGE("Error in creating scan result"); 884 return; 885 } 886 887 // helper.setStringField(scanResult, "SSID", results[i].ssid); 888 889 char bssid[32]; 890 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result.bssid[0], result.bssid[1], 891 result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]); 892 893 helper.setStringField(scanResult, "BSSID", bssid); 894 895 helper.setIntField(scanResult, "level", result.rssi[0]); 896 helper.setIntField(scanResult, "frequency", result.channel); 897 // helper.setLongField(scanResult, "timestamp", result.ts); 898 899 helper.setObjectArrayElement(scanResults, i, scanResult); 900 } 901 902 helper.reportEvent(mCls, "onSignificantWifiChange", "(I[Landroid/net/wifi/ScanResult;)V", 903 id, scanResults.get()); 904 905 } 906 907 static jboolean android_net_wifi_trackSignificantWifiChange( 908 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) { 909 910 JNIHelper helper(env); 911 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 912 ALOGD("tracking significant wifi change on interface[%d] = %p", iface, handle); 913 914 wifi_significant_change_params params; 915 memset(¶ms, 0, sizeof(params)); 916 917 params.rssi_sample_size = helper.getIntField(settings, "rssiSampleSize"); 918 params.lost_ap_sample_size = helper.getIntField(settings, "lostApSampleSize"); 919 params.min_breaching = helper.getIntField(settings, "minApsBreachingThreshold"); 920 921 const char *bssid_info_array_type = "[Landroid/net/wifi/WifiScanner$BssidInfo;"; 922 JNIObject<jobjectArray> bssids = helper.getArrayField( 923 settings, "bssidInfos", bssid_info_array_type); 924 params.num_bssid = helper.getArrayLength(bssids); 925 926 if (params.num_bssid == 0) { 927 ALOGE("Error in accessing array"); 928 return false; 929 } 930 931 ALOGD("Initialized common fields %d, %d, %d, %d", params.rssi_sample_size, 932 params.lost_ap_sample_size, params.min_breaching, params.num_bssid); 933 934 for (int i = 0; i < params.num_bssid; i++) { 935 JNIObject<jobject> objAp = helper.getObjectArrayElement(bssids, i); 936 937 JNIObject<jstring> macAddrString = helper.getStringField(objAp, "bssid"); 938 if (macAddrString == NULL) { 939 ALOGE("Error getting bssid field"); 940 return false; 941 } 942 943 ScopedUtfChars chars(env, macAddrString.get()); 944 const char *bssid = chars.c_str(); 945 if (bssid == NULL) { 946 ALOGE("Error getting bssid"); 947 return false; 948 } 949 950 mac_addr addr; 951 parseMacAddress(bssid, addr); 952 memcpy(params.ap[i].bssid, addr, sizeof(mac_addr)); 953 954 char bssidOut[32]; 955 sprintf(bssidOut, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], 956 addr[2], addr[3], addr[4], addr[5]); 957 958 params.ap[i].low = helper.getIntField(objAp, "low"); 959 params.ap[i].high = helper.getIntField(objAp, "high"); 960 961 ALOGD("Added bssid %s, [%04d, %04d]", bssidOut, params.ap[i].low, params.ap[i].high); 962 } 963 964 ALOGD("Added %d bssids", params.num_bssid); 965 966 wifi_significant_change_handler handler; 967 memset(&handler, 0, sizeof(handler)); 968 969 handler.on_significant_change = &onSignificantWifiChange; 970 return hal_fn.wifi_set_significant_change_handler(id, handle, params, handler) == WIFI_SUCCESS; 971 } 972 973 static jboolean android_net_wifi_untrackSignificantWifiChange( 974 JNIEnv *env, jclass cls, jint iface, jint id) { 975 976 JNIHelper helper(env); 977 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 978 ALOGD("resetting significant wifi change on interface[%d] = %p", iface, handle); 979 980 return hal_fn.wifi_reset_significant_change_handler(id, handle) == WIFI_SUCCESS; 981 } 982 983 wifi_iface_stat link_stat; 984 wifi_radio_stat radio_stat; // L release has support for only one radio 985 986 void onLinkStatsResults(wifi_request_id id, wifi_iface_stat *iface_stat, 987 int num_radios, wifi_radio_stat *radio_stats) 988 { 989 if (iface_stat != 0) { 990 memcpy(&link_stat, iface_stat, sizeof(wifi_iface_stat)); 991 } else { 992 memset(&link_stat, 0, sizeof(wifi_iface_stat)); 993 } 994 995 if (num_radios > 0 && radio_stats != 0) { 996 memcpy(&radio_stat, radio_stats, sizeof(wifi_radio_stat)); 997 } else { 998 memset(&radio_stat, 0, sizeof(wifi_radio_stat)); 999 } 1000 } 1001 1002 static void android_net_wifi_setLinkLayerStats (JNIEnv *env, jclass cls, jint iface, int enable) { 1003 JNIHelper helper(env); 1004 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1005 1006 wifi_link_layer_params params; 1007 params.aggressive_statistics_gathering = enable; 1008 params.mpdu_size_threshold = 128; 1009 1010 ALOGD("android_net_wifi_setLinkLayerStats: %u\n", enable); 1011 1012 hal_fn.wifi_set_link_stats(handle, params); 1013 } 1014 1015 static jobject android_net_wifi_getLinkLayerStats (JNIEnv *env, jclass cls, jint iface) { 1016 1017 JNIHelper helper(env); 1018 wifi_stats_result_handler handler; 1019 memset(&handler, 0, sizeof(handler)); 1020 handler.on_link_stats_results = &onLinkStatsResults; 1021 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1022 int result = hal_fn.wifi_get_link_stats(0, handle, handler); 1023 if (result < 0) { 1024 ALOGE("android_net_wifi_getLinkLayerStats: failed to get link statistics\n"); 1025 return NULL; 1026 } 1027 1028 JNIObject<jobject> wifiLinkLayerStats = helper.createObject( 1029 "android/net/wifi/WifiLinkLayerStats"); 1030 if (wifiLinkLayerStats == NULL) { 1031 ALOGE("Error in allocating wifiLinkLayerStats"); 1032 return NULL; 1033 } 1034 1035 helper.setIntField(wifiLinkLayerStats, "beacon_rx", link_stat.beacon_rx); 1036 helper.setIntField(wifiLinkLayerStats, "rssi_mgmt", link_stat.rssi_mgmt); 1037 helper.setLongField(wifiLinkLayerStats, "rxmpdu_be", link_stat.ac[WIFI_AC_BE].rx_mpdu); 1038 helper.setLongField(wifiLinkLayerStats, "rxmpdu_bk", link_stat.ac[WIFI_AC_BK].rx_mpdu); 1039 helper.setLongField(wifiLinkLayerStats, "rxmpdu_vi", link_stat.ac[WIFI_AC_VI].rx_mpdu); 1040 helper.setLongField(wifiLinkLayerStats, "rxmpdu_vo", link_stat.ac[WIFI_AC_VO].rx_mpdu); 1041 helper.setLongField(wifiLinkLayerStats, "txmpdu_be", link_stat.ac[WIFI_AC_BE].tx_mpdu); 1042 helper.setLongField(wifiLinkLayerStats, "txmpdu_bk", link_stat.ac[WIFI_AC_BK].tx_mpdu); 1043 helper.setLongField(wifiLinkLayerStats, "txmpdu_vi", link_stat.ac[WIFI_AC_VI].tx_mpdu); 1044 helper.setLongField(wifiLinkLayerStats, "txmpdu_vo", link_stat.ac[WIFI_AC_VO].tx_mpdu); 1045 helper.setLongField(wifiLinkLayerStats, "lostmpdu_be", link_stat.ac[WIFI_AC_BE].mpdu_lost); 1046 helper.setLongField(wifiLinkLayerStats, "lostmpdu_bk", link_stat.ac[WIFI_AC_BK].mpdu_lost); 1047 helper.setLongField(wifiLinkLayerStats, "lostmpdu_vi", link_stat.ac[WIFI_AC_VI].mpdu_lost); 1048 helper.setLongField(wifiLinkLayerStats, "lostmpdu_vo", link_stat.ac[WIFI_AC_VO].mpdu_lost); 1049 helper.setLongField(wifiLinkLayerStats, "retries_be", link_stat.ac[WIFI_AC_BE].retries); 1050 helper.setLongField(wifiLinkLayerStats, "retries_bk", link_stat.ac[WIFI_AC_BK].retries); 1051 helper.setLongField(wifiLinkLayerStats, "retries_vi", link_stat.ac[WIFI_AC_VI].retries); 1052 helper.setLongField(wifiLinkLayerStats, "retries_vo", link_stat.ac[WIFI_AC_VO].retries); 1053 1054 helper.setIntField(wifiLinkLayerStats, "on_time", radio_stat.on_time); 1055 helper.setIntField(wifiLinkLayerStats, "tx_time", radio_stat.tx_time); 1056 helper.setIntField(wifiLinkLayerStats, "rx_time", radio_stat.rx_time); 1057 helper.setIntField(wifiLinkLayerStats, "on_time_scan", radio_stat.on_time_scan); 1058 1059 return wifiLinkLayerStats.detach(); 1060 } 1061 1062 static jint android_net_wifi_getSupportedFeatures(JNIEnv *env, jclass cls, jint iface) { 1063 1064 JNIHelper helper(env); 1065 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1066 feature_set set = 0; 1067 1068 wifi_error result = WIFI_SUCCESS; 1069 /* 1070 set = WIFI_FEATURE_INFRA 1071 | WIFI_FEATURE_INFRA_5G 1072 | WIFI_FEATURE_HOTSPOT 1073 | WIFI_FEATURE_P2P 1074 | WIFI_FEATURE_SOFT_AP 1075 | WIFI_FEATURE_GSCAN 1076 | WIFI_FEATURE_PNO 1077 | WIFI_FEATURE_TDLS 1078 | WIFI_FEATURE_EPR; 1079 */ 1080 1081 result = hal_fn.wifi_get_supported_feature_set(handle, &set); 1082 if (result == WIFI_SUCCESS) { 1083 // ALOGD("wifi_get_supported_feature_set returned set = 0x%x", set); 1084 return set; 1085 } else { 1086 ALOGE("wifi_get_supported_feature_set returned error = 0x%x", result); 1087 return 0; 1088 } 1089 } 1090 1091 static void onRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* results[]) { 1092 1093 JNIHelper helper(mVM); 1094 1095 ALOGD("onRttResults called, vm = %p, obj = %p", mVM, mCls); 1096 1097 JNIObject<jobjectArray> rttResults = helper.newObjectArray( 1098 num_results, "android/net/wifi/RttManager$RttResult", NULL); 1099 if (rttResults == NULL) { 1100 ALOGE("Error in allocating array"); 1101 return; 1102 } 1103 1104 for (unsigned i = 0; i < num_results; i++) { 1105 1106 wifi_rtt_result *result = results[i]; 1107 1108 JNIObject<jobject> rttResult = helper.createObject("android/net/wifi/RttManager$RttResult"); 1109 if (rttResult == NULL) { 1110 ALOGE("Error in creating rtt result"); 1111 return; 1112 } 1113 1114 char bssid[32]; 1115 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->addr[0], result->addr[1], 1116 result->addr[2], result->addr[3], result->addr[4], result->addr[5]); 1117 1118 helper.setStringField(rttResult, "bssid", bssid); 1119 helper.setIntField( rttResult, "burstNumber", result->burst_num); 1120 helper.setIntField( rttResult, "measurementFrameNumber", result->measurement_number); 1121 helper.setIntField( rttResult, "successMeasurementFrameNumber", result->success_number); 1122 helper.setIntField(rttResult, "frameNumberPerBurstPeer", result->number_per_burst_peer); 1123 helper.setIntField( rttResult, "status", result->status); 1124 helper.setIntField( rttResult, "measurementType", result->type); 1125 helper.setIntField(rttResult, "retryAfterDuration", result->retry_after_duration); 1126 helper.setLongField(rttResult, "ts", result->ts); 1127 helper.setIntField( rttResult, "rssi", result->rssi); 1128 helper.setIntField( rttResult, "rssiSpread", result->rssi_spread); 1129 helper.setIntField( rttResult, "txRate", result->tx_rate.bitrate); 1130 helper.setIntField( rttResult, "rxRate", result->rx_rate.bitrate); 1131 helper.setLongField(rttResult, "rtt", result->rtt); 1132 helper.setLongField(rttResult, "rttStandardDeviation", result->rtt_sd); 1133 helper.setIntField( rttResult, "distance", result->distance); 1134 helper.setIntField( rttResult, "distanceStandardDeviation", result->distance_sd); 1135 helper.setIntField( rttResult, "distanceSpread", result->distance_spread); 1136 helper.setIntField( rttResult, "burstDuration", result->burst_duration); 1137 helper.setIntField( rttResult, "negotiatedBurstNum", result->negotiated_burst_num); 1138 1139 JNIObject<jobject> LCI = helper.createObject( 1140 "android/net/wifi/RttManager$WifiInformationElement"); 1141 if (result->LCI != NULL && result->LCI->len > 0) { 1142 ALOGD("Add LCI in result"); 1143 helper.setByteField(LCI, "id", result->LCI->id); 1144 JNIObject<jbyteArray> elements = helper.newByteArray(result->LCI->len); 1145 jbyte *bytes = (jbyte *)&(result->LCI->data[0]); 1146 helper.setByteArrayRegion(elements, 0, result->LCI->len, bytes); 1147 helper.setObjectField(LCI, "data", "[B", elements); 1148 } else { 1149 ALOGD("No LCI in result"); 1150 helper.setByteField(LCI, "id", (byte)(0xff)); 1151 } 1152 helper.setObjectField(rttResult, "LCI", 1153 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCI); 1154 1155 JNIObject<jobject> LCR = helper.createObject( 1156 "android/net/wifi/RttManager$WifiInformationElement"); 1157 if (result->LCR != NULL && result->LCR->len > 0) { 1158 ALOGD("Add LCR in result"); 1159 helper.setByteField(LCR, "id", result->LCR->id); 1160 JNIObject<jbyteArray> elements = helper.newByteArray(result->LCI->len); 1161 jbyte *bytes = (jbyte *)&(result->LCR->data[0]); 1162 helper.setByteArrayRegion(elements, 0, result->LCI->len, bytes); 1163 helper.setObjectField(LCR, "data", "[B", elements); 1164 } else { 1165 ALOGD("No LCR in result"); 1166 helper.setByteField(LCR, "id", (byte)(0xff)); 1167 } 1168 helper.setObjectField(rttResult, "LCR", 1169 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCR); 1170 1171 helper.setObjectArrayElement(rttResults, i, rttResult); 1172 } 1173 1174 helper.reportEvent(mCls, "onRttResults", "(I[Landroid/net/wifi/RttManager$RttResult;)V", 1175 id, rttResults.get()); 1176 } 1177 1178 const int MaxRttConfigs = 16; 1179 1180 static jboolean android_net_wifi_requestRange( 1181 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) { 1182 1183 JNIHelper helper(env); 1184 1185 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1186 ALOGD("sending rtt request [%d] = %p", id, handle); 1187 1188 wifi_rtt_config configs[MaxRttConfigs]; 1189 memset(&configs, 0, sizeof(configs)); 1190 1191 int len = helper.getArrayLength((jobjectArray)params); 1192 if (len > MaxRttConfigs) { 1193 return false; 1194 } 1195 1196 for (int i = 0; i < len; i++) { 1197 1198 JNIObject<jobject> param = helper.getObjectArrayElement((jobjectArray)params, i); 1199 if (param == NULL) { 1200 ALOGD("could not get element %d", i); 1201 continue; 1202 } 1203 1204 wifi_rtt_config &config = configs[i]; 1205 1206 parseMacAddress(env, param, config.addr); 1207 config.type = (wifi_rtt_type)helper.getIntField(param, "requestType"); 1208 config.peer = (rtt_peer_type)helper.getIntField(param, "deviceType"); 1209 config.channel.center_freq = helper.getIntField(param, "frequency"); 1210 config.channel.width = (wifi_channel_width) helper.getIntField(param, "channelWidth"); 1211 config.channel.center_freq0 = helper.getIntField(param, "centerFreq0"); 1212 config.channel.center_freq1 = helper.getIntField(param, "centerFreq1"); 1213 1214 config.num_burst = helper.getIntField(param, "numberBurst"); 1215 config.burst_period = (unsigned) helper.getIntField(param, "interval"); 1216 config.num_frames_per_burst = (unsigned) helper.getIntField(param, "numSamplesPerBurst"); 1217 config.num_retries_per_rtt_frame = (unsigned) helper.getIntField(param, 1218 "numRetriesPerMeasurementFrame"); 1219 config.num_retries_per_ftmr = (unsigned) helper.getIntField(param, "numRetriesPerFTMR"); 1220 config.LCI_request = helper.getBoolField(param, "LCIRequest") ? 1 : 0; 1221 config.LCR_request = helper.getBoolField(param, "LCRRequest") ? 1 : 0; 1222 config.burst_duration = (unsigned) helper.getIntField(param, "burstTimeout"); 1223 config.preamble = (wifi_rtt_preamble) helper.getIntField(param, "preamble"); 1224 config.bw = (wifi_rtt_bw) helper.getIntField(param, "bandwidth"); 1225 1226 ALOGD("RTT request destination %d: type is %d, peer is %d, bw is %d, center_freq is %d ", i, 1227 config.type,config.peer, config.channel.width, config.channel.center_freq); 1228 ALOGD("center_freq0 is %d, center_freq1 is %d, num_burst is %d,interval is %d", 1229 config.channel.center_freq0, config.channel.center_freq1, config.num_burst, 1230 config.burst_period); 1231 ALOGD("frames_per_burst is %d, retries of measurement frame is %d, retries_per_ftmr is %d", 1232 config.num_frames_per_burst, config.num_retries_per_rtt_frame, 1233 config.num_retries_per_ftmr); 1234 ALOGD("LCI_requestis %d, LCR_request is %d, burst_timeout is %d, preamble is %d, bw is %d", 1235 config.LCI_request, config.LCR_request, config.burst_duration, config.preamble, 1236 config.bw); 1237 } 1238 1239 wifi_rtt_event_handler handler; 1240 handler.on_rtt_results = &onRttResults; 1241 1242 return hal_fn.wifi_rtt_range_request(id, handle, len, configs, handler) == WIFI_SUCCESS; 1243 } 1244 1245 static jboolean android_net_wifi_cancelRange( 1246 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) { 1247 1248 JNIHelper helper(env); 1249 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1250 ALOGD("cancelling rtt request [%d] = %p", id, handle); 1251 1252 mac_addr addrs[MaxRttConfigs]; 1253 memset(&addrs, 0, sizeof(addrs)); 1254 1255 int len = helper.getArrayLength((jobjectArray)params); 1256 if (len > MaxRttConfigs) { 1257 return false; 1258 } 1259 1260 for (int i = 0; i < len; i++) { 1261 1262 JNIObject<jobject> param = helper.getObjectArrayElement(params, i); 1263 if (param == NULL) { 1264 ALOGD("could not get element %d", i); 1265 continue; 1266 } 1267 1268 parseMacAddress(env, param, addrs[i]); 1269 } 1270 1271 return hal_fn.wifi_rtt_range_cancel(id, handle, len, addrs) == WIFI_SUCCESS; 1272 } 1273 1274 static jboolean android_net_wifi_setScanningMacOui(JNIEnv *env, jclass cls, 1275 jint iface, jbyteArray param) { 1276 1277 JNIHelper helper(env); 1278 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1279 ALOGD("setting scan oui %p", handle); 1280 1281 static const unsigned oui_len = 3; /* OUI is upper 3 bytes of mac_address */ 1282 int len = helper.getArrayLength(param); 1283 if (len != oui_len) { 1284 ALOGE("invalid oui length %d", len); 1285 return false; 1286 } 1287 1288 ScopedBytesRO paramBytes(env, param); 1289 const jbyte* bytes = paramBytes.get(); 1290 if (bytes == NULL) { 1291 ALOGE("failed to get array"); 1292 return false; 1293 } 1294 1295 return hal_fn.wifi_set_scanning_mac_oui(handle, (byte *)bytes) == WIFI_SUCCESS; 1296 } 1297 1298 static jboolean android_net_wifi_is_get_channels_for_band_supported(JNIEnv *env, jclass cls){ 1299 return (hal_fn.wifi_get_valid_channels == wifi_get_valid_channels_stub); 1300 } 1301 1302 static jintArray android_net_wifi_getValidChannels(JNIEnv *env, jclass cls, 1303 jint iface, jint band) { 1304 1305 JNIHelper helper(env); 1306 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1307 ALOGD("getting valid channels %p", handle); 1308 1309 static const int MaxChannels = 64; 1310 wifi_channel channels[64]; 1311 int num_channels = 0; 1312 wifi_error result = hal_fn.wifi_get_valid_channels(handle, band, MaxChannels, 1313 channels, &num_channels); 1314 1315 if (result == WIFI_SUCCESS) { 1316 JNIObject<jintArray> channelArray = helper.newIntArray(num_channels); 1317 if (channelArray == NULL) { 1318 ALOGE("failed to allocate channel list"); 1319 return NULL; 1320 } 1321 1322 helper.setIntArrayRegion(channelArray, 0, num_channels, channels); 1323 return channelArray.detach(); 1324 } else { 1325 ALOGE("failed to get channel list : %d", result); 1326 return NULL; 1327 } 1328 } 1329 1330 static jboolean android_net_wifi_setDfsFlag(JNIEnv *env, jclass cls, jint iface, jboolean dfs) { 1331 1332 JNIHelper helper(env); 1333 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1334 ALOGD("setting dfs flag to %s, %p", dfs ? "true" : "false", handle); 1335 1336 u32 nodfs = dfs ? 0 : 1; 1337 wifi_error result = hal_fn.wifi_set_nodfs_flag(handle, nodfs); 1338 return result == WIFI_SUCCESS; 1339 } 1340 1341 static jobject android_net_wifi_get_rtt_capabilities(JNIEnv *env, jclass cls, jint iface) { 1342 1343 JNIHelper helper(env); 1344 wifi_rtt_capabilities rtt_capabilities; 1345 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1346 wifi_error ret = hal_fn.wifi_get_rtt_capabilities(handle, &rtt_capabilities); 1347 1348 if(WIFI_SUCCESS == ret) { 1349 JNIObject<jobject> capabilities = helper.createObject( 1350 "android/net/wifi/RttManager$RttCapabilities"); 1351 helper.setBooleanField(capabilities, "oneSidedRttSupported", 1352 rtt_capabilities.rtt_one_sided_supported == 1); 1353 helper.setBooleanField(capabilities, "twoSided11McRttSupported", 1354 rtt_capabilities.rtt_ftm_supported == 1); 1355 helper.setBooleanField(capabilities, "lciSupported", 1356 rtt_capabilities.lci_support); 1357 helper.setBooleanField(capabilities, "lcrSupported", 1358 rtt_capabilities.lcr_support); 1359 helper.setIntField(capabilities, "preambleSupported", 1360 rtt_capabilities.preamble_support); 1361 helper.setIntField(capabilities, "bwSupported", 1362 rtt_capabilities.bw_support); 1363 ALOGD("One side RTT is: %s", rtt_capabilities.rtt_one_sided_supported ==1 ? "support" : 1364 "not support"); 1365 ALOGD("Two side RTT is: %s", rtt_capabilities.rtt_ftm_supported == 1 ? "support" : 1366 "not support"); 1367 ALOGD("LCR is: %s", rtt_capabilities.lcr_support == 1 ? "support" : "not support"); 1368 1369 ALOGD("LCI is: %s", rtt_capabilities.lci_support == 1 ? "support" : "not support"); 1370 1371 ALOGD("Support Preamble is : %d support BW is %d", rtt_capabilities.preamble_support, 1372 rtt_capabilities.bw_support); 1373 return capabilities.detach(); 1374 } else { 1375 return NULL; 1376 } 1377 } 1378 1379 static jboolean android_net_wifi_set_Country_Code_Hal(JNIEnv *env,jclass cls, jint iface, 1380 jstring country_code) { 1381 1382 JNIHelper helper(env); 1383 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1384 1385 ScopedUtfChars chars(env, country_code); 1386 const char *country = chars.c_str(); 1387 1388 ALOGD("set country code: %s", country); 1389 wifi_error res = hal_fn.wifi_set_country_code(handle, country); 1390 return res == WIFI_SUCCESS; 1391 } 1392 1393 static jboolean android_net_wifi_enable_disable_tdls(JNIEnv *env,jclass cls, jint iface, 1394 jboolean enable, jstring addr) { 1395 1396 JNIHelper helper(env); 1397 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1398 1399 mac_addr address; 1400 parseMacAddress(env, addr, address); 1401 wifi_tdls_handler tdls_handler; 1402 //tdls_handler.on_tdls_state_changed = &on_tdls_state_changed; 1403 1404 if(enable) { 1405 return (hal_fn.wifi_enable_tdls(handle, address, NULL, tdls_handler) == WIFI_SUCCESS); 1406 } else { 1407 return (hal_fn.wifi_disable_tdls(handle, address) == WIFI_SUCCESS); 1408 } 1409 } 1410 1411 static void on_tdls_state_changed(mac_addr addr, wifi_tdls_status status) { 1412 1413 JNIHelper helper(mVM); 1414 1415 ALOGD("on_tdls_state_changed is called: vm = %p, obj = %p", mVM, mCls); 1416 1417 char mac[32]; 1418 sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], 1419 addr[5]); 1420 1421 JNIObject<jstring> mac_address = helper.newStringUTF(mac); 1422 helper.reportEvent(mCls, "onTdlsStatus", "(Ljava/lang/StringII;)V", 1423 mac_address.get(), status.state, status.reason); 1424 1425 } 1426 1427 static jobject android_net_wifi_get_tdls_status(JNIEnv *env,jclass cls, jint iface,jstring addr) { 1428 1429 JNIHelper helper(env); 1430 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1431 1432 mac_addr address; 1433 parseMacAddress(env, addr, address); 1434 1435 wifi_tdls_status status; 1436 1437 wifi_error ret; 1438 ret = hal_fn.wifi_get_tdls_status(handle, address, &status ); 1439 1440 if (ret != WIFI_SUCCESS) { 1441 return NULL; 1442 } else { 1443 JNIObject<jobject> tdls_status = helper.createObject( 1444 "com/android/server/wifi/WifiNative$TdlsStatus"); 1445 helper.setIntField(tdls_status, "channel", status.channel); 1446 helper.setIntField(tdls_status, "global_operating_class", status.global_operating_class); 1447 helper.setIntField(tdls_status, "state", status.state); 1448 helper.setIntField(tdls_status, "reason", status.reason); 1449 return tdls_status.detach(); 1450 } 1451 } 1452 1453 static jobject android_net_wifi_get_tdls_capabilities(JNIEnv *env, jclass cls, jint iface) { 1454 1455 JNIHelper helper(env); 1456 wifi_tdls_capabilities tdls_capabilities; 1457 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1458 wifi_error ret = hal_fn.wifi_get_tdls_capabilities(handle, &tdls_capabilities); 1459 1460 if (WIFI_SUCCESS == ret) { 1461 JNIObject<jobject> capabilities = helper.createObject( 1462 "com/android/server/wifi/WifiNative$TdlsCapabilities"); 1463 helper.setIntField(capabilities, "maxConcurrentTdlsSessionNumber", 1464 tdls_capabilities.max_concurrent_tdls_session_num); 1465 helper.setBooleanField(capabilities, "isGlobalTdlsSupported", 1466 tdls_capabilities.is_global_tdls_supported == 1); 1467 helper.setBooleanField(capabilities, "isPerMacTdlsSupported", 1468 tdls_capabilities.is_per_mac_tdls_supported == 1); 1469 helper.setBooleanField(capabilities, "isOffChannelTdlsSupported", 1470 tdls_capabilities.is_off_channel_tdls_supported); 1471 1472 ALOGD("TDLS Max Concurrent Tdls Session Number is: %d", 1473 tdls_capabilities.max_concurrent_tdls_session_num); 1474 ALOGD("Global Tdls is: %s", tdls_capabilities.is_global_tdls_supported == 1 ? "support" : 1475 "not support"); 1476 ALOGD("Per Mac Tdls is: %s", tdls_capabilities.is_per_mac_tdls_supported == 1 ? "support" : 1477 "not support"); 1478 ALOGD("Off Channel Tdls is: %s", tdls_capabilities.is_off_channel_tdls_supported == 1 ? 1479 "support" : "not support"); 1480 1481 return capabilities.detach(); 1482 } else { 1483 return NULL; 1484 } 1485 } 1486 1487 // ---------------------------------------------------------------------------- 1488 // Debug framework 1489 // ---------------------------------------------------------------------------- 1490 static jint android_net_wifi_get_supported_logger_feature(JNIEnv *env, jclass cls, jint iface){ 1491 //Not implemented yet 1492 JNIHelper helper(env); 1493 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1494 return -1; 1495 } 1496 1497 static jobject android_net_wifi_get_driver_version(JNIEnv *env, jclass cls, jint iface) { 1498 //Need to be fixed. The memory should be allocated from lower layer 1499 //char *buffer = NULL; 1500 JNIHelper helper(env); 1501 int buffer_length = 256; 1502 char *buffer = (char *)malloc(buffer_length); 1503 if (!buffer) return NULL; 1504 memset(buffer, 0, buffer_length); 1505 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1506 1507 ALOGD("android_net_wifi_get_driver_version = %p", handle); 1508 1509 if (handle == 0) { 1510 return NULL; 1511 } 1512 1513 wifi_error result = hal_fn.wifi_get_driver_version(handle, buffer, buffer_length); 1514 1515 if (result == WIFI_SUCCESS) { 1516 ALOGD("buffer is %p, length is %d", buffer, buffer_length); 1517 JNIObject<jstring> driver_version = helper.newStringUTF(buffer); 1518 free(buffer); 1519 return driver_version.detach(); 1520 } else { 1521 ALOGD("Fail to get driver version"); 1522 free(buffer); 1523 return NULL; 1524 } 1525 } 1526 1527 static jobject android_net_wifi_get_firmware_version(JNIEnv *env, jclass cls, jint iface) { 1528 1529 //char *buffer = NULL; 1530 JNIHelper helper(env); 1531 int buffer_length = 256; 1532 char *buffer = (char *)malloc(buffer_length); 1533 if (!buffer) return NULL; 1534 memset(buffer, 0, buffer_length); 1535 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1536 1537 ALOGD("android_net_wifi_get_firmware_version = %p", handle); 1538 1539 if (handle == 0) { 1540 return NULL; 1541 } 1542 1543 wifi_error result = hal_fn.wifi_get_firmware_version(handle, buffer, buffer_length); 1544 1545 if (result == WIFI_SUCCESS) { 1546 ALOGD("buffer is %p, length is %d", buffer, buffer_length); 1547 JNIObject<jstring> firmware_version = helper.newStringUTF(buffer); 1548 free(buffer); 1549 return firmware_version.detach(); 1550 } else { 1551 ALOGD("Fail to get Firmware version"); 1552 free(buffer); 1553 return NULL; 1554 } 1555 } 1556 1557 static jobject android_net_wifi_get_ring_buffer_status (JNIEnv *env, jclass cls, jint iface) { 1558 1559 JNIHelper helper(env); 1560 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1561 1562 ALOGD("android_net_wifi_get_ring_buffer_status = %p", handle); 1563 1564 if (handle == 0) { 1565 return NULL; 1566 } 1567 1568 //wifi_ring_buffer_status *status = NULL; 1569 u32 num_rings = 10; 1570 wifi_ring_buffer_status *status = 1571 (wifi_ring_buffer_status *)malloc(sizeof(wifi_ring_buffer_status) * num_rings); 1572 if (!status) return NULL; 1573 memset(status, 0, sizeof(wifi_ring_buffer_status) * num_rings); 1574 wifi_error result = hal_fn.wifi_get_ring_buffers_status(handle, &num_rings, status); 1575 if (result == WIFI_SUCCESS) { 1576 ALOGD("status is %p, number is %d", status, num_rings); 1577 1578 JNIObject<jobjectArray> ringBuffersStatus = helper.newObjectArray( 1579 num_rings, "com/android/server/wifi/WifiNative$RingBufferStatus", NULL); 1580 1581 wifi_ring_buffer_status *tmp = status; 1582 1583 for(u32 i = 0; i < num_rings; i++, tmp++) { 1584 1585 JNIObject<jobject> ringStatus = helper.createObject( 1586 "com/android/server/wifi/WifiNative$RingBufferStatus"); 1587 1588 if (ringStatus == NULL) { 1589 ALOGE("Error in creating ringBufferStatus"); 1590 free(status); 1591 return NULL; 1592 } 1593 1594 char name[32]; 1595 for(int j = 0; j < 32; j++) { 1596 name[j] = tmp->name[j]; 1597 } 1598 1599 helper.setStringField(ringStatus, "name", name); 1600 helper.setIntField(ringStatus, "flag", tmp->flags); 1601 helper.setIntField(ringStatus, "ringBufferId", tmp->ring_id); 1602 helper.setIntField(ringStatus, "ringBufferByteSize", tmp->ring_buffer_byte_size); 1603 helper.setIntField(ringStatus, "verboseLevel", tmp->verbose_level); 1604 helper.setIntField(ringStatus, "writtenBytes", tmp->written_bytes); 1605 helper.setIntField(ringStatus, "readBytes", tmp->read_bytes); 1606 helper.setIntField(ringStatus, "writtenRecords", tmp->written_records); 1607 1608 helper.setObjectArrayElement(ringBuffersStatus, i, ringStatus); 1609 } 1610 1611 free(status); 1612 return ringBuffersStatus.detach(); 1613 } else { 1614 free(status); 1615 return NULL; 1616 } 1617 } 1618 1619 static void on_ring_buffer_data(char *ring_name, char *buffer, int buffer_size, 1620 wifi_ring_buffer_status *status) { 1621 1622 if (!ring_name || !buffer || !status || 1623 (unsigned int)buffer_size <= sizeof(wifi_ring_buffer_entry)) { 1624 ALOGE("Error input for on_ring_buffer_data!"); 1625 return; 1626 } 1627 1628 1629 JNIHelper helper(mVM); 1630 /* ALOGD("on_ring_buffer_data called, vm = %p, obj = %p, env = %p buffer size = %d", mVM, 1631 mCls, env, buffer_size); */ 1632 1633 JNIObject<jobject> ringStatus = helper.createObject( 1634 "com/android/server/wifi/WifiNative$RingBufferStatus"); 1635 if (status == NULL) { 1636 ALOGE("Error in creating ringBufferStatus"); 1637 return; 1638 } 1639 1640 helper.setStringField(ringStatus, "name", ring_name); 1641 helper.setIntField(ringStatus, "flag", status->flags); 1642 helper.setIntField(ringStatus, "ringBufferId", status->ring_id); 1643 helper.setIntField(ringStatus, "ringBufferByteSize", status->ring_buffer_byte_size); 1644 helper.setIntField(ringStatus, "verboseLevel", status->verbose_level); 1645 helper.setIntField(ringStatus, "writtenBytes", status->written_bytes); 1646 helper.setIntField(ringStatus, "readBytes", status->read_bytes); 1647 helper.setIntField(ringStatus, "writtenRecords", status->written_records); 1648 1649 JNIObject<jbyteArray> bytes = helper.newByteArray(buffer_size); 1650 helper.setByteArrayRegion(bytes, 0, buffer_size, (jbyte*)buffer); 1651 1652 helper.reportEvent(mCls,"onRingBufferData", 1653 "(Lcom/android/server/wifi/WifiNative$RingBufferStatus;[B)V", 1654 ringStatus.get(), bytes.get()); 1655 } 1656 1657 static void on_alert_data(wifi_request_id id, char *buffer, int buffer_size, int err_code){ 1658 1659 JNIHelper helper(mVM); 1660 ALOGD("on_alert_data called, vm = %p, obj = %p, buffer_size = %d, error code = %d" 1661 , mVM, mCls, buffer_size, err_code); 1662 1663 if (buffer_size > 0) { 1664 JNIObject<jbyteArray> records = helper.newByteArray(buffer_size); 1665 jbyte *bytes = (jbyte *) buffer; 1666 helper.setByteArrayRegion(records, 0,buffer_size, bytes); 1667 helper.reportEvent(mCls,"onWifiAlert","([BI)V", records.get(), err_code); 1668 } else { 1669 helper.reportEvent(mCls,"onWifiAlert","([BI)V", NULL, err_code); 1670 } 1671 } 1672 1673 1674 static jboolean android_net_wifi_start_logging_ring_buffer(JNIEnv *env, jclass cls, jint iface, 1675 jint verbose_level,jint flags, jint max_interval,jint min_data_size, jstring ring_name) { 1676 1677 JNIHelper helper(env); 1678 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1679 1680 ALOGD("android_net_wifi_start_logging_ring_buffer = %p", handle); 1681 1682 if (handle == 0) { 1683 return false; 1684 } 1685 1686 ScopedUtfChars chars(env, ring_name); 1687 const char* ring_name_const_char = chars.c_str(); 1688 int ret = hal_fn.wifi_start_logging(handle, verbose_level, 1689 flags, max_interval, min_data_size, const_cast<char *>(ring_name_const_char)); 1690 1691 if (ret != WIFI_SUCCESS) { 1692 ALOGE("Fail to start logging for ring %s", ring_name_const_char); 1693 } else { 1694 ALOGD("start logging for ring %s", ring_name_const_char); 1695 } 1696 1697 return ret == WIFI_SUCCESS; 1698 } 1699 1700 static jboolean android_net_wifi_get_ring_buffer_data(JNIEnv *env, jclass cls, jint iface, 1701 jstring ring_name) { 1702 1703 JNIHelper helper(env); 1704 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1705 // ALOGD("android_net_wifi_get_ring_buffer_data = %p", handle); 1706 1707 ScopedUtfChars chars(env, ring_name); 1708 const char* ring_name_const_char = chars.c_str(); 1709 int result = hal_fn.wifi_get_ring_data(handle, const_cast<char *>(ring_name_const_char)); 1710 return result == WIFI_SUCCESS; 1711 } 1712 1713 1714 void on_firmware_memory_dump(char *buffer, int buffer_size) { 1715 1716 JNIHelper helper(mVM); 1717 /* ALOGD("on_firmware_memory_dump called, vm = %p, obj = %p, env = %p buffer_size = %d" 1718 , mVM, mCls, env, buffer_size); */ 1719 1720 if (buffer_size > 0) { 1721 JNIObject<jbyteArray> dump = helper.newByteArray(buffer_size); 1722 jbyte *bytes = (jbyte *) (buffer); 1723 helper.setByteArrayRegion(dump, 0, buffer_size, bytes); 1724 helper.reportEvent(mCls,"onWifiFwMemoryAvailable","([B)V", dump.get()); 1725 } 1726 } 1727 1728 static jboolean android_net_wifi_get_fw_memory_dump(JNIEnv *env, jclass cls, jint iface){ 1729 1730 JNIHelper helper(env); 1731 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1732 // ALOGD("android_net_wifi_get_fw_memory_dump = %p", handle); 1733 1734 if (handle == NULL) { 1735 ALOGE("Can not get wifi_interface_handle"); 1736 return false; 1737 } 1738 1739 wifi_firmware_memory_dump_handler fw_dump_handle; 1740 fw_dump_handle.on_firmware_memory_dump = on_firmware_memory_dump; 1741 int result = hal_fn.wifi_get_firmware_memory_dump(handle, fw_dump_handle); 1742 return result == WIFI_SUCCESS; 1743 1744 } 1745 1746 static jboolean android_net_wifi_set_log_handler(JNIEnv *env, jclass cls, jint iface, jint id) { 1747 1748 JNIHelper helper(env); 1749 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1750 ALOGD("android_net_wifi_set_log_handler = %p", handle); 1751 1752 //initialize the handler on first time 1753 wifi_ring_buffer_data_handler handler; 1754 handler.on_ring_buffer_data = &on_ring_buffer_data; 1755 int result = hal_fn.wifi_set_log_handler(id, handle, handler); 1756 if (result != WIFI_SUCCESS) { 1757 ALOGE("Fail to set logging handler"); 1758 return false; 1759 } 1760 1761 //set alter handler This will start alert too 1762 wifi_alert_handler alert_handler; 1763 alert_handler.on_alert = &on_alert_data; 1764 result = hal_fn.wifi_set_alert_handler(id, handle, alert_handler); 1765 if (result != WIFI_SUCCESS) { 1766 ALOGE(" Fail to set alert handler"); 1767 return false; 1768 } 1769 1770 return true; 1771 } 1772 1773 static jboolean android_net_wifi_reset_log_handler(JNIEnv *env, jclass cls, jint iface, jint id) { 1774 1775 JNIHelper helper(env); 1776 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1777 1778 //reset alter handler 1779 ALOGD("android_net_wifi_reset_alert_handler = %p", handle); 1780 int result = hal_fn.wifi_reset_alert_handler(id, handle); 1781 if (result != WIFI_SUCCESS) { 1782 ALOGE(" Fail to reset alert handler"); 1783 return false; 1784 } 1785 1786 //reset log handler 1787 ALOGD("android_net_wifi_reset_log_handler = %p", handle); 1788 result = hal_fn.wifi_reset_log_handler(id, handle); 1789 if (result != WIFI_SUCCESS) { 1790 ALOGE("Fail to reset logging handler"); 1791 return false; 1792 } 1793 1794 return true; 1795 } 1796 1797 // ---------------------------------------------------------------------------- 1798 // ePno framework 1799 // ---------------------------------------------------------------------------- 1800 1801 1802 static void onPnoNetworkFound(wifi_request_id id, 1803 unsigned num_results, wifi_scan_result *results) { 1804 1805 JNIHelper helper(mVM); 1806 1807 ALOGD("onPnoNetworkFound called, vm = %p, obj = %p, num_results %u", mVM, mCls, num_results); 1808 1809 if (results == 0 || num_results == 0) { 1810 ALOGE("onPnoNetworkFound: Error no results"); 1811 return; 1812 } 1813 1814 jbyte *bytes; 1815 JNIObject<jobjectArray> scanResults(helper, NULL); 1816 //jbyteArray elements; 1817 1818 for (unsigned i=0; i<num_results; i++) { 1819 1820 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]); 1821 if (i == 0) { 1822 scanResults = helper.newObjectArray( 1823 num_results, "android/net/wifi/ScanResult", scanResult); 1824 if (scanResults == 0) { 1825 ALOGD("cant allocate array"); 1826 } else { 1827 ALOGD("allocated array %u", helper.getArrayLength(scanResults)); 1828 } 1829 } else { 1830 helper.setObjectArrayElement(scanResults, i, scanResult); 1831 } 1832 1833 ALOGD("Scan result with ie length %d, i %u, <%s> rssi=%d %02x:%02x:%02x:%02x:%02x:%02x", 1834 results->ie_length, i, results[i].ssid, results[i].rssi, results[i].bssid[0], 1835 results[i].bssid[1],results[i].bssid[2], results[i].bssid[3], results[i].bssid[4], 1836 results[i].bssid[5]); 1837 1838 /*elements = helper.newByteArray(results->ie_length); 1839 if (elements == NULL) { 1840 ALOGE("Error in allocating array"); 1841 return; 1842 }*/ 1843 1844 //ALOGD("onPnoNetworkFound: Setting byte array"); 1845 1846 //bytes = (jbyte *)&(results->ie_data[0]); 1847 //helper.setByteArrayRegion(elements, 0, results->ie_length, bytes); 1848 1849 //ALOGD("onPnoNetworkFound: Returning result"); 1850 } 1851 1852 1853 ALOGD("calling report"); 1854 1855 helper.reportEvent(mCls, "onPnoNetworkFound", "(I[Landroid/net/wifi/ScanResult;)V", id, 1856 scanResults.get()); 1857 ALOGD("free ref"); 1858 } 1859 1860 static jboolean android_net_wifi_setPnoListNative( 1861 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) { 1862 1863 JNIHelper helper(env); 1864 wifi_epno_handler handler; 1865 handler.on_network_found = &onPnoNetworkFound; 1866 1867 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1868 ALOGD("configure ePno list request [%d] = %p", id, handle); 1869 1870 if (list == NULL) { 1871 // stop pno 1872 int result = hal_fn.wifi_set_epno_list(id, handle, 0, NULL, handler); 1873 ALOGE(" setPnoListNative: STOP result = %d", result); 1874 return result >= 0; 1875 } 1876 1877 wifi_epno_network net_list[MAX_PNO_SSID]; 1878 memset(&net_list, 0, sizeof(net_list)); 1879 1880 size_t len = helper.getArrayLength((jobjectArray)list); 1881 if (len > (size_t)MAX_PNO_SSID) { 1882 return false; 1883 } 1884 1885 for (unsigned int i = 0; i < len; i++) { 1886 1887 JNIObject<jobject> pno_net = helper.getObjectArrayElement((jobjectArray)list, i); 1888 if (pno_net == NULL) { 1889 ALOGD("setPnoListNative: could not get element %d", i); 1890 continue; 1891 } 1892 1893 JNIObject<jstring> sssid = helper.getStringField(pno_net, "SSID"); 1894 if (sssid == NULL) { 1895 ALOGE("Error setPnoListNative: getting ssid field"); 1896 return false; 1897 } 1898 1899 ScopedUtfChars chars(env, (jstring)sssid.get()); 1900 const char *ssid = chars.c_str(); 1901 if (ssid == NULL) { 1902 ALOGE("Error setPnoListNative: getting ssid"); 1903 return false; 1904 } 1905 int ssid_len = strnlen((const char*)ssid, 33); 1906 if (ssid_len > 32) { 1907 ALOGE("Error setPnoListNative: long ssid %u", strnlen((const char*)ssid, 256)); 1908 return false; 1909 } 1910 1911 if (ssid_len > 1 && ssid[0] == '"' && ssid[ssid_len-1]) 1912 { 1913 // strip leading and trailing '"' 1914 ssid++; 1915 ssid_len-=2; 1916 } 1917 if (ssid_len == 0) { 1918 ALOGE("Error setPnoListNative: zero length ssid, skip it"); 1919 continue; 1920 } 1921 memcpy(net_list[i].ssid, ssid, ssid_len); 1922 1923 int rssit = helper.getIntField(pno_net, "rssi_threshold"); 1924 net_list[i].rssi_threshold = (byte)rssit; 1925 int a = helper.getIntField(pno_net, "auth"); 1926 net_list[i].auth_bit_field = a; 1927 int f = helper.getIntField(pno_net, "flags"); 1928 net_list[i].flags = f; 1929 ALOGE(" setPnoListNative: idx %u rssi %d/%d auth %x/%x flags %x/%x [%s]", i, 1930 (signed)net_list[i].rssi_threshold, net_list[i].rssi_threshold, 1931 net_list[i].auth_bit_field, a, net_list[i].flags, f, net_list[i].ssid); 1932 } 1933 1934 int result = hal_fn.wifi_set_epno_list(id, handle, len, net_list, handler); 1935 ALOGE(" setPnoListNative: result %d", result); 1936 1937 return result >= 0; 1938 } 1939 1940 static jboolean android_net_wifi_setLazyRoam( 1941 JNIEnv *env, jclass cls, jint iface, jint id, jboolean enabled, jobject roam_param) { 1942 1943 JNIHelper helper(env); 1944 wifi_error status = WIFI_SUCCESS; 1945 wifi_roam_params params; 1946 memset(¶ms, 0, sizeof(params)); 1947 1948 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1949 ALOGD("configure lazy roam request [%d] = %p", id, handle); 1950 1951 if (roam_param != NULL) { 1952 params.A_band_boost_threshold = helper.getIntField(roam_param, "A_band_boost_threshold"); 1953 params.A_band_penalty_threshold = helper.getIntField(roam_param, "A_band_penalty_threshold"); 1954 params.A_band_boost_factor = helper.getIntField(roam_param, "A_band_boost_factor"); 1955 params.A_band_penalty_factor = helper.getIntField(roam_param, "A_band_penalty_factor"); 1956 params.A_band_max_boost = helper.getIntField(roam_param, "A_band_max_boost"); 1957 params.lazy_roam_hysteresis = helper.getIntField(roam_param, "lazy_roam_hysteresis"); 1958 params.alert_roam_rssi_trigger = helper.getIntField(roam_param, "alert_roam_rssi_trigger"); 1959 status = hal_fn.wifi_set_gscan_roam_params(id, handle, ¶ms); 1960 } 1961 ALOGE("android_net_wifi_setLazyRoam configured params status=%d\n", status); 1962 1963 if (status >= 0) { 1964 int doEnable = enabled ? 1 : 0; 1965 status = hal_fn.wifi_enable_lazy_roam(id, handle, doEnable); 1966 ALOGE("android_net_wifi_setLazyRoam enabled roam status=%d\n", status); 1967 } 1968 return status >= 0; 1969 } 1970 1971 static jboolean android_net_wifi_setBssidBlacklist( 1972 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) { 1973 1974 JNIHelper helper(env); 1975 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1976 ALOGD("configure BSSID black list request [%d] = %p", id, handle); 1977 1978 wifi_bssid_params params; 1979 memset(¶ms, 0, sizeof(params)); 1980 1981 if (list != NULL) { 1982 size_t len = helper.getArrayLength((jobjectArray)list); 1983 if (len > (size_t)MAX_BLACKLIST_BSSID) { 1984 return false; 1985 } 1986 for (unsigned int i = 0; i < len; i++) { 1987 1988 JNIObject<jobject> jbssid = helper.getObjectArrayElement(list, i); 1989 if (jbssid == NULL) { 1990 ALOGD("configure BSSID blacklist: could not get element %d", i); 1991 continue; 1992 } 1993 1994 ScopedUtfChars chars(env, (jstring)jbssid.get()); 1995 const char *bssid = chars.c_str(); 1996 if (bssid == NULL) { 1997 ALOGE("Error getting bssid"); 1998 return false; 1999 } 2000 2001 mac_addr addr; 2002 parseMacAddress(bssid, addr); 2003 memcpy(params.bssids[i], addr, sizeof(mac_addr)); 2004 2005 char bssidOut[32]; 2006 sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1], 2007 addr[2], addr[3], addr[4], addr[5]); 2008 2009 ALOGD("BSSID blacklist: added bssid %s", bssidOut); 2010 2011 params.num_bssid++; 2012 } 2013 } 2014 2015 ALOGD("Added %d bssids", params.num_bssid); 2016 return hal_fn.wifi_set_bssid_blacklist(id, handle, params) == WIFI_SUCCESS; 2017 } 2018 2019 static jboolean android_net_wifi_setSsidWhitelist( 2020 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) { 2021 2022 JNIHelper helper(env); 2023 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 2024 ALOGD("configure SSID white list request [%d] = %p", id, handle); 2025 wifi_ssid *ssids = NULL; 2026 int num_ssids = 0; 2027 if (list != NULL) { 2028 size_t len = helper.getArrayLength((jobjectArray)list); 2029 if (len > 0) { 2030 ssids = (wifi_ssid *)malloc(len * sizeof (wifi_ssid)); 2031 if (!ssids) return false; 2032 memset(ssids, 0, len * sizeof (wifi_ssid)); 2033 for (unsigned int i = 0; i < len; i++) { 2034 2035 JNIObject<jobject> jssid = helper.getObjectArrayElement(list, i); 2036 if (jssid == NULL) { 2037 ALOGD("configure SSID whitelist: could not get element %d", i); 2038 free(ssids); 2039 return false; 2040 } 2041 2042 ScopedUtfChars chars(env, (jstring)jssid.get()); 2043 const char *utf = chars.c_str(); 2044 if (utf == NULL) { 2045 ALOGE("Error getting sssid"); 2046 free(ssids); 2047 return false; 2048 } 2049 2050 int slen = strnlen(utf, 33); 2051 if (slen <= 0 || slen > 32) { 2052 ALOGE("Error wrong ssid length %d", slen); 2053 free(ssids); 2054 return false; 2055 } 2056 2057 memcpy(ssids[i].ssid, utf, slen); 2058 num_ssids++; 2059 ALOGD("SSID white list: added ssid %s", utf); 2060 } 2061 } 2062 } 2063 2064 ALOGD("android_net_wifi_setSsidWhitelist Added %d sssids", num_ssids); 2065 return hal_fn.wifi_set_ssid_white_list(id, handle, num_ssids, ssids) == WIFI_SUCCESS; 2066 } 2067 2068 // ---------------------------------------------------------------------------- 2069 2070 /* 2071 * JNI registration. 2072 */ 2073 static JNINativeMethod gWifiMethods[] = { 2074 /* name, signature, funcPtr */ 2075 2076 { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver }, 2077 { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded }, 2078 { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver }, 2079 { "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant }, 2080 { "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant }, 2081 { "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant }, 2082 { "closeSupplicantConnectionNative", "()V", 2083 (void *)android_net_wifi_closeSupplicantConnection }, 2084 { "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForEvent }, 2085 { "doBooleanCommandNative", "(Ljava/lang/String;)Z", (void*)android_net_wifi_doBooleanCommand }, 2086 { "doIntCommandNative", "(Ljava/lang/String;)I", (void*)android_net_wifi_doIntCommand }, 2087 { "doStringCommandNative", "(Ljava/lang/String;)Ljava/lang/String;", 2088 (void*) android_net_wifi_doStringCommand }, 2089 { "startHalNative", "()Z", (void*) android_net_wifi_startHal }, 2090 { "stopHalNative", "()V", (void*) android_net_wifi_stopHal }, 2091 { "waitForHalEventNative", "()V", (void*) android_net_wifi_waitForHalEvents }, 2092 { "getInterfacesNative", "()I", (void*) android_net_wifi_getInterfaces}, 2093 { "getInterfaceNameNative", "(I)Ljava/lang/String;", (void*) android_net_wifi_getInterfaceName}, 2094 { "getScanCapabilitiesNative", "(ILcom/android/server/wifi/WifiNative$ScanCapabilities;)Z", 2095 (void *) android_net_wifi_getScanCapabilities}, 2096 { "startScanNative", "(IILcom/android/server/wifi/WifiNative$ScanSettings;)Z", 2097 (void*) android_net_wifi_startScan}, 2098 { "stopScanNative", "(II)Z", (void*) android_net_wifi_stopScan}, 2099 { "getScanResultsNative", "(IZ)[Landroid/net/wifi/WifiScanner$ScanData;", 2100 (void *) android_net_wifi_getScanResults}, 2101 { "setHotlistNative", "(IILandroid/net/wifi/WifiScanner$HotlistSettings;)Z", 2102 (void*) android_net_wifi_setHotlist}, 2103 { "resetHotlistNative", "(II)Z", (void*) android_net_wifi_resetHotlist}, 2104 { "trackSignificantWifiChangeNative", "(IILandroid/net/wifi/WifiScanner$WifiChangeSettings;)Z", 2105 (void*) android_net_wifi_trackSignificantWifiChange}, 2106 { "untrackSignificantWifiChangeNative", "(II)Z", 2107 (void*) android_net_wifi_untrackSignificantWifiChange}, 2108 { "getWifiLinkLayerStatsNative", "(I)Landroid/net/wifi/WifiLinkLayerStats;", 2109 (void*) android_net_wifi_getLinkLayerStats}, 2110 { "setWifiLinkLayerStatsNative", "(II)V", 2111 (void*) android_net_wifi_setLinkLayerStats}, 2112 { "getSupportedFeatureSetNative", "(I)I", 2113 (void*) android_net_wifi_getSupportedFeatures}, 2114 { "requestRangeNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z", 2115 (void*) android_net_wifi_requestRange}, 2116 { "cancelRangeRequestNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z", 2117 (void*) android_net_wifi_cancelRange}, 2118 { "setScanningMacOuiNative", "(I[B)Z", (void*) android_net_wifi_setScanningMacOui}, 2119 { "getChannelsForBandNative", "(II)[I", (void*) android_net_wifi_getValidChannels}, 2120 { "setDfsFlagNative", "(IZ)Z", (void*) android_net_wifi_setDfsFlag}, 2121 { "toggleInterfaceNative", "(I)Z", (void*) android_net_wifi_toggle_interface}, 2122 { "getRttCapabilitiesNative", "(I)Landroid/net/wifi/RttManager$RttCapabilities;", 2123 (void*) android_net_wifi_get_rtt_capabilities}, 2124 {"setCountryCodeHalNative", "(ILjava/lang/String;)Z", 2125 (void*) android_net_wifi_set_Country_Code_Hal}, 2126 { "setPnoListNative", "(II[Lcom/android/server/wifi/WifiNative$WifiPnoNetwork;)Z", 2127 (void*) android_net_wifi_setPnoListNative}, 2128 {"enableDisableTdlsNative", "(IZLjava/lang/String;)Z", 2129 (void*) android_net_wifi_enable_disable_tdls}, 2130 {"getTdlsStatusNative", "(ILjava/lang/String;)Lcom/android/server/wifi/WifiNative$TdlsStatus;", 2131 (void*) android_net_wifi_get_tdls_status}, 2132 {"getTdlsCapabilitiesNative", "(I)Lcom/android/server/wifi/WifiNative$TdlsCapabilities;", 2133 (void*) android_net_wifi_get_tdls_capabilities}, 2134 {"getSupportedLoggerFeatureSetNative","(I)I", 2135 (void*) android_net_wifi_get_supported_logger_feature}, 2136 {"getDriverVersionNative", "(I)Ljava/lang/String;", 2137 (void*) android_net_wifi_get_driver_version}, 2138 {"getFirmwareVersionNative", "(I)Ljava/lang/String;", 2139 (void*) android_net_wifi_get_firmware_version}, 2140 {"getRingBufferStatusNative", "(I)[Lcom/android/server/wifi/WifiNative$RingBufferStatus;", 2141 (void*) android_net_wifi_get_ring_buffer_status}, 2142 {"startLoggingRingBufferNative", "(IIIIILjava/lang/String;)Z", 2143 (void*) android_net_wifi_start_logging_ring_buffer}, 2144 {"getRingBufferDataNative", "(ILjava/lang/String;)Z", 2145 (void*) android_net_wifi_get_ring_buffer_data}, 2146 {"getFwMemoryDumpNative","(I)Z", (void*) android_net_wifi_get_fw_memory_dump}, 2147 { "setLazyRoamNative", "(IIZLcom/android/server/wifi/WifiNative$WifiLazyRoamParams;)Z", 2148 (void*) android_net_wifi_setLazyRoam}, 2149 { "setBssidBlacklistNative", "(II[Ljava/lang/String;)Z", 2150 (void*)android_net_wifi_setBssidBlacklist}, 2151 { "setSsidWhitelistNative", "(II[Ljava/lang/String;)Z", 2152 (void*)android_net_wifi_setSsidWhitelist}, 2153 {"setLoggingEventHandlerNative", "(II)Z", (void *) android_net_wifi_set_log_handler}, 2154 {"resetLogHandlerNative", "(II)Z", (void *) android_net_wifi_reset_log_handler}, 2155 {"isGetChannelsForBandSupportedNative", "()Z", 2156 (void*)android_net_wifi_is_get_channels_for_band_supported} 2157 }; 2158 2159 int register_android_net_wifi_WifiNative(JNIEnv* env) { 2160 return AndroidRuntime::registerNativeMethods(env, 2161 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods)); 2162 } 2163 2164 2165 /* User to register native functions */ 2166 extern "C" 2167 jint Java_com_android_server_wifi_WifiNative_registerNatives(JNIEnv* env, jclass clazz) { 2168 return AndroidRuntime::registerNativeMethods(env, 2169 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods)); 2170 } 2171 2172 }; // namespace android 2173