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