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