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