com_android_server_wifi_WifiNative.cpp revision 04fdb2ce414b6175aad402fa459b3988a3238e97
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 38namespace android { 39 40static jint DBG = false; 41 42//Please put all HAL function call here and call from the function table instead of directly call 43static wifi_hal_fn hal_fn; 44int 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 103static 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 128static 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 136static 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. 145static 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 153static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject) 154{ 155 return (::is_wifi_driver_loaded() == 1); 156} 157 158static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject) 159{ 160 return (::wifi_load_driver() == 0); 161} 162 163static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject) 164{ 165 return (::wifi_unload_driver() == 0); 166} 167 168static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) 169{ 170 return (::wifi_start_supplicant(p2pSupported) == 0); 171} 172 173static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) 174{ 175 return (::wifi_stop_supplicant(p2pSupported) == 0); 176} 177 178static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject) 179{ 180 return (::wifi_connect_to_supplicant() == 0); 181} 182 183static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject) 184{ 185 ::wifi_close_supplicant_connection(); 186} 187 188static 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 199static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) { 200 return doBooleanCommand(env, javaCommand); 201} 202 203static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) { 204 return doIntCommand(env, javaCommand); 205} 206 207static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) { 208 return doStringCommand(env,javaCommand); 209} 210 211/* wifi_hal <==> WifiNative bridge */ 212 213static jclass mCls; /* saved WifiNative object */ 214static JavaVM *mVM; /* saved JVM pointer */ 215 216static const char *WifiHandleVarName = "sWifiHalHandle"; 217static const char *WifiIfaceHandleVarName = "sWifiIfaceHandles"; 218static jmethodID OnScanResultsMethodID; 219 220static wifi_handle getWifiHandle(JNIHelper &helper, jclass cls) { 221 return (wifi_handle) helper.getStaticLongField(cls, WifiHandleVarName); 222} 223 224static wifi_interface_handle getIfaceHandle(JNIHelper &helper, jclass cls, jint index) { 225 return (wifi_interface_handle) helper.getStaticLongArrayField(cls, WifiIfaceHandleVarName, index); 226} 227 228jboolean 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} 243static 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 273int 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 326static jboolean android_net_wifi_toggle_interface(JNIEnv* env, jclass cls, int toggle) { 327 return(set_iface_flags("wlan0", toggle) == 0); 328} 329 330static 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 365void 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 376static 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 388static 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 398static 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 442static 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 460static 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 469static 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 478static 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 505static 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 572static 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 581static 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 587static 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 653static 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 681static 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 694static byte parseHexByte(const char * &str) { 695 if (str[0] == '\0') { 696 ALOGE("Passed an empty string"); 697 return 0; 698 } 699 byte b = parseHexChar(str[0]); 700 if (str[1] == '\0' || str[1] == ':') { 701 str ++; 702 } else { 703 b = b << 4 | parseHexChar(str[1]); 704 str += 2; 705 } 706 707 // Skip trailing delimiter if not at the end of the string. 708 if (str[0] != '\0') { 709 str++; 710 } 711 return b; 712} 713 714static void parseMacAddress(const char *str, mac_addr addr) { 715 addr[0] = parseHexByte(str); 716 addr[1] = parseHexByte(str); 717 addr[2] = parseHexByte(str); 718 addr[3] = parseHexByte(str); 719 addr[4] = parseHexByte(str); 720 addr[5] = parseHexByte(str); 721} 722 723static bool parseMacAddress(JNIEnv *env, jobject obj, mac_addr addr) { 724 JNIHelper helper(env); 725 JNIObject<jstring> macAddrString = helper.getStringField(obj, "bssid"); 726 if (macAddrString == NULL) { 727 ALOGE("Error getting bssid field"); 728 return false; 729 } 730 731 ScopedUtfChars chars(env, macAddrString); 732 const char *bssid = chars.c_str(); 733 if (bssid == NULL) { 734 ALOGE("Error getting bssid"); 735 return false; 736 } 737 738 parseMacAddress(bssid, addr); 739 return true; 740} 741 742static void onHotlistApFound(wifi_request_id id, 743 unsigned num_results, wifi_scan_result *results) { 744 745 JNIHelper helper(mVM); 746 ALOGD("onHotlistApFound called, vm = %p, obj = %p, num_results = %d", mVM, mCls, num_results); 747 748 JNIObject<jobjectArray> scanResults = helper.newObjectArray(num_results, 749 "android/net/wifi/ScanResult", NULL); 750 if (scanResults == NULL) { 751 ALOGE("Error in allocating array"); 752 return; 753 } 754 755 for (unsigned i = 0; i < num_results; i++) { 756 757 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]); 758 if (scanResult == NULL) { 759 ALOGE("Error in creating scan result"); 760 return; 761 } 762 763 helper.setObjectArrayElement(scanResults, i, scanResult); 764 765 ALOGD("Found AP %32s", results[i].ssid); 766 } 767 768 helper.reportEvent(mCls, "onHotlistApFound", "(I[Landroid/net/wifi/ScanResult;)V", 769 id, scanResults.get()); 770} 771 772static void onHotlistApLost(wifi_request_id id, 773 unsigned num_results, wifi_scan_result *results) { 774 775 JNIHelper helper(mVM); 776 ALOGD("onHotlistApLost called, vm = %p, obj = %p, num_results = %d", mVM, mCls, num_results); 777 778 JNIObject<jobjectArray> scanResults = helper.newObjectArray(num_results, 779 "android/net/wifi/ScanResult", NULL); 780 if (scanResults == NULL) { 781 ALOGE("Error in allocating array"); 782 return; 783 } 784 785 for (unsigned i = 0; i < num_results; i++) { 786 787 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]); 788 if (scanResult == NULL) { 789 ALOGE("Error in creating scan result"); 790 return; 791 } 792 793 helper.setObjectArrayElement(scanResults, i, scanResult); 794 795 ALOGD("Lost AP %32s", results[i].ssid); 796 } 797 798 helper.reportEvent(mCls, "onHotlistApLost", "(I[Landroid/net/wifi/ScanResult;)V", 799 id, scanResults.get()); 800} 801 802 803static jboolean android_net_wifi_setHotlist( 804 JNIEnv *env, jclass cls, jint iface, jint id, jobject ap) { 805 806 JNIHelper helper(env); 807 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 808 ALOGD("setting hotlist on interface[%d] = %p", iface, handle); 809 810 wifi_bssid_hotlist_params params; 811 memset(¶ms, 0, sizeof(params)); 812 813 params.lost_ap_sample_size = helper.getIntField(ap, "apLostThreshold"); 814 815 JNIObject<jobjectArray> array = helper.getArrayField( 816 ap, "bssidInfos", "[Landroid/net/wifi/WifiScanner$BssidInfo;"); 817 params.num_bssid = helper.getArrayLength(array); 818 819 if (params.num_bssid == 0) { 820 ALOGE("Error in accesing array"); 821 return false; 822 } 823 824 for (int i = 0; i < params.num_bssid; i++) { 825 JNIObject<jobject> objAp = helper.getObjectArrayElement(array, i); 826 827 JNIObject<jstring> macAddrString = helper.getStringField(objAp, "bssid"); 828 if (macAddrString == NULL) { 829 ALOGE("Error getting bssid field"); 830 return false; 831 } 832 833 ScopedUtfChars chars(env, macAddrString); 834 const char *bssid = chars.c_str(); 835 if (bssid == NULL) { 836 ALOGE("Error getting bssid"); 837 return false; 838 } 839 parseMacAddress(bssid, params.ap[i].bssid); 840 841 mac_addr addr; 842 memcpy(addr, params.ap[i].bssid, sizeof(mac_addr)); 843 844 char bssidOut[32]; 845 sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1], 846 addr[2], addr[3], addr[4], addr[5]); 847 848 ALOGD("Added bssid %s", bssidOut); 849 850 params.ap[i].low = helper.getIntField(objAp, "low"); 851 params.ap[i].high = helper.getIntField(objAp, "high"); 852 } 853 854 wifi_hotlist_ap_found_handler handler; 855 memset(&handler, 0, sizeof(handler)); 856 857 handler.on_hotlist_ap_found = &onHotlistApFound; 858 handler.on_hotlist_ap_lost = &onHotlistApLost; 859 return hal_fn.wifi_set_bssid_hotlist(id, handle, params, handler) == WIFI_SUCCESS; 860} 861 862static jboolean android_net_wifi_resetHotlist(JNIEnv *env, jclass cls, jint iface, jint id) { 863 864 JNIHelper helper(env); 865 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 866 ALOGD("resetting hotlist on interface[%d] = %p", iface, handle); 867 868 return hal_fn.wifi_reset_bssid_hotlist(id, handle) == WIFI_SUCCESS; 869} 870 871void onSignificantWifiChange(wifi_request_id id, 872 unsigned num_results, wifi_significant_change_result **results) { 873 874 JNIHelper helper(mVM); 875 876 ALOGD("onSignificantWifiChange called, vm = %p, obj = %p", mVM, mCls); 877 878 JNIObject<jobjectArray> scanResults = helper.newObjectArray( 879 num_results, "android/net/wifi/ScanResult", NULL); 880 if (scanResults == NULL) { 881 ALOGE("Error in allocating array"); 882 return; 883 } 884 885 for (unsigned i = 0; i < num_results; i++) { 886 887 wifi_significant_change_result &result = *(results[i]); 888 889 JNIObject<jobject> scanResult = helper.createObject("android/net/wifi/ScanResult"); 890 if (scanResult == NULL) { 891 ALOGE("Error in creating scan result"); 892 return; 893 } 894 895 // helper.setStringField(scanResult, "SSID", results[i].ssid); 896 897 char bssid[32]; 898 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result.bssid[0], result.bssid[1], 899 result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]); 900 901 helper.setStringField(scanResult, "BSSID", bssid); 902 903 helper.setIntField(scanResult, "level", result.rssi[0]); 904 helper.setIntField(scanResult, "frequency", result.channel); 905 // helper.setLongField(scanResult, "timestamp", result.ts); 906 907 helper.setObjectArrayElement(scanResults, i, scanResult); 908 } 909 910 helper.reportEvent(mCls, "onSignificantWifiChange", "(I[Landroid/net/wifi/ScanResult;)V", 911 id, scanResults.get()); 912 913} 914 915static jboolean android_net_wifi_trackSignificantWifiChange( 916 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) { 917 918 JNIHelper helper(env); 919 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 920 ALOGD("tracking significant wifi change on interface[%d] = %p", iface, handle); 921 922 wifi_significant_change_params params; 923 memset(¶ms, 0, sizeof(params)); 924 925 params.rssi_sample_size = helper.getIntField(settings, "rssiSampleSize"); 926 params.lost_ap_sample_size = helper.getIntField(settings, "lostApSampleSize"); 927 params.min_breaching = helper.getIntField(settings, "minApsBreachingThreshold"); 928 929 const char *bssid_info_array_type = "[Landroid/net/wifi/WifiScanner$BssidInfo;"; 930 JNIObject<jobjectArray> bssids = helper.getArrayField( 931 settings, "bssidInfos", bssid_info_array_type); 932 params.num_bssid = helper.getArrayLength(bssids); 933 934 if (params.num_bssid == 0) { 935 ALOGE("Error in accessing array"); 936 return false; 937 } 938 939 ALOGD("Initialized common fields %d, %d, %d, %d", params.rssi_sample_size, 940 params.lost_ap_sample_size, params.min_breaching, params.num_bssid); 941 942 for (int i = 0; i < params.num_bssid; i++) { 943 JNIObject<jobject> objAp = helper.getObjectArrayElement(bssids, i); 944 945 JNIObject<jstring> macAddrString = helper.getStringField(objAp, "bssid"); 946 if (macAddrString == NULL) { 947 ALOGE("Error getting bssid field"); 948 return false; 949 } 950 951 ScopedUtfChars chars(env, macAddrString.get()); 952 const char *bssid = chars.c_str(); 953 if (bssid == NULL) { 954 ALOGE("Error getting bssid"); 955 return false; 956 } 957 958 mac_addr addr; 959 parseMacAddress(bssid, addr); 960 memcpy(params.ap[i].bssid, addr, sizeof(mac_addr)); 961 962 char bssidOut[32]; 963 sprintf(bssidOut, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], 964 addr[2], addr[3], addr[4], addr[5]); 965 966 params.ap[i].low = helper.getIntField(objAp, "low"); 967 params.ap[i].high = helper.getIntField(objAp, "high"); 968 969 ALOGD("Added bssid %s, [%04d, %04d]", bssidOut, params.ap[i].low, params.ap[i].high); 970 } 971 972 ALOGD("Added %d bssids", params.num_bssid); 973 974 wifi_significant_change_handler handler; 975 memset(&handler, 0, sizeof(handler)); 976 977 handler.on_significant_change = &onSignificantWifiChange; 978 return hal_fn.wifi_set_significant_change_handler(id, handle, params, handler) == WIFI_SUCCESS; 979} 980 981static jboolean android_net_wifi_untrackSignificantWifiChange( 982 JNIEnv *env, jclass cls, jint iface, jint id) { 983 984 JNIHelper helper(env); 985 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 986 ALOGD("resetting significant wifi change on interface[%d] = %p", iface, handle); 987 988 return hal_fn.wifi_reset_significant_change_handler(id, handle) == WIFI_SUCCESS; 989} 990 991wifi_iface_stat link_stat; 992wifi_radio_stat radio_stat; // L release has support for only one radio 993 994void onLinkStatsResults(wifi_request_id id, wifi_iface_stat *iface_stat, 995 int num_radios, wifi_radio_stat *radio_stats) 996{ 997 if (iface_stat != 0) { 998 memcpy(&link_stat, iface_stat, sizeof(wifi_iface_stat)); 999 } else { 1000 memset(&link_stat, 0, sizeof(wifi_iface_stat)); 1001 } 1002 1003 if (num_radios > 0 && radio_stats != 0) { 1004 memcpy(&radio_stat, radio_stats, sizeof(wifi_radio_stat)); 1005 } else { 1006 memset(&radio_stat, 0, sizeof(wifi_radio_stat)); 1007 } 1008} 1009 1010static void android_net_wifi_setLinkLayerStats (JNIEnv *env, jclass cls, jint iface, int enable) { 1011 JNIHelper helper(env); 1012 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1013 1014 wifi_link_layer_params params; 1015 params.aggressive_statistics_gathering = enable; 1016 params.mpdu_size_threshold = 128; 1017 1018 ALOGD("android_net_wifi_setLinkLayerStats: %u\n", enable); 1019 1020 hal_fn.wifi_set_link_stats(handle, params); 1021} 1022 1023static jobject android_net_wifi_getLinkLayerStats (JNIEnv *env, jclass cls, jint iface) { 1024 1025 JNIHelper helper(env); 1026 wifi_stats_result_handler handler; 1027 memset(&handler, 0, sizeof(handler)); 1028 handler.on_link_stats_results = &onLinkStatsResults; 1029 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1030 int result = hal_fn.wifi_get_link_stats(0, handle, handler); 1031 if (result < 0) { 1032 ALOGE("android_net_wifi_getLinkLayerStats: failed to get link statistics\n"); 1033 return NULL; 1034 } 1035 1036 JNIObject<jobject> wifiLinkLayerStats = helper.createObject( 1037 "android/net/wifi/WifiLinkLayerStats"); 1038 if (wifiLinkLayerStats == NULL) { 1039 ALOGE("Error in allocating wifiLinkLayerStats"); 1040 return NULL; 1041 } 1042 1043 helper.setIntField(wifiLinkLayerStats, "beacon_rx", link_stat.beacon_rx); 1044 helper.setIntField(wifiLinkLayerStats, "rssi_mgmt", link_stat.rssi_mgmt); 1045 helper.setLongField(wifiLinkLayerStats, "rxmpdu_be", link_stat.ac[WIFI_AC_BE].rx_mpdu); 1046 helper.setLongField(wifiLinkLayerStats, "rxmpdu_bk", link_stat.ac[WIFI_AC_BK].rx_mpdu); 1047 helper.setLongField(wifiLinkLayerStats, "rxmpdu_vi", link_stat.ac[WIFI_AC_VI].rx_mpdu); 1048 helper.setLongField(wifiLinkLayerStats, "rxmpdu_vo", link_stat.ac[WIFI_AC_VO].rx_mpdu); 1049 helper.setLongField(wifiLinkLayerStats, "txmpdu_be", link_stat.ac[WIFI_AC_BE].tx_mpdu); 1050 helper.setLongField(wifiLinkLayerStats, "txmpdu_bk", link_stat.ac[WIFI_AC_BK].tx_mpdu); 1051 helper.setLongField(wifiLinkLayerStats, "txmpdu_vi", link_stat.ac[WIFI_AC_VI].tx_mpdu); 1052 helper.setLongField(wifiLinkLayerStats, "txmpdu_vo", link_stat.ac[WIFI_AC_VO].tx_mpdu); 1053 helper.setLongField(wifiLinkLayerStats, "lostmpdu_be", link_stat.ac[WIFI_AC_BE].mpdu_lost); 1054 helper.setLongField(wifiLinkLayerStats, "lostmpdu_bk", link_stat.ac[WIFI_AC_BK].mpdu_lost); 1055 helper.setLongField(wifiLinkLayerStats, "lostmpdu_vi", link_stat.ac[WIFI_AC_VI].mpdu_lost); 1056 helper.setLongField(wifiLinkLayerStats, "lostmpdu_vo", link_stat.ac[WIFI_AC_VO].mpdu_lost); 1057 helper.setLongField(wifiLinkLayerStats, "retries_be", link_stat.ac[WIFI_AC_BE].retries); 1058 helper.setLongField(wifiLinkLayerStats, "retries_bk", link_stat.ac[WIFI_AC_BK].retries); 1059 helper.setLongField(wifiLinkLayerStats, "retries_vi", link_stat.ac[WIFI_AC_VI].retries); 1060 helper.setLongField(wifiLinkLayerStats, "retries_vo", link_stat.ac[WIFI_AC_VO].retries); 1061 1062 helper.setIntField(wifiLinkLayerStats, "on_time", radio_stat.on_time); 1063 helper.setIntField(wifiLinkLayerStats, "tx_time", radio_stat.tx_time); 1064 helper.setIntField(wifiLinkLayerStats, "rx_time", radio_stat.rx_time); 1065 helper.setIntField(wifiLinkLayerStats, "on_time_scan", radio_stat.on_time_scan); 1066 1067 return wifiLinkLayerStats.detach(); 1068} 1069 1070static jint android_net_wifi_getSupportedFeatures(JNIEnv *env, jclass cls, jint iface) { 1071 1072 JNIHelper helper(env); 1073 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1074 feature_set set = 0; 1075 1076 wifi_error result = WIFI_SUCCESS; 1077 /* 1078 set = WIFI_FEATURE_INFRA 1079 | WIFI_FEATURE_INFRA_5G 1080 | WIFI_FEATURE_HOTSPOT 1081 | WIFI_FEATURE_P2P 1082 | WIFI_FEATURE_SOFT_AP 1083 | WIFI_FEATURE_GSCAN 1084 | WIFI_FEATURE_PNO 1085 | WIFI_FEATURE_TDLS 1086 | WIFI_FEATURE_EPR; 1087 */ 1088 1089 result = hal_fn.wifi_get_supported_feature_set(handle, &set); 1090 if (result == WIFI_SUCCESS) { 1091 // ALOGD("wifi_get_supported_feature_set returned set = 0x%x", set); 1092 return set; 1093 } else { 1094 ALOGE("wifi_get_supported_feature_set returned error = 0x%x", result); 1095 return 0; 1096 } 1097} 1098 1099static void onRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* results[]) { 1100 1101 JNIHelper helper(mVM); 1102 1103 ALOGD("onRttResults called, vm = %p, obj = %p", mVM, mCls); 1104 1105 JNIObject<jobjectArray> rttResults = helper.newObjectArray( 1106 num_results, "android/net/wifi/RttManager$RttResult", NULL); 1107 if (rttResults == NULL) { 1108 ALOGE("Error in allocating array"); 1109 return; 1110 } 1111 1112 for (unsigned i = 0; i < num_results; i++) { 1113 1114 wifi_rtt_result *result = results[i]; 1115 1116 JNIObject<jobject> rttResult = helper.createObject("android/net/wifi/RttManager$RttResult"); 1117 if (rttResult == NULL) { 1118 ALOGE("Error in creating rtt result"); 1119 return; 1120 } 1121 1122 char bssid[32]; 1123 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->addr[0], result->addr[1], 1124 result->addr[2], result->addr[3], result->addr[4], result->addr[5]); 1125 1126 helper.setStringField(rttResult, "bssid", bssid); 1127 helper.setIntField( rttResult, "burstNumber", result->burst_num); 1128 helper.setIntField( rttResult, "measurementFrameNumber", result->measurement_number); 1129 helper.setIntField( rttResult, "successMeasurementFrameNumber", result->success_number); 1130 helper.setIntField(rttResult, "frameNumberPerBurstPeer", result->number_per_burst_peer); 1131 helper.setIntField( rttResult, "status", result->status); 1132 helper.setIntField( rttResult, "measurementType", result->type); 1133 helper.setIntField(rttResult, "retryAfterDuration", result->retry_after_duration); 1134 helper.setLongField(rttResult, "ts", result->ts); 1135 helper.setIntField( rttResult, "rssi", result->rssi); 1136 helper.setIntField( rttResult, "rssiSpread", result->rssi_spread); 1137 helper.setIntField( rttResult, "txRate", result->tx_rate.bitrate); 1138 helper.setIntField( rttResult, "rxRate", result->rx_rate.bitrate); 1139 helper.setLongField(rttResult, "rtt", result->rtt); 1140 helper.setLongField(rttResult, "rttStandardDeviation", result->rtt_sd); 1141 helper.setIntField( rttResult, "distance", result->distance); 1142 helper.setIntField( rttResult, "distanceStandardDeviation", result->distance_sd); 1143 helper.setIntField( rttResult, "distanceSpread", result->distance_spread); 1144 helper.setIntField( rttResult, "burstDuration", result->burst_duration); 1145 helper.setIntField( rttResult, "negotiatedBurstNum", result->negotiated_burst_num); 1146 1147 JNIObject<jobject> LCI = helper.createObject( 1148 "android/net/wifi/RttManager$WifiInformationElement"); 1149 if (result->LCI != NULL && result->LCI->len > 0) { 1150 ALOGD("Add LCI in result"); 1151 helper.setByteField(LCI, "id", result->LCI->id); 1152 JNIObject<jbyteArray> elements = helper.newByteArray(result->LCI->len); 1153 jbyte *bytes = (jbyte *)&(result->LCI->data[0]); 1154 helper.setByteArrayRegion(elements, 0, result->LCI->len, bytes); 1155 helper.setObjectField(LCI, "data", "[B", elements); 1156 } else { 1157 ALOGD("No LCI in result"); 1158 helper.setByteField(LCI, "id", (byte)(0xff)); 1159 } 1160 helper.setObjectField(rttResult, "LCI", 1161 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCI); 1162 1163 JNIObject<jobject> LCR = helper.createObject( 1164 "android/net/wifi/RttManager$WifiInformationElement"); 1165 if (result->LCR != NULL && result->LCR->len > 0) { 1166 ALOGD("Add LCR in result"); 1167 helper.setByteField(LCR, "id", result->LCR->id); 1168 JNIObject<jbyteArray> elements = helper.newByteArray(result->LCI->len); 1169 jbyte *bytes = (jbyte *)&(result->LCR->data[0]); 1170 helper.setByteArrayRegion(elements, 0, result->LCI->len, bytes); 1171 helper.setObjectField(LCR, "data", "[B", elements); 1172 } else { 1173 ALOGD("No LCR in result"); 1174 helper.setByteField(LCR, "id", (byte)(0xff)); 1175 } 1176 helper.setObjectField(rttResult, "LCR", 1177 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCR); 1178 1179 helper.setObjectArrayElement(rttResults, i, rttResult); 1180 } 1181 1182 helper.reportEvent(mCls, "onRttResults", "(I[Landroid/net/wifi/RttManager$RttResult;)V", 1183 id, rttResults.get()); 1184} 1185 1186const int MaxRttConfigs = 16; 1187 1188static jboolean android_net_wifi_requestRange( 1189 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) { 1190 1191 JNIHelper helper(env); 1192 1193 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1194 ALOGD("sending rtt request [%d] = %p", id, handle); 1195 1196 wifi_rtt_config configs[MaxRttConfigs]; 1197 memset(&configs, 0, sizeof(configs)); 1198 1199 int len = helper.getArrayLength((jobjectArray)params); 1200 if (len > MaxRttConfigs) { 1201 return false; 1202 } 1203 1204 for (int i = 0; i < len; i++) { 1205 1206 JNIObject<jobject> param = helper.getObjectArrayElement((jobjectArray)params, i); 1207 if (param == NULL) { 1208 ALOGD("could not get element %d", i); 1209 continue; 1210 } 1211 1212 wifi_rtt_config &config = configs[i]; 1213 1214 parseMacAddress(env, param, config.addr); 1215 config.type = (wifi_rtt_type)helper.getIntField(param, "requestType"); 1216 config.peer = (rtt_peer_type)helper.getIntField(param, "deviceType"); 1217 config.channel.center_freq = helper.getIntField(param, "frequency"); 1218 config.channel.width = (wifi_channel_width) helper.getIntField(param, "channelWidth"); 1219 config.channel.center_freq0 = helper.getIntField(param, "centerFreq0"); 1220 config.channel.center_freq1 = helper.getIntField(param, "centerFreq1"); 1221 1222 config.num_burst = helper.getIntField(param, "numberBurst"); 1223 config.burst_period = (unsigned) helper.getIntField(param, "interval"); 1224 config.num_frames_per_burst = (unsigned) helper.getIntField(param, "numSamplesPerBurst"); 1225 config.num_retries_per_rtt_frame = (unsigned) helper.getIntField(param, 1226 "numRetriesPerMeasurementFrame"); 1227 config.num_retries_per_ftmr = (unsigned) helper.getIntField(param, "numRetriesPerFTMR"); 1228 config.LCI_request = helper.getBoolField(param, "LCIRequest") ? 1 : 0; 1229 config.LCR_request = helper.getBoolField(param, "LCRRequest") ? 1 : 0; 1230 config.burst_duration = (unsigned) helper.getIntField(param, "burstTimeout"); 1231 config.preamble = (wifi_rtt_preamble) helper.getIntField(param, "preamble"); 1232 config.bw = (wifi_rtt_bw) helper.getIntField(param, "bandwidth"); 1233 1234 ALOGD("RTT request destination %d: type is %d, peer is %d, bw is %d, center_freq is %d ", i, 1235 config.type,config.peer, config.channel.width, config.channel.center_freq); 1236 ALOGD("center_freq0 is %d, center_freq1 is %d, num_burst is %d,interval is %d", 1237 config.channel.center_freq0, config.channel.center_freq1, config.num_burst, 1238 config.burst_period); 1239 ALOGD("frames_per_burst is %d, retries of measurement frame is %d, retries_per_ftmr is %d", 1240 config.num_frames_per_burst, config.num_retries_per_rtt_frame, 1241 config.num_retries_per_ftmr); 1242 ALOGD("LCI_requestis %d, LCR_request is %d, burst_timeout is %d, preamble is %d, bw is %d", 1243 config.LCI_request, config.LCR_request, config.burst_duration, config.preamble, 1244 config.bw); 1245 } 1246 1247 wifi_rtt_event_handler handler; 1248 handler.on_rtt_results = &onRttResults; 1249 1250 return hal_fn.wifi_rtt_range_request(id, handle, len, configs, handler) == WIFI_SUCCESS; 1251} 1252 1253static jboolean android_net_wifi_cancelRange( 1254 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) { 1255 1256 JNIHelper helper(env); 1257 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1258 ALOGD("cancelling rtt request [%d] = %p", id, handle); 1259 1260 mac_addr addrs[MaxRttConfigs]; 1261 memset(&addrs, 0, sizeof(addrs)); 1262 1263 int len = helper.getArrayLength((jobjectArray)params); 1264 if (len > MaxRttConfigs) { 1265 return false; 1266 } 1267 1268 for (int i = 0; i < len; i++) { 1269 1270 JNIObject<jobject> param = helper.getObjectArrayElement(params, i); 1271 if (param == NULL) { 1272 ALOGD("could not get element %d", i); 1273 continue; 1274 } 1275 1276 parseMacAddress(env, param, addrs[i]); 1277 } 1278 1279 return hal_fn.wifi_rtt_range_cancel(id, handle, len, addrs) == WIFI_SUCCESS; 1280} 1281 1282static jboolean android_net_wifi_setScanningMacOui(JNIEnv *env, jclass cls, 1283 jint iface, jbyteArray param) { 1284 1285 JNIHelper helper(env); 1286 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1287 ALOGD("setting scan oui %p", handle); 1288 1289 static const unsigned oui_len = 3; /* OUI is upper 3 bytes of mac_address */ 1290 int len = helper.getArrayLength(param); 1291 if (len != oui_len) { 1292 ALOGE("invalid oui length %d", len); 1293 return false; 1294 } 1295 1296 ScopedBytesRO paramBytes(env, param); 1297 const jbyte* bytes = paramBytes.get(); 1298 if (bytes == NULL) { 1299 ALOGE("failed to get array"); 1300 return false; 1301 } 1302 1303 return hal_fn.wifi_set_scanning_mac_oui(handle, (byte *)bytes) == WIFI_SUCCESS; 1304} 1305 1306static jboolean android_net_wifi_is_get_channels_for_band_supported(JNIEnv *env, jclass cls){ 1307 return (hal_fn.wifi_get_valid_channels == wifi_get_valid_channels_stub); 1308} 1309 1310static jintArray android_net_wifi_getValidChannels(JNIEnv *env, jclass cls, 1311 jint iface, jint band) { 1312 1313 JNIHelper helper(env); 1314 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1315 ALOGD("getting valid channels %p", handle); 1316 1317 static const int MaxChannels = 64; 1318 wifi_channel channels[64]; 1319 int num_channels = 0; 1320 wifi_error result = hal_fn.wifi_get_valid_channels(handle, band, MaxChannels, 1321 channels, &num_channels); 1322 1323 if (result == WIFI_SUCCESS) { 1324 JNIObject<jintArray> channelArray = helper.newIntArray(num_channels); 1325 if (channelArray == NULL) { 1326 ALOGE("failed to allocate channel list"); 1327 return NULL; 1328 } 1329 1330 helper.setIntArrayRegion(channelArray, 0, num_channels, channels); 1331 return channelArray.detach(); 1332 } else { 1333 ALOGE("failed to get channel list : %d", result); 1334 return NULL; 1335 } 1336} 1337 1338static jboolean android_net_wifi_setDfsFlag(JNIEnv *env, jclass cls, jint iface, jboolean dfs) { 1339 1340 JNIHelper helper(env); 1341 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1342 ALOGD("setting dfs flag to %s, %p", dfs ? "true" : "false", handle); 1343 1344 u32 nodfs = dfs ? 0 : 1; 1345 wifi_error result = hal_fn.wifi_set_nodfs_flag(handle, nodfs); 1346 return result == WIFI_SUCCESS; 1347} 1348 1349static jobject android_net_wifi_get_rtt_capabilities(JNIEnv *env, jclass cls, jint iface) { 1350 1351 JNIHelper helper(env); 1352 wifi_rtt_capabilities rtt_capabilities; 1353 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1354 wifi_error ret = hal_fn.wifi_get_rtt_capabilities(handle, &rtt_capabilities); 1355 1356 if(WIFI_SUCCESS == ret) { 1357 JNIObject<jobject> capabilities = helper.createObject( 1358 "android/net/wifi/RttManager$RttCapabilities"); 1359 helper.setBooleanField(capabilities, "oneSidedRttSupported", 1360 rtt_capabilities.rtt_one_sided_supported == 1); 1361 helper.setBooleanField(capabilities, "twoSided11McRttSupported", 1362 rtt_capabilities.rtt_ftm_supported == 1); 1363 helper.setBooleanField(capabilities, "lciSupported", 1364 rtt_capabilities.lci_support); 1365 helper.setBooleanField(capabilities, "lcrSupported", 1366 rtt_capabilities.lcr_support); 1367 helper.setIntField(capabilities, "preambleSupported", 1368 rtt_capabilities.preamble_support); 1369 helper.setIntField(capabilities, "bwSupported", 1370 rtt_capabilities.bw_support); 1371 ALOGD("One side RTT is: %s", rtt_capabilities.rtt_one_sided_supported ==1 ? "support" : 1372 "not support"); 1373 ALOGD("Two side RTT is: %s", rtt_capabilities.rtt_ftm_supported == 1 ? "support" : 1374 "not support"); 1375 ALOGD("LCR is: %s", rtt_capabilities.lcr_support == 1 ? "support" : "not support"); 1376 1377 ALOGD("LCI is: %s", rtt_capabilities.lci_support == 1 ? "support" : "not support"); 1378 1379 ALOGD("Support Preamble is : %d support BW is %d", rtt_capabilities.preamble_support, 1380 rtt_capabilities.bw_support); 1381 return capabilities.detach(); 1382 } else { 1383 return NULL; 1384 } 1385} 1386 1387static jboolean android_net_wifi_set_Country_Code_Hal(JNIEnv *env,jclass cls, jint iface, 1388 jstring country_code) { 1389 1390 JNIHelper helper(env); 1391 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1392 1393 ScopedUtfChars chars(env, country_code); 1394 const char *country = chars.c_str(); 1395 1396 ALOGD("set country code: %s", country); 1397 wifi_error res = hal_fn.wifi_set_country_code(handle, country); 1398 return res == WIFI_SUCCESS; 1399} 1400 1401static jboolean android_net_wifi_enable_disable_tdls(JNIEnv *env,jclass cls, jint iface, 1402 jboolean enable, jstring addr) { 1403 1404 JNIHelper helper(env); 1405 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1406 1407 mac_addr address; 1408 parseMacAddress(env, addr, address); 1409 wifi_tdls_handler tdls_handler; 1410 //tdls_handler.on_tdls_state_changed = &on_tdls_state_changed; 1411 1412 if(enable) { 1413 return (hal_fn.wifi_enable_tdls(handle, address, NULL, tdls_handler) == WIFI_SUCCESS); 1414 } else { 1415 return (hal_fn.wifi_disable_tdls(handle, address) == WIFI_SUCCESS); 1416 } 1417} 1418 1419static void on_tdls_state_changed(mac_addr addr, wifi_tdls_status status) { 1420 1421 JNIHelper helper(mVM); 1422 1423 ALOGD("on_tdls_state_changed is called: vm = %p, obj = %p", mVM, mCls); 1424 1425 char mac[32]; 1426 sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], 1427 addr[5]); 1428 1429 JNIObject<jstring> mac_address = helper.newStringUTF(mac); 1430 helper.reportEvent(mCls, "onTdlsStatus", "(Ljava/lang/StringII;)V", 1431 mac_address.get(), status.state, status.reason); 1432 1433} 1434 1435static jobject android_net_wifi_get_tdls_status(JNIEnv *env,jclass cls, jint iface,jstring addr) { 1436 1437 JNIHelper helper(env); 1438 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1439 1440 mac_addr address; 1441 parseMacAddress(env, addr, address); 1442 1443 wifi_tdls_status status; 1444 1445 wifi_error ret; 1446 ret = hal_fn.wifi_get_tdls_status(handle, address, &status ); 1447 1448 if (ret != WIFI_SUCCESS) { 1449 return NULL; 1450 } else { 1451 JNIObject<jobject> tdls_status = helper.createObject( 1452 "com/android/server/wifi/WifiNative$TdlsStatus"); 1453 helper.setIntField(tdls_status, "channel", status.channel); 1454 helper.setIntField(tdls_status, "global_operating_class", status.global_operating_class); 1455 helper.setIntField(tdls_status, "state", status.state); 1456 helper.setIntField(tdls_status, "reason", status.reason); 1457 return tdls_status.detach(); 1458 } 1459} 1460 1461static jobject android_net_wifi_get_tdls_capabilities(JNIEnv *env, jclass cls, jint iface) { 1462 1463 JNIHelper helper(env); 1464 wifi_tdls_capabilities tdls_capabilities; 1465 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1466 wifi_error ret = hal_fn.wifi_get_tdls_capabilities(handle, &tdls_capabilities); 1467 1468 if (WIFI_SUCCESS == ret) { 1469 JNIObject<jobject> capabilities = helper.createObject( 1470 "com/android/server/wifi/WifiNative$TdlsCapabilities"); 1471 helper.setIntField(capabilities, "maxConcurrentTdlsSessionNumber", 1472 tdls_capabilities.max_concurrent_tdls_session_num); 1473 helper.setBooleanField(capabilities, "isGlobalTdlsSupported", 1474 tdls_capabilities.is_global_tdls_supported == 1); 1475 helper.setBooleanField(capabilities, "isPerMacTdlsSupported", 1476 tdls_capabilities.is_per_mac_tdls_supported == 1); 1477 helper.setBooleanField(capabilities, "isOffChannelTdlsSupported", 1478 tdls_capabilities.is_off_channel_tdls_supported); 1479 1480 ALOGD("TDLS Max Concurrent Tdls Session Number is: %d", 1481 tdls_capabilities.max_concurrent_tdls_session_num); 1482 ALOGD("Global Tdls is: %s", tdls_capabilities.is_global_tdls_supported == 1 ? "support" : 1483 "not support"); 1484 ALOGD("Per Mac Tdls is: %s", tdls_capabilities.is_per_mac_tdls_supported == 1 ? "support" : 1485 "not support"); 1486 ALOGD("Off Channel Tdls is: %s", tdls_capabilities.is_off_channel_tdls_supported == 1 ? 1487 "support" : "not support"); 1488 1489 return capabilities.detach(); 1490 } else { 1491 return NULL; 1492 } 1493} 1494 1495// ---------------------------------------------------------------------------- 1496// Debug framework 1497// ---------------------------------------------------------------------------- 1498static jint android_net_wifi_get_supported_logger_feature(JNIEnv *env, jclass cls, jint iface){ 1499 //Not implemented yet 1500 JNIHelper helper(env); 1501 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1502 return -1; 1503} 1504 1505static jobject android_net_wifi_get_driver_version(JNIEnv *env, jclass cls, jint iface) { 1506 //Need to be fixed. The memory should be allocated from lower layer 1507 //char *buffer = NULL; 1508 JNIHelper helper(env); 1509 int buffer_length = 256; 1510 char *buffer = (char *)malloc(buffer_length); 1511 if (!buffer) return NULL; 1512 memset(buffer, 0, buffer_length); 1513 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1514 1515 ALOGD("android_net_wifi_get_driver_version = %p", handle); 1516 1517 if (handle == 0) { 1518 return NULL; 1519 } 1520 1521 wifi_error result = hal_fn.wifi_get_driver_version(handle, buffer, buffer_length); 1522 1523 if (result == WIFI_SUCCESS) { 1524 ALOGD("buffer is %p, length is %d", buffer, buffer_length); 1525 JNIObject<jstring> driver_version = helper.newStringUTF(buffer); 1526 free(buffer); 1527 return driver_version.detach(); 1528 } else { 1529 ALOGD("Fail to get driver version"); 1530 free(buffer); 1531 return NULL; 1532 } 1533} 1534 1535static jobject android_net_wifi_get_firmware_version(JNIEnv *env, jclass cls, jint iface) { 1536 1537 //char *buffer = NULL; 1538 JNIHelper helper(env); 1539 int buffer_length = 256; 1540 char *buffer = (char *)malloc(buffer_length); 1541 if (!buffer) return NULL; 1542 memset(buffer, 0, buffer_length); 1543 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1544 1545 ALOGD("android_net_wifi_get_firmware_version = %p", handle); 1546 1547 if (handle == 0) { 1548 return NULL; 1549 } 1550 1551 wifi_error result = hal_fn.wifi_get_firmware_version(handle, buffer, buffer_length); 1552 1553 if (result == WIFI_SUCCESS) { 1554 ALOGD("buffer is %p, length is %d", buffer, buffer_length); 1555 JNIObject<jstring> firmware_version = helper.newStringUTF(buffer); 1556 free(buffer); 1557 return firmware_version.detach(); 1558 } else { 1559 ALOGD("Fail to get Firmware version"); 1560 free(buffer); 1561 return NULL; 1562 } 1563} 1564 1565static jobject android_net_wifi_get_ring_buffer_status (JNIEnv *env, jclass cls, jint iface) { 1566 1567 JNIHelper helper(env); 1568 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1569 1570 ALOGD("android_net_wifi_get_ring_buffer_status = %p", handle); 1571 1572 if (handle == 0) { 1573 return NULL; 1574 } 1575 1576 //wifi_ring_buffer_status *status = NULL; 1577 u32 num_rings = 10; 1578 wifi_ring_buffer_status *status = 1579 (wifi_ring_buffer_status *)malloc(sizeof(wifi_ring_buffer_status) * num_rings); 1580 if (!status) return NULL; 1581 memset(status, 0, sizeof(wifi_ring_buffer_status) * num_rings); 1582 wifi_error result = hal_fn.wifi_get_ring_buffers_status(handle, &num_rings, status); 1583 if (result == WIFI_SUCCESS) { 1584 ALOGD("status is %p, number is %d", status, num_rings); 1585 1586 JNIObject<jobjectArray> ringBuffersStatus = helper.newObjectArray( 1587 num_rings, "com/android/server/wifi/WifiNative$RingBufferStatus", NULL); 1588 1589 wifi_ring_buffer_status *tmp = status; 1590 1591 for(u32 i = 0; i < num_rings; i++, tmp++) { 1592 1593 JNIObject<jobject> ringStatus = helper.createObject( 1594 "com/android/server/wifi/WifiNative$RingBufferStatus"); 1595 1596 if (ringStatus == NULL) { 1597 ALOGE("Error in creating ringBufferStatus"); 1598 free(status); 1599 return NULL; 1600 } 1601 1602 char name[32]; 1603 for(int j = 0; j < 32; j++) { 1604 name[j] = tmp->name[j]; 1605 } 1606 1607 helper.setStringField(ringStatus, "name", name); 1608 helper.setIntField(ringStatus, "flag", tmp->flags); 1609 helper.setIntField(ringStatus, "ringBufferId", tmp->ring_id); 1610 helper.setIntField(ringStatus, "ringBufferByteSize", tmp->ring_buffer_byte_size); 1611 helper.setIntField(ringStatus, "verboseLevel", tmp->verbose_level); 1612 helper.setIntField(ringStatus, "writtenBytes", tmp->written_bytes); 1613 helper.setIntField(ringStatus, "readBytes", tmp->read_bytes); 1614 helper.setIntField(ringStatus, "writtenRecords", tmp->written_records); 1615 1616 helper.setObjectArrayElement(ringBuffersStatus, i, ringStatus); 1617 } 1618 1619 free(status); 1620 return ringBuffersStatus.detach(); 1621 } else { 1622 free(status); 1623 return NULL; 1624 } 1625} 1626 1627static void on_ring_buffer_data(char *ring_name, char *buffer, int buffer_size, 1628 wifi_ring_buffer_status *status) { 1629 1630 if (!ring_name || !buffer || !status || 1631 (unsigned int)buffer_size <= sizeof(wifi_ring_buffer_entry)) { 1632 ALOGE("Error input for on_ring_buffer_data!"); 1633 return; 1634 } 1635 1636 1637 JNIHelper helper(mVM); 1638 /* ALOGD("on_ring_buffer_data called, vm = %p, obj = %p, env = %p buffer size = %d", mVM, 1639 mCls, env, buffer_size); */ 1640 1641 JNIObject<jobject> ringStatus = helper.createObject( 1642 "com/android/server/wifi/WifiNative$RingBufferStatus"); 1643 if (status == NULL) { 1644 ALOGE("Error in creating ringBufferStatus"); 1645 return; 1646 } 1647 1648 helper.setStringField(ringStatus, "name", ring_name); 1649 helper.setIntField(ringStatus, "flag", status->flags); 1650 helper.setIntField(ringStatus, "ringBufferId", status->ring_id); 1651 helper.setIntField(ringStatus, "ringBufferByteSize", status->ring_buffer_byte_size); 1652 helper.setIntField(ringStatus, "verboseLevel", status->verbose_level); 1653 helper.setIntField(ringStatus, "writtenBytes", status->written_bytes); 1654 helper.setIntField(ringStatus, "readBytes", status->read_bytes); 1655 helper.setIntField(ringStatus, "writtenRecords", status->written_records); 1656 1657 JNIObject<jbyteArray> bytes = helper.newByteArray(buffer_size); 1658 helper.setByteArrayRegion(bytes, 0, buffer_size, (jbyte*)buffer); 1659 1660 helper.reportEvent(mCls,"onRingBufferData", 1661 "(Lcom/android/server/wifi/WifiNative$RingBufferStatus;[B)V", 1662 ringStatus.get(), bytes.get()); 1663} 1664 1665static void on_alert_data(wifi_request_id id, char *buffer, int buffer_size, int err_code){ 1666 1667 JNIHelper helper(mVM); 1668 ALOGD("on_alert_data called, vm = %p, obj = %p, buffer_size = %d, error code = %d" 1669 , mVM, mCls, buffer_size, err_code); 1670 1671 if (buffer_size > 0) { 1672 JNIObject<jbyteArray> records = helper.newByteArray(buffer_size); 1673 jbyte *bytes = (jbyte *) buffer; 1674 helper.setByteArrayRegion(records, 0,buffer_size, bytes); 1675 helper.reportEvent(mCls,"onWifiAlert","([BI)V", records.get(), err_code); 1676 } else { 1677 helper.reportEvent(mCls,"onWifiAlert","([BI)V", NULL, err_code); 1678 } 1679} 1680 1681 1682static jboolean android_net_wifi_start_logging_ring_buffer(JNIEnv *env, jclass cls, jint iface, 1683 jint verbose_level,jint flags, jint max_interval,jint min_data_size, jstring ring_name) { 1684 1685 JNIHelper helper(env); 1686 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1687 1688 ALOGD("android_net_wifi_start_logging_ring_buffer = %p", handle); 1689 1690 if (handle == 0) { 1691 return false; 1692 } 1693 1694 ScopedUtfChars chars(env, ring_name); 1695 const char* ring_name_const_char = chars.c_str(); 1696 int ret = hal_fn.wifi_start_logging(handle, verbose_level, 1697 flags, max_interval, min_data_size, const_cast<char *>(ring_name_const_char)); 1698 1699 if (ret != WIFI_SUCCESS) { 1700 ALOGE("Fail to start logging for ring %s", ring_name_const_char); 1701 } else { 1702 ALOGD("start logging for ring %s", ring_name_const_char); 1703 } 1704 1705 return ret == WIFI_SUCCESS; 1706} 1707 1708static jboolean android_net_wifi_get_ring_buffer_data(JNIEnv *env, jclass cls, jint iface, 1709 jstring ring_name) { 1710 1711 JNIHelper helper(env); 1712 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1713 // ALOGD("android_net_wifi_get_ring_buffer_data = %p", handle); 1714 1715 ScopedUtfChars chars(env, ring_name); 1716 const char* ring_name_const_char = chars.c_str(); 1717 int result = hal_fn.wifi_get_ring_data(handle, const_cast<char *>(ring_name_const_char)); 1718 return result == WIFI_SUCCESS; 1719} 1720 1721 1722void on_firmware_memory_dump(char *buffer, int buffer_size) { 1723 1724 JNIHelper helper(mVM); 1725 /* ALOGD("on_firmware_memory_dump called, vm = %p, obj = %p, env = %p buffer_size = %d" 1726 , mVM, mCls, env, buffer_size); */ 1727 1728 if (buffer_size > 0) { 1729 JNIObject<jbyteArray> dump = helper.newByteArray(buffer_size); 1730 jbyte *bytes = (jbyte *) (buffer); 1731 helper.setByteArrayRegion(dump, 0, buffer_size, bytes); 1732 helper.reportEvent(mCls,"onWifiFwMemoryAvailable","([B)V", dump.get()); 1733 } 1734} 1735 1736static jboolean android_net_wifi_get_fw_memory_dump(JNIEnv *env, jclass cls, jint iface){ 1737 1738 JNIHelper helper(env); 1739 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1740 // ALOGD("android_net_wifi_get_fw_memory_dump = %p", handle); 1741 1742 if (handle == NULL) { 1743 ALOGE("Can not get wifi_interface_handle"); 1744 return false; 1745 } 1746 1747 wifi_firmware_memory_dump_handler fw_dump_handle; 1748 fw_dump_handle.on_firmware_memory_dump = on_firmware_memory_dump; 1749 int result = hal_fn.wifi_get_firmware_memory_dump(handle, fw_dump_handle); 1750 return result == WIFI_SUCCESS; 1751 1752} 1753 1754static jboolean android_net_wifi_set_log_handler(JNIEnv *env, jclass cls, jint iface, jint id) { 1755 1756 JNIHelper helper(env); 1757 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1758 ALOGD("android_net_wifi_set_log_handler = %p", handle); 1759 1760 //initialize the handler on first time 1761 wifi_ring_buffer_data_handler handler; 1762 handler.on_ring_buffer_data = &on_ring_buffer_data; 1763 int result = hal_fn.wifi_set_log_handler(id, handle, handler); 1764 if (result != WIFI_SUCCESS) { 1765 ALOGE("Fail to set logging handler"); 1766 return false; 1767 } 1768 1769 //set alter handler This will start alert too 1770 wifi_alert_handler alert_handler; 1771 alert_handler.on_alert = &on_alert_data; 1772 result = hal_fn.wifi_set_alert_handler(id, handle, alert_handler); 1773 if (result != WIFI_SUCCESS) { 1774 ALOGE(" Fail to set alert handler"); 1775 return false; 1776 } 1777 1778 return true; 1779} 1780 1781static jboolean android_net_wifi_reset_log_handler(JNIEnv *env, jclass cls, jint iface, jint id) { 1782 1783 JNIHelper helper(env); 1784 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1785 1786 //reset alter handler 1787 ALOGD("android_net_wifi_reset_alert_handler = %p", handle); 1788 int result = hal_fn.wifi_reset_alert_handler(id, handle); 1789 if (result != WIFI_SUCCESS) { 1790 ALOGE(" Fail to reset alert handler"); 1791 return false; 1792 } 1793 1794 //reset log handler 1795 ALOGD("android_net_wifi_reset_log_handler = %p", handle); 1796 result = hal_fn.wifi_reset_log_handler(id, handle); 1797 if (result != WIFI_SUCCESS) { 1798 ALOGE("Fail to reset logging handler"); 1799 return false; 1800 } 1801 1802 return true; 1803} 1804 1805// ---------------------------------------------------------------------------- 1806// ePno framework 1807// ---------------------------------------------------------------------------- 1808 1809 1810static void onPnoNetworkFound(wifi_request_id id, 1811 unsigned num_results, wifi_scan_result *results) { 1812 1813 JNIHelper helper(mVM); 1814 1815 ALOGD("onPnoNetworkFound called, vm = %p, obj = %p, num_results %u", mVM, mCls, num_results); 1816 1817 if (results == 0 || num_results == 0) { 1818 ALOGE("onPnoNetworkFound: Error no results"); 1819 return; 1820 } 1821 1822 jbyte *bytes; 1823 JNIObject<jobjectArray> scanResults(helper, NULL); 1824 //jbyteArray elements; 1825 1826 for (unsigned i=0; i<num_results; i++) { 1827 1828 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]); 1829 if (i == 0) { 1830 scanResults = helper.newObjectArray( 1831 num_results, "android/net/wifi/ScanResult", scanResult); 1832 if (scanResults == 0) { 1833 ALOGD("cant allocate array"); 1834 } else { 1835 ALOGD("allocated array %u", helper.getArrayLength(scanResults)); 1836 } 1837 } else { 1838 helper.setObjectArrayElement(scanResults, i, scanResult); 1839 } 1840 1841 ALOGD("Scan result with ie length %d, i %u, <%s> rssi=%d %02x:%02x:%02x:%02x:%02x:%02x", 1842 results->ie_length, i, results[i].ssid, results[i].rssi, results[i].bssid[0], 1843 results[i].bssid[1],results[i].bssid[2], results[i].bssid[3], results[i].bssid[4], 1844 results[i].bssid[5]); 1845 1846 /*elements = helper.newByteArray(results->ie_length); 1847 if (elements == NULL) { 1848 ALOGE("Error in allocating array"); 1849 return; 1850 }*/ 1851 1852 //ALOGD("onPnoNetworkFound: Setting byte array"); 1853 1854 //bytes = (jbyte *)&(results->ie_data[0]); 1855 //helper.setByteArrayRegion(elements, 0, results->ie_length, bytes); 1856 1857 //ALOGD("onPnoNetworkFound: Returning result"); 1858 } 1859 1860 1861 ALOGD("calling report"); 1862 1863 helper.reportEvent(mCls, "onPnoNetworkFound", "(I[Landroid/net/wifi/ScanResult;)V", id, 1864 scanResults.get()); 1865 ALOGD("free ref"); 1866} 1867 1868static jboolean android_net_wifi_setPnoListNative( 1869 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) { 1870 1871 JNIHelper helper(env); 1872 wifi_epno_handler handler; 1873 handler.on_network_found = &onPnoNetworkFound; 1874 1875 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1876 ALOGD("configure ePno list request [%d] = %p", id, handle); 1877 1878 if (list == NULL) { 1879 // stop pno 1880 int result = hal_fn.wifi_set_epno_list(id, handle, 0, NULL, handler); 1881 ALOGE(" setPnoListNative: STOP result = %d", result); 1882 return result >= 0; 1883 } 1884 1885 wifi_epno_network net_list[MAX_PNO_SSID]; 1886 memset(&net_list, 0, sizeof(net_list)); 1887 1888 size_t len = helper.getArrayLength((jobjectArray)list); 1889 if (len > (size_t)MAX_PNO_SSID) { 1890 return false; 1891 } 1892 1893 for (unsigned int i = 0; i < len; i++) { 1894 1895 JNIObject<jobject> pno_net = helper.getObjectArrayElement((jobjectArray)list, i); 1896 if (pno_net == NULL) { 1897 ALOGD("setPnoListNative: could not get element %d", i); 1898 continue; 1899 } 1900 1901 JNIObject<jstring> sssid = helper.getStringField(pno_net, "SSID"); 1902 if (sssid == NULL) { 1903 ALOGE("Error setPnoListNative: getting ssid field"); 1904 return false; 1905 } 1906 1907 ScopedUtfChars chars(env, (jstring)sssid.get()); 1908 const char *ssid = chars.c_str(); 1909 if (ssid == NULL) { 1910 ALOGE("Error setPnoListNative: getting ssid"); 1911 return false; 1912 } 1913 int ssid_len = strnlen((const char*)ssid, 33); 1914 if (ssid_len > 32) { 1915 ALOGE("Error setPnoListNative: long ssid %u", strnlen((const char*)ssid, 256)); 1916 return false; 1917 } 1918 1919 if (ssid_len > 1 && ssid[0] == '"' && ssid[ssid_len-1]) 1920 { 1921 // strip leading and trailing '"' 1922 ssid++; 1923 ssid_len-=2; 1924 } 1925 if (ssid_len == 0) { 1926 ALOGE("Error setPnoListNative: zero length ssid, skip it"); 1927 continue; 1928 } 1929 memcpy(net_list[i].ssid, ssid, ssid_len); 1930 1931 int rssit = helper.getIntField(pno_net, "rssi_threshold"); 1932 net_list[i].rssi_threshold = (byte)rssit; 1933 int a = helper.getIntField(pno_net, "auth"); 1934 net_list[i].auth_bit_field = a; 1935 int f = helper.getIntField(pno_net, "flags"); 1936 net_list[i].flags = f; 1937 ALOGE(" setPnoListNative: idx %u rssi %d/%d auth %x/%x flags %x/%x [%s]", i, 1938 (signed)net_list[i].rssi_threshold, net_list[i].rssi_threshold, 1939 net_list[i].auth_bit_field, a, net_list[i].flags, f, net_list[i].ssid); 1940 } 1941 1942 int result = hal_fn.wifi_set_epno_list(id, handle, len, net_list, handler); 1943 ALOGE(" setPnoListNative: result %d", result); 1944 1945 return result >= 0; 1946} 1947 1948static jboolean android_net_wifi_setLazyRoam( 1949 JNIEnv *env, jclass cls, jint iface, jint id, jboolean enabled, jobject roam_param) { 1950 1951 JNIHelper helper(env); 1952 wifi_error status = WIFI_SUCCESS; 1953 wifi_roam_params params; 1954 memset(¶ms, 0, sizeof(params)); 1955 1956 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1957 ALOGD("configure lazy roam request [%d] = %p", id, handle); 1958 1959 if (roam_param != NULL) { 1960 params.A_band_boost_threshold = helper.getIntField(roam_param, "A_band_boost_threshold"); 1961 params.A_band_penalty_threshold = helper.getIntField(roam_param, "A_band_penalty_threshold"); 1962 params.A_band_boost_factor = helper.getIntField(roam_param, "A_band_boost_factor"); 1963 params.A_band_penalty_factor = helper.getIntField(roam_param, "A_band_penalty_factor"); 1964 params.A_band_max_boost = helper.getIntField(roam_param, "A_band_max_boost"); 1965 params.lazy_roam_hysteresis = helper.getIntField(roam_param, "lazy_roam_hysteresis"); 1966 params.alert_roam_rssi_trigger = helper.getIntField(roam_param, "alert_roam_rssi_trigger"); 1967 status = hal_fn.wifi_set_gscan_roam_params(id, handle, ¶ms); 1968 } 1969 ALOGE("android_net_wifi_setLazyRoam configured params status=%d\n", status); 1970 1971 if (status >= 0) { 1972 int doEnable = enabled ? 1 : 0; 1973 status = hal_fn.wifi_enable_lazy_roam(id, handle, doEnable); 1974 ALOGE("android_net_wifi_setLazyRoam enabled roam status=%d\n", status); 1975 } 1976 return status >= 0; 1977} 1978 1979static jboolean android_net_wifi_setBssidBlacklist( 1980 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) { 1981 1982 JNIHelper helper(env); 1983 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 1984 ALOGD("configure BSSID black list request [%d] = %p", id, handle); 1985 1986 wifi_bssid_params params; 1987 memset(¶ms, 0, sizeof(params)); 1988 1989 if (list != NULL) { 1990 size_t len = helper.getArrayLength((jobjectArray)list); 1991 if (len > (size_t)MAX_BLACKLIST_BSSID) { 1992 return false; 1993 } 1994 for (unsigned int i = 0; i < len; i++) { 1995 1996 JNIObject<jobject> jbssid = helper.getObjectArrayElement(list, i); 1997 if (jbssid == NULL) { 1998 ALOGD("configure BSSID blacklist: could not get element %d", i); 1999 continue; 2000 } 2001 2002 ScopedUtfChars chars(env, (jstring)jbssid.get()); 2003 const char *bssid = chars.c_str(); 2004 if (bssid == NULL) { 2005 ALOGE("Error getting bssid"); 2006 return false; 2007 } 2008 2009 mac_addr addr; 2010 parseMacAddress(bssid, addr); 2011 memcpy(params.bssids[i], addr, sizeof(mac_addr)); 2012 2013 char bssidOut[32]; 2014 sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1], 2015 addr[2], addr[3], addr[4], addr[5]); 2016 2017 ALOGD("BSSID blacklist: added bssid %s", bssidOut); 2018 2019 params.num_bssid++; 2020 } 2021 } 2022 2023 ALOGD("Added %d bssids", params.num_bssid); 2024 return hal_fn.wifi_set_bssid_blacklist(id, handle, params) == WIFI_SUCCESS; 2025} 2026 2027static jboolean android_net_wifi_setSsidWhitelist( 2028 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) { 2029 2030 JNIHelper helper(env); 2031 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface); 2032 ALOGD("configure SSID white list request [%d] = %p", id, handle); 2033 wifi_ssid *ssids = NULL; 2034 int num_ssids = 0; 2035 if (list != NULL) { 2036 size_t len = helper.getArrayLength((jobjectArray)list); 2037 if (len > 0) { 2038 ssids = (wifi_ssid *)malloc(len * sizeof (wifi_ssid)); 2039 if (!ssids) return false; 2040 memset(ssids, 0, len * sizeof (wifi_ssid)); 2041 for (unsigned int i = 0; i < len; i++) { 2042 2043 JNIObject<jobject> jssid = helper.getObjectArrayElement(list, i); 2044 if (jssid == NULL) { 2045 ALOGD("configure SSID whitelist: could not get element %d", i); 2046 free(ssids); 2047 return false; 2048 } 2049 2050 ScopedUtfChars chars(env, (jstring)jssid.get()); 2051 const char *utf = chars.c_str(); 2052 if (utf == NULL) { 2053 ALOGE("Error getting sssid"); 2054 free(ssids); 2055 return false; 2056 } 2057 2058 int slen = strnlen(utf, 33); 2059 if (slen <= 0 || slen > 32) { 2060 ALOGE("Error wrong ssid length %d", slen); 2061 free(ssids); 2062 return false; 2063 } 2064 2065 memcpy(ssids[i].ssid, utf, slen); 2066 num_ssids++; 2067 ALOGD("SSID white list: added ssid %s", utf); 2068 } 2069 } 2070 } 2071 2072 ALOGD("android_net_wifi_setSsidWhitelist Added %d sssids", num_ssids); 2073 return hal_fn.wifi_set_ssid_white_list(id, handle, num_ssids, ssids) == WIFI_SUCCESS; 2074} 2075 2076// ---------------------------------------------------------------------------- 2077 2078/* 2079 * JNI registration. 2080 */ 2081static JNINativeMethod gWifiMethods[] = { 2082 /* name, signature, funcPtr */ 2083 2084 { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver }, 2085 { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded }, 2086 { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver }, 2087 { "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant }, 2088 { "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant }, 2089 { "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant }, 2090 { "closeSupplicantConnectionNative", "()V", 2091 (void *)android_net_wifi_closeSupplicantConnection }, 2092 { "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForEvent }, 2093 { "doBooleanCommandNative", "(Ljava/lang/String;)Z", (void*)android_net_wifi_doBooleanCommand }, 2094 { "doIntCommandNative", "(Ljava/lang/String;)I", (void*)android_net_wifi_doIntCommand }, 2095 { "doStringCommandNative", "(Ljava/lang/String;)Ljava/lang/String;", 2096 (void*) android_net_wifi_doStringCommand }, 2097 { "startHalNative", "()Z", (void*) android_net_wifi_startHal }, 2098 { "stopHalNative", "()V", (void*) android_net_wifi_stopHal }, 2099 { "waitForHalEventNative", "()V", (void*) android_net_wifi_waitForHalEvents }, 2100 { "getInterfacesNative", "()I", (void*) android_net_wifi_getInterfaces}, 2101 { "getInterfaceNameNative", "(I)Ljava/lang/String;", (void*) android_net_wifi_getInterfaceName}, 2102 { "getScanCapabilitiesNative", "(ILcom/android/server/wifi/WifiNative$ScanCapabilities;)Z", 2103 (void *) android_net_wifi_getScanCapabilities}, 2104 { "startScanNative", "(IILcom/android/server/wifi/WifiNative$ScanSettings;)Z", 2105 (void*) android_net_wifi_startScan}, 2106 { "stopScanNative", "(II)Z", (void*) android_net_wifi_stopScan}, 2107 { "getScanResultsNative", "(IZ)[Landroid/net/wifi/WifiScanner$ScanData;", 2108 (void *) android_net_wifi_getScanResults}, 2109 { "setHotlistNative", "(IILandroid/net/wifi/WifiScanner$HotlistSettings;)Z", 2110 (void*) android_net_wifi_setHotlist}, 2111 { "resetHotlistNative", "(II)Z", (void*) android_net_wifi_resetHotlist}, 2112 { "trackSignificantWifiChangeNative", "(IILandroid/net/wifi/WifiScanner$WifiChangeSettings;)Z", 2113 (void*) android_net_wifi_trackSignificantWifiChange}, 2114 { "untrackSignificantWifiChangeNative", "(II)Z", 2115 (void*) android_net_wifi_untrackSignificantWifiChange}, 2116 { "getWifiLinkLayerStatsNative", "(I)Landroid/net/wifi/WifiLinkLayerStats;", 2117 (void*) android_net_wifi_getLinkLayerStats}, 2118 { "setWifiLinkLayerStatsNative", "(II)V", 2119 (void*) android_net_wifi_setLinkLayerStats}, 2120 { "getSupportedFeatureSetNative", "(I)I", 2121 (void*) android_net_wifi_getSupportedFeatures}, 2122 { "requestRangeNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z", 2123 (void*) android_net_wifi_requestRange}, 2124 { "cancelRangeRequestNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z", 2125 (void*) android_net_wifi_cancelRange}, 2126 { "setScanningMacOuiNative", "(I[B)Z", (void*) android_net_wifi_setScanningMacOui}, 2127 { "getChannelsForBandNative", "(II)[I", (void*) android_net_wifi_getValidChannels}, 2128 { "setDfsFlagNative", "(IZ)Z", (void*) android_net_wifi_setDfsFlag}, 2129 { "toggleInterfaceNative", "(I)Z", (void*) android_net_wifi_toggle_interface}, 2130 { "getRttCapabilitiesNative", "(I)Landroid/net/wifi/RttManager$RttCapabilities;", 2131 (void*) android_net_wifi_get_rtt_capabilities}, 2132 {"setCountryCodeHalNative", "(ILjava/lang/String;)Z", 2133 (void*) android_net_wifi_set_Country_Code_Hal}, 2134 { "setPnoListNative", "(II[Lcom/android/server/wifi/WifiNative$WifiPnoNetwork;)Z", 2135 (void*) android_net_wifi_setPnoListNative}, 2136 {"enableDisableTdlsNative", "(IZLjava/lang/String;)Z", 2137 (void*) android_net_wifi_enable_disable_tdls}, 2138 {"getTdlsStatusNative", "(ILjava/lang/String;)Lcom/android/server/wifi/WifiNative$TdlsStatus;", 2139 (void*) android_net_wifi_get_tdls_status}, 2140 {"getTdlsCapabilitiesNative", "(I)Lcom/android/server/wifi/WifiNative$TdlsCapabilities;", 2141 (void*) android_net_wifi_get_tdls_capabilities}, 2142 {"getSupportedLoggerFeatureSetNative","(I)I", 2143 (void*) android_net_wifi_get_supported_logger_feature}, 2144 {"getDriverVersionNative", "(I)Ljava/lang/String;", 2145 (void*) android_net_wifi_get_driver_version}, 2146 {"getFirmwareVersionNative", "(I)Ljava/lang/String;", 2147 (void*) android_net_wifi_get_firmware_version}, 2148 {"getRingBufferStatusNative", "(I)[Lcom/android/server/wifi/WifiNative$RingBufferStatus;", 2149 (void*) android_net_wifi_get_ring_buffer_status}, 2150 {"startLoggingRingBufferNative", "(IIIIILjava/lang/String;)Z", 2151 (void*) android_net_wifi_start_logging_ring_buffer}, 2152 {"getRingBufferDataNative", "(ILjava/lang/String;)Z", 2153 (void*) android_net_wifi_get_ring_buffer_data}, 2154 {"getFwMemoryDumpNative","(I)Z", (void*) android_net_wifi_get_fw_memory_dump}, 2155 { "setLazyRoamNative", "(IIZLcom/android/server/wifi/WifiNative$WifiLazyRoamParams;)Z", 2156 (void*) android_net_wifi_setLazyRoam}, 2157 { "setBssidBlacklistNative", "(II[Ljava/lang/String;)Z", 2158 (void*)android_net_wifi_setBssidBlacklist}, 2159 { "setSsidWhitelistNative", "(II[Ljava/lang/String;)Z", 2160 (void*)android_net_wifi_setSsidWhitelist}, 2161 {"setLoggingEventHandlerNative", "(II)Z", (void *) android_net_wifi_set_log_handler}, 2162 {"resetLogHandlerNative", "(II)Z", (void *) android_net_wifi_reset_log_handler}, 2163 {"isGetChannelsForBandSupportedNative", "()Z", 2164 (void*)android_net_wifi_is_get_channels_for_band_supported} 2165}; 2166 2167int register_android_net_wifi_WifiNative(JNIEnv* env) { 2168 return AndroidRuntime::registerNativeMethods(env, 2169 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods)); 2170} 2171 2172 2173/* User to register native functions */ 2174extern "C" 2175jint Java_com_android_server_wifi_WifiNative_registerNatives(JNIEnv* env, jclass clazz) { 2176 return AndroidRuntime::registerNativeMethods(env, 2177 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods)); 2178} 2179 2180}; // namespace android 2181