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