com_android_server_wifi_WifiNative.cpp revision e4e3750390bec0a849a9153348b7c21b2cc8b843
1155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/* 2155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Copyright 2008, The Android Open Source Project 3155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 4155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Licensed under the Apache License, Version 2.0 (the "License"); 5155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * you may not use this file except in compliance with the License. 6155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * You may obtain a copy of the License at 7155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 8155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * http://www.apache.org/licenses/LICENSE-2.0 9155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 10155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Unless required by applicable law or agreed to in writing, software 11155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * distributed under the License is distributed on an "AS IS" BASIS, 12155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See the License for the specific language governing permissions and 14155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * limitations under the License. 15155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 16155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 17155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande#define LOG_TAG "wifi" 18155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 19155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande#include "jni.h" 20155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande#include <ScopedUtfChars.h> 21155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande#include <utils/misc.h> 22155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande#include <android_runtime/AndroidRuntime.h> 23155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande#include <utils/Log.h> 24155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande#include <utils/String16.h> 25e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde#include <ctype.h> 26155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 27155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande#include "wifi.h" 287ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde#include "wifi_hal.h" 297f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde#include "jni_helper.h" 30155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 31155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande#define REPLY_BUF_SIZE 4096 // wpa_supplicant's maximum size. 32155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande#define EVENT_BUF_SIZE 2048 33155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 34155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandenamespace android { 35155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 36155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jint DBG = false; 37155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 38155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic bool doCommand(JNIEnv* env, jstring javaCommand, 39155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande char* reply, size_t reply_len) { 40155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande ScopedUtfChars command(env, javaCommand); 41155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (command.c_str() == NULL) { 42155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return false; // ScopedUtfChars already threw on error. 43155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 44155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 45155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) { 46155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande ALOGD("doCommand: %s", command.c_str()); 47155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 48155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 49155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande --reply_len; // Ensure we have room to add NUL termination. 50155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (::wifi_command(command.c_str(), reply, &reply_len) != 0) { 51155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return false; 52155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 53155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 54155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande // Strip off trailing newline. 55155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (reply_len > 0 && reply[reply_len-1] == '\n') { 56155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande reply[reply_len-1] = '\0'; 57155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 58155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande reply[reply_len] = '\0'; 59155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 60155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return true; 61155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 62155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 63155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jint doIntCommand(JNIEnv* env, jstring javaCommand) { 64155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande char reply[REPLY_BUF_SIZE]; 65155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (!doCommand(env, javaCommand, reply, sizeof(reply))) { 66155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return -1; 67155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 68155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return static_cast<jint>(atoi(reply)); 69155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 70155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 71155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jboolean doBooleanCommand(JNIEnv* env, jstring javaCommand) { 72155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande char reply[REPLY_BUF_SIZE]; 73155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (!doCommand(env, javaCommand, reply, sizeof(reply))) { 74155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return JNI_FALSE; 75155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 76155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return (strcmp(reply, "OK") == 0); 77155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 78155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 79155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande// Send a command to the supplicant, and return the reply as a String. 80155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jstring doStringCommand(JNIEnv* env, jstring javaCommand) { 81155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande char reply[REPLY_BUF_SIZE]; 82155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (!doCommand(env, javaCommand, reply, sizeof(reply))) { 83155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NULL; 84155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 85155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return env->NewStringUTF(reply); 86155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 87155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 88155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject) 89155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande{ 90155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return (::is_wifi_driver_loaded() == 1); 91155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 92155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 93155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject) 94155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande{ 95155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return (::wifi_load_driver() == 0); 96155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 97155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 98155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject) 99155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande{ 100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return (::wifi_unload_driver() == 0); 101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) 104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande{ 105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return (::wifi_start_supplicant(p2pSupported) == 0); 106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) 109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande{ 110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return (::wifi_stop_supplicant(p2pSupported) == 0); 111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject) 114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande{ 115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return (::wifi_connect_to_supplicant() == 0); 116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject) 119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande{ 120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande ::wifi_close_supplicant_connection(); 121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject) 124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande{ 125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande char buf[EVENT_BUF_SIZE]; 126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande int nread = ::wifi_wait_for_event(buf, sizeof buf); 127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (nread > 0) { 128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return env->NewStringUTF(buf); 129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NULL; 131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) { 135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return doBooleanCommand(env, javaCommand); 136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) { 139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return doIntCommand(env, javaCommand); 140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) { 143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return doStringCommand(env,javaCommand); 144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 1467f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* wifi_hal <==> WifiNative bridge */ 1477f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 1487f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic jobject mObj; /* saved WifiNative object */ 1497f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic JavaVM *mVM; /* saved JVM pointer */ 1507f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 1517f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic const char *WifiHandleVarName = "mWifiHalHandle"; 1527f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic const char *WifiIfaceHandleVarName = "mWifiIfaceHandles"; 1537f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic jmethodID OnScanResultsMethodID; 1547f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 1557f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic JNIEnv *getEnv() { 1567f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde JNIEnv *env = NULL; 1577f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde mVM->AttachCurrentThread(&env, NULL); 1587f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return env; 1597f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde} 1607f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 1617f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic wifi_handle getWifiHandle(JNIEnv *env, jobject obj) { 1627f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return (wifi_handle) getLongField(env, obj, WifiHandleVarName); 1637f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde} 1647f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 1657f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic wifi_interface_handle getIfaceHandle(JNIEnv *env, jobject obj, jint index) { 1667f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return (wifi_interface_handle) getLongArrayField(env, obj, WifiIfaceHandleVarName, index); 1677f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde} 1687f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 1697f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic jboolean android_net_wifi_startHal(JNIEnv* env, jobject obj) { 1707ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde ALOGD("In wifi start Hal"); 1717f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde wifi_handle halHandle = getWifiHandle(env, obj); 1727ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde if (halHandle == NULL) { 1737ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde wifi_error res = wifi_initialize(&halHandle); 1747f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde if (res == WIFI_SUCCESS) { 1757f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde setLongField(env, obj, WifiHandleVarName, (jlong)halHandle); 1767f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } 1777f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde env->GetJavaVM(&mVM); 1787f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde mObj = env->NewGlobalRef(obj); 1797f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde ALOGD("halHandle = %p, mVM = %p, mObj = %p", halHandle, mVM, mObj); 1807ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde return res == WIFI_SUCCESS; 1817f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } else { 1827f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return true; 1837ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde } 1847ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde} 1857ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde 1867ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapndevoid android_net_wifi_hal_cleaned_up_handler(wifi_handle handle) { 1877ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde ALOGD("In wifi cleaned up handler"); 1887f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 1897f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde JNIEnv * env = getEnv(); 1907f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde setLongField(env, mObj, WifiHandleVarName, 0); 1917f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde env->DeleteGlobalRef(mObj); 1927f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde mObj = NULL; 1937f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde mVM = NULL; 1947ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde} 1957ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde 1967f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic void android_net_wifi_stopHal(JNIEnv* env, jobject obj) { 1977ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde ALOGD("In wifi stop Hal"); 1987f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde wifi_handle halHandle = getWifiHandle(env, obj); 1997ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde wifi_cleanup(halHandle, android_net_wifi_hal_cleaned_up_handler); 2007ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde} 2017ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde 2027f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic void android_net_wifi_waitForHalEvents(JNIEnv* env, jobject obj) { 2037f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 2047f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde ALOGD("waitForHalEvents called, vm = %p, obj = %p, env = %p", mVM, mObj, env); 2057f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 2067f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde wifi_handle halHandle = getWifiHandle(env, obj); 2077f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde ALOGD("halHandle = %p", halHandle); 2087ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde wifi_event_loop(halHandle); 2097ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde} 2107ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde 2117f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int android_net_wifi_getInterfaces(JNIEnv *env, jobject obj) { 2127f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde int n = 0; 2137f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde wifi_handle halHandle = getWifiHandle(env, obj); 2147f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde wifi_interface_handle *ifaceHandles = NULL; 2157f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde int result = wifi_get_ifaces(halHandle, &n, &ifaceHandles); 2167f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde if (result < 0) { 2177f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return result; 2187f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } 2197f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 2207f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde jlongArray array = (env)->NewLongArray(n); 2217f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde if (array == NULL) { 2227f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde THROW(env, "Error in accessing array"); 2237f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return 0; 2247f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } 2257f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 2267f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde jlong elems[8]; 2277f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde if (n > 8) { 2287f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde THROW(env, "Too many interfaces"); 2297f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return 0; 2307f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } 2317f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 2327f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde for (int i = 0; i < n; i++) { 2337f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde elems[i] = reinterpret_cast<jlong>(ifaceHandles[i]); 2347f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } 2357f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 2367f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde env->SetLongArrayRegion(array, 0, n, elems); 2377f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 2387f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde setLongArrayField(env, obj, WifiIfaceHandleVarName, array); 2397f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return (result < 0) ? result : n; 2407f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde} 2417f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 2427f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic jstring android_net_wifi_getInterfaceName(JNIEnv *env, jobject obj, jint i) { 2437f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde char buf[EVENT_BUF_SIZE]; 2447f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 2457f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde jlong value = getLongArrayField(env, obj, WifiIfaceHandleVarName, i); 2467f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde wifi_interface_handle handle = (wifi_interface_handle) value; 2477f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde int result = ::wifi_get_iface_name(handle, buf, sizeof(buf)); 2487f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde if (result < 0) { 2497f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return NULL; 2507f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } else { 2517f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return env->NewStringUTF(buf); 2527f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } 2537f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde} 2547f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 255766cb4b1fa3b93c146952eacbf6756f67f172ec1Vinit Deshapndestatic void onScanResultsAvailable(wifi_request_id id, unsigned num_results) { 256766cb4b1fa3b93c146952eacbf6756f67f172ec1Vinit Deshapnde 2577f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde JNIEnv *env = NULL; 2587f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde mVM->AttachCurrentThread(&env, NULL); 2597f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 260766cb4b1fa3b93c146952eacbf6756f67f172ec1Vinit Deshapnde ALOGD("onScanResultsAvailable called, vm = %p, obj = %p, env = %p", mVM, mObj, env); 261766cb4b1fa3b93c146952eacbf6756f67f172ec1Vinit Deshapnde 262e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde reportEvent(env, mObj, "onScanResultsAvailable", "(I)V", id); 263e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 264e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 265e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic jboolean android_net_wifi_startScan( 266e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde JNIEnv *env, jobject obj, jint iface, jint id, jobject settings) { 267e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 268e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_interface_handle handle = getIfaceHandle(env, obj, iface); 269e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("starting scan on interface[%d] = %p", iface, handle); 270e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 271e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_scan_cmd_params params; 272e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde memset(¶ms, 0, sizeof(params)); 273e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 274e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.base_period = getIntField(env, settings, "base_period_ms"); 275e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.max_ap_per_scan = getIntField(env, settings, "max_ap_per_scan"); 276e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.report_threshold = getIntField(env, settings, "report_threshold"); 277e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 278e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Initialized common fields %d, %d, %d", params.base_period, 279e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.max_ap_per_scan, params.report_threshold); 280e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 281e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde const char *bucket_array_type = "[Lcom/android/server/wifi/WifiNative$BucketSettings;"; 282e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde const char *channel_array_type = "[Lcom/android/server/wifi/WifiNative$ChannelSettings;"; 283e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 284e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobjectArray buckets = (jobjectArray)getObjectField(env, settings, "buckets", bucket_array_type); 285e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.num_buckets = getIntField(env, settings, "num_buckets"); 286e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 287e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Initialized num_buckets to %d", params.num_buckets); 288e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 289e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde for (int i = 0; i < params.num_buckets; i++) { 290e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobject bucket = getObjectArrayField(env, settings, "buckets", bucket_array_type, i); 291e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 292e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.buckets[i].bucket = getIntField(env, bucket, "bucket"); 293e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.buckets[i].band = (wifi_band) getIntField(env, bucket, "band"); 294e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.buckets[i].period = getIntField(env, bucket, "period_ms"); 295e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 296e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Initialized common bucket fields %d:%d:%d", params.buckets[i].bucket, 297e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.buckets[i].band, params.buckets[i].period); 298e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 299e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde int report_events = getIntField(env, bucket, "report_events"); 300e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.buckets[i].report_events = report_events; 301e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 302e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Initialized report events to %d", params.buckets[i].report_events); 303e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 304e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobjectArray channels = (jobjectArray)getObjectField( 305e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde env, bucket, "channels", channel_array_type); 306e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 307e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.buckets[i].num_channels = getIntField(env, bucket, "num_channels"); 308e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Initialized num_channels to %d", params.buckets[i].num_channels); 309e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 310e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde for (int j = 0; j < params.buckets[i].num_channels; j++) { 311e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobject channel = getObjectArrayField(env, bucket, "channels", channel_array_type, j); 312e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 313e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.buckets[i].channels[j].channel = getIntField(env, channel, "frequency"); 314e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.buckets[i].channels[j].dwellTimeMs = getIntField(env, channel, "dwell_time_ms"); 315e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 316e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde bool passive = getBoolField(env, channel, "passive"); 317e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.buckets[i].channels[j].passive = (passive ? 1 : 0); 318e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 319e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Initialized channel %d", params.buckets[i].channels[j].channel); 320e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 321e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 322e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 323e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Initialized all fields"); 324e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 325e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_scan_result_handler handler; 326e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde memset(&handler, 0, sizeof(handler)); 327e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde handler.on_scan_results_available = &onScanResultsAvailable; 328e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 329e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return wifi_start_gscan(id, handle, params, handler) == WIFI_SUCCESS; 330e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 331e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 332e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic jboolean android_net_wifi_stopScan(JNIEnv *env, jobject obj, jint iface, jint id) { 333e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_interface_handle handle = getIfaceHandle(env, obj, iface); 334e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("stopping scan on interface[%d] = %p", iface, handle); 335e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 336e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return wifi_stop_gscan(id, handle) == WIFI_SUCCESS; 337e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 338e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 339e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic jobject android_net_wifi_getScanResults( 340e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde JNIEnv *env, jobject obj, jint iface, jboolean flush) { 341e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 342e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_scan_result results[256]; 343e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde int num_results = 256; 344e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 345e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_interface_handle handle = getIfaceHandle(env, obj, iface); 346e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("getting scan results on interface[%d] = %p", iface, handle); 347e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 348e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde int result = wifi_get_cached_gscan_results(handle, 1, results, &num_results); 349e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (result == WIFI_SUCCESS) { 350e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jclass clsScanResult = (env)->FindClass("android/net/wifi/ScanResult"); 351e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (clsScanResult == NULL) { 352e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error in accessing class"); 353e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return NULL; 354e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 355e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 356e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobjectArray scanResults = env->NewObjectArray(num_results, clsScanResult, NULL); 357e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (scanResults == NULL) { 358e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error in allocating array"); 359e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return NULL; 360e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 361e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 362e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde for (int i = 0; i < num_results; i++) { 363e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 364e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobject scanResult = createObject(env, "android/net/wifi/ScanResult"); 365e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (scanResult == NULL) { 366e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error in creating scan result"); 367e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return NULL; 368e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 369e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 370e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setStringField(env, scanResult, "SSID", results[i].ssid); 3717f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 372e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde char bssid[32]; 373e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", results[i].bssid[0], 374e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde results[i].bssid[1], results[i].bssid[2], results[i].bssid[3], 375e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde results[i].bssid[4], results[i].bssid[5]); 376e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 377e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setStringField(env, scanResult, "BSSID", bssid); 378e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 379e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, scanResult, "level", results[i].rssi); 380e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, scanResult, "frequency", results[i].channel); 381e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setLongField(env, scanResult, "timestamp", results[i].ts); 382e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 383e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde env->SetObjectArrayElement(scanResults, i, scanResult); 384e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde env->DeleteLocalRef(scanResult); 385e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 386e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 387e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return scanResults; 388e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } else { 389e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return NULL; 390e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 391e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 392e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 393e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 394e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic jboolean android_net_wifi_getScanCapabilities( 395e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde JNIEnv *env, jobject obj, jint iface, jobject capabilities) { 396e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 397e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_interface_handle handle = getIfaceHandle(env, obj, iface); 398e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("getting scan capabilities on interface[%d] = %p", iface, handle); 399e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 400e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_gscan_capabilities c; 401e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde memset(&c, 0, sizeof(c)); 402e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde int result = wifi_get_gscan_capabilities(handle, &c); 403e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (result != WIFI_SUCCESS) { 404e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("failed to get capabilities : %d", result); 405e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return JNI_FALSE; 406e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 407e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 408e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, capabilities, "max_scan_cache_size", c.max_scan_cache_size); 409e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, capabilities, "max_scan_buckets", c.max_scan_buckets); 410e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, capabilities, "max_ap_cache_per_scan", c.max_ap_cache_per_scan); 411e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, capabilities, "max_rssi_sample_size", c.max_rssi_sample_size); 412e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, capabilities, "max_scan_reporting_threshold", c.max_scan_reporting_threshold); 413e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, capabilities, "max_hotlist_aps", c.max_hotlist_aps); 414e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, capabilities, "max_significant_wifi_change_aps", 415e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde c.max_significant_wifi_change_aps); 416e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 417e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return JNI_TRUE; 418e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 419e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 420e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 421e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic byte parseHexChar(char ch) { 422e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (isdigit(ch)) 423e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return ch - '0'; 424e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde else if ('A' <= ch && ch <= 'F') 425e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return ch - 'A' + 10; 426e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde else if ('a' <= ch && ch <= 'f') 427e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return ch - 'a' + 10; 428e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde else { 429e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("invalid character in bssid %c", ch); 430e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return 0; 431e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 432e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 433e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 434e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic byte parseHexByte(const char * &str) { 435e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde byte b = parseHexChar(str[0]); 436e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (str[1] == ':' || str[1] == '\0') { 437e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde str += 2; 438e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return b; 439e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } else { 440e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde b = b << 4 | parseHexChar(str[1]); 441e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde str += 3; 442e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return b; 443e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 444e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 445e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 446e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic void parseMacAddress(const char *str, mac_addr addr) { 447e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde addr[0] = parseHexByte(str); 448e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde addr[1] = parseHexByte(str); 449e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde addr[2] = parseHexByte(str); 450e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde addr[3] = parseHexByte(str); 451e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde addr[4] = parseHexByte(str); 452e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde addr[5] = parseHexByte(str); 453e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 454e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 455e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic void onHotlistApFound(wifi_request_id id, 456e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde unsigned num_results, wifi_scan_result *results) { 457e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 458e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde JNIEnv *env = NULL; 459e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde mVM->AttachCurrentThread(&env, NULL); 460e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 461e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("onHotlistApFound called, vm = %p, obj = %p, env = %p, num_results = %d", 462e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde mVM, mObj, env, num_results); 463e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 464e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jclass clsScanResult = (env)->FindClass("android/net/wifi/ScanResult"); 4657f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde if (clsScanResult == NULL) { 4667f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde ALOGE("Error in accessing class"); 4677f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return; 4687f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } 4697f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 4707f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde jobjectArray scanResults = env->NewObjectArray(num_results, clsScanResult, NULL); 4717f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde if (scanResults == NULL) { 4727f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde ALOGE("Error in allocating array"); 4737f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return; 4747f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } 4757f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 4767f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde for (unsigned i = 0; i < num_results; i++) { 4777f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 478e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobject scanResult = createObject(env, "android/net/wifi/ScanResult"); 4797f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde if (scanResult == NULL) { 4807f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde ALOGE("Error in creating scan result"); 4817f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde return; 4827f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } 4837f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 4847f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde setStringField(env, scanResult, "SSID", results[i].ssid); 4857f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 4867f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde char bssid[32]; 487e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", results[i].bssid[0], results[i].bssid[1], 4887f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde results[i].bssid[2], results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]); 4897f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 4907f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde setStringField(env, scanResult, "BSSID", bssid); 4917f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 4927f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde setIntField(env, scanResult, "level", results[i].rssi); 493e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, scanResult, "frequency", results[i].channel); 4947f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde setLongField(env, scanResult, "timestamp", results[i].ts); 495e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 496e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde env->SetObjectArrayElement(scanResults, i, scanResult); 497e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 498e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Found AP %32s %s", results[i].ssid, bssid); 499e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 500e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 501e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde reportEvent(env, mObj, "onHotlistApFound", "(I[Landroid/net/wifi/ScanResult;)V", 502e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde id, scanResults); 503e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 504e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 505e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic jboolean android_net_wifi_setHotlist( 506e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde JNIEnv *env, jobject obj, jint iface, jint id, jobject ap) { 507e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 508e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_interface_handle handle = getIfaceHandle(env, obj, iface); 509e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("setting hotlist on interface[%d] = %p", iface, handle); 510e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 511e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_bssid_hotlist_params params; 512e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde memset(¶ms, 0, sizeof(params)); 513e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 514e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobjectArray array = (jobjectArray) getObjectField(env, ap, 515e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde "hotspotInfos", "[Landroid/net/wifi/WifiScanner$HotspotInfo;"); 516e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.num = env->GetArrayLength(array); 517e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 518e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (params.num == 0) { 519e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error in accesing array"); 520e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return false; 521e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 522e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 523e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde for (int i = 0; i < params.num; i++) { 524e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobject objAp = env->GetObjectArrayElement(array, i); 525e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 526e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jstring macAddrString = (jstring) getObjectField( 527e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde env, objAp, "bssid", "Ljava/lang/String;"); 528e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (macAddrString == NULL) { 529e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error getting bssid field"); 530e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return false; 531e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 532e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 533e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde const char *bssid = env->GetStringUTFChars(macAddrString, NULL); 534e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (bssid == NULL) { 535e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error getting bssid"); 536e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return false; 537e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 538e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde parseMacAddress(bssid, params.bssids[i].bssid); 539e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 540e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde mac_addr addr; 541e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde memcpy(addr, params.bssids[i].bssid, sizeof(mac_addr)); 542e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 543e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde char bssidOut[32]; 544e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1], 545e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde addr[2], addr[3], addr[4], addr[5]); 546e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 547e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Added bssid %s", bssidOut); 548e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 549e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.bssids[i].low = getIntField(env, objAp, "low"); 550e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.bssids[i].high = getIntField(env, objAp, "high"); 551e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 552e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 553e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_hotlist_ap_found_handler handler; 554e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde memset(&handler, 0, sizeof(handler)); 555e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 556e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde handler.on_hotlist_ap_found = &onHotlistApFound; 557e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return wifi_set_bssid_hotlist(id, handle, params, handler) == WIFI_SUCCESS; 558e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 559e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 560e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic jboolean android_net_wifi_resetHotlist( 561e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde JNIEnv *env, jobject obj, jint iface, jint id) { 562e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 563e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_interface_handle handle = getIfaceHandle(env, obj, iface); 564e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("resetting hotlist on interface[%d] = %p", iface, handle); 565e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 566e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return wifi_reset_bssid_hotlist(id, handle) == WIFI_SUCCESS; 567e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde} 568e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 569e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndevoid onSignificantWifiChange(wifi_request_id id, unsigned num_results, wifi_scan_result *results) { 570e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde JNIEnv *env = NULL; 571e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde mVM->AttachCurrentThread(&env, NULL); 572e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 573e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("onSignificantWifiChange called, vm = %p, obj = %p, env = %p", mVM, mObj, env); 574e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 575e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jclass clsScanResult = (env)->FindClass("android/net/wifi/ScanResult"); 576e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (clsScanResult == NULL) { 577e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error in accessing class"); 578e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return; 579e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 580e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 581e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobjectArray scanResults = env->NewObjectArray(num_results, clsScanResult, NULL); 582e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (scanResults == NULL) { 583e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error in allocating array"); 584e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return; 585e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 586e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 587e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde for (unsigned i = 0; i < num_results; i++) { 588e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 589e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobject scanResult = createObject(env, "android/net/wifi/ScanResult"); 590e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (scanResult == NULL) { 591e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error in creating scan result"); 592e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return; 593e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 594e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 595e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setStringField(env, scanResult, "SSID", results[i].ssid); 596e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 597e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde char bssid[32]; 598e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", results[i].bssid[0], results[i].bssid[1], 599e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde results[i].bssid[2], results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]); 600e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 601e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setStringField(env, scanResult, "BSSID", bssid); 602e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 603e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setIntField(env, scanResult, "level", results[i].rssi); 6047f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde setIntField(env, scanResult, "frequency", results[i].channel); 605e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde setLongField(env, scanResult, "timestamp", results[i].ts); 6067f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 6077f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde env->SetObjectArrayElement(scanResults, i, scanResult); 6087f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde } 6097f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 610e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde reportEvent(env, mObj, "onSignificantWifiChange", "(I[Landroid/net/wifi/ScanResult;)V", 611e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde id, scanResults); 612e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 6137f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde} 6147f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 615e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic jboolean android_net_wifi_trackSignificantWifiChange( 616e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde JNIEnv *env, jobject obj, jint iface, jint id, jobject settings) { 6177f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 6187f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde wifi_interface_handle handle = getIfaceHandle(env, obj, iface); 619e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("tracking significant wifi change on interface[%d] = %p", iface, handle); 6207f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 621e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_significant_change_params params; 6227f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde memset(¶ms, 0, sizeof(params)); 6237f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 624e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.rssi_sample_size = getIntField(env, settings, "rssiSampleSize"); 625e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.lost_ap_sample_size = getIntField(env, settings, "lostApSampleSize"); 626e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.min_breaching = getIntField(env, settings, "minApsBreachingThreshold"); 627e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 628e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde const char *hotspot_info_array_type = "[Landroid/net/wifi/WifiScanner$HotspotInfo;"; 629e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobjectArray hotspots = (jobjectArray)getObjectField( 630e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde env, settings, "hotspotInfos", hotspot_info_array_type); 631e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.num = env->GetArrayLength(hotspots); 632e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 633e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (params.num == 0) { 634e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error in accesing array"); 635e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return false; 636e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 637e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 638e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Initialized common fields %d, %d, %d, %d", params.rssi_sample_size, 639e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.lost_ap_sample_size, params.min_breaching, params.num); 640e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 641e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde for (int i = 0; i < params.num; i++) { 642e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jobject objAp = env->GetObjectArrayElement(hotspots, i); 643e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 644e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde jstring macAddrString = (jstring) getObjectField( 645e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde env, objAp, "bssid", "Ljava/lang/String;"); 646e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (macAddrString == NULL) { 647e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error getting bssid field"); 648e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return false; 649e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 650e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 651e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde const char *bssid = env->GetStringUTFChars(macAddrString, NULL); 652e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde if (bssid == NULL) { 653e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGE("Error getting bssid"); 654e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return false; 655e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 656e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 657e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde mac_addr addr; 658e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde parseMacAddress(bssid, addr); 659e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde memcpy(params.bssids[i].bssid, addr, sizeof(mac_addr)); 660e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 661e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde char bssidOut[32]; 662e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1], 663e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde addr[2], addr[3], addr[4], addr[5]); 664e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 665e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.bssids[i].low = getIntField(env, objAp, "low"); 666e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde params.bssids[i].high = getIntField(env, objAp, "high"); 667e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 668e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Added bssid %s, [%04d, %04d]", bssidOut, params.bssids[i].low, params.bssids[i].high); 669e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde } 670e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 671e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("Added %d bssids", params.num); 672e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 673e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde wifi_significant_change_handler handler; 6747f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde memset(&handler, 0, sizeof(handler)); 6757f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 676e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde handler.on_significant_change = &onSignificantWifiChange; 677e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return wifi_set_significant_change_handler(id, handle, params, handler) == WIFI_SUCCESS; 6787f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde} 6797f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 680e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndestatic jboolean android_net_wifi_untrackSignificantWifiChange( 681e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde JNIEnv *env, jobject obj, jint iface, jint id) { 682e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 6837f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde wifi_interface_handle handle = getIfaceHandle(env, obj, iface); 684e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde ALOGD("resetting significant wifi change on interface[%d] = %p", iface, handle); 6857f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde 686e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde return wifi_reset_significant_change_handler(id, handle) == WIFI_SUCCESS; 6877f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde} 6887ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde 689e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 690155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande// ---------------------------------------------------------------------------- 691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/* 693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * JNI registration. 694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 695155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandestatic JNINativeMethod gWifiMethods[] = { 696155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* name, signature, funcPtr */ 697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver }, 699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded }, 700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver }, 701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant }, 702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant }, 703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant }, 704155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "closeSupplicantConnectionNative", "()V", 705155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande (void *)android_net_wifi_closeSupplicantConnection }, 706155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForEvent }, 707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "doBooleanCommandNative", "(Ljava/lang/String;)Z", (void*)android_net_wifi_doBooleanCommand }, 708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "doIntCommandNative", "(Ljava/lang/String;)I", (void*)android_net_wifi_doIntCommand }, 709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande { "doStringCommandNative", "(Ljava/lang/String;)Ljava/lang/String;", 710155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande (void*) android_net_wifi_doStringCommand }, 7117ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde { "startHalNative", "()Z", (void*) android_net_wifi_startHal }, 7127ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde { "stopHalNative", "()V", (void*) android_net_wifi_stopHal }, 7137ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde { "waitForHalEventNative", "()V", (void*) android_net_wifi_waitForHalEvents }, 7147f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde { "getInterfacesNative", "()I", (void*) android_net_wifi_getInterfaces}, 7157f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde { "getInterfaceNameNative", "(I)Ljava/lang/String;", (void*) android_net_wifi_getInterfaceName}, 716e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde { "getScanCapabilitiesNative", "(ILcom/android/server/wifi/WifiNative$ScanCapabilities;)Z", 717e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde (void *) android_net_wifi_getScanCapabilities}, 718e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde { "startScanNative", "(IILcom/android/server/wifi/WifiNative$ScanSettings;)Z", 719e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde (void*) android_net_wifi_startScan}, 720e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde { "stopScanNative", "(II)Z", (void*) android_net_wifi_stopScan}, 721e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde { "getScanResultsNative", "(IZ)[Landroid/net/wifi/ScanResult;", 722e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde (void *) android_net_wifi_getScanResults}, 723e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 724e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde { "setHotlistNative", "(IILandroid/net/wifi/WifiScanner$HotlistSettings;)Z", 725e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde (void*) android_net_wifi_setHotlist}, 726e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde { "resetHotlistNative", "(II)Z", (void*) android_net_wifi_resetHotlist}, 727e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 728e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde 729e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde { "trackSignificantWifiChangeNative", "(IILandroid/net/wifi/WifiScanner$WifiChangeSettings;)Z", 730e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde (void*) android_net_wifi_trackSignificantWifiChange}, 731e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde { "untrackSignificantWifiChangeNative", "(II)Z", 732e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde (void*) android_net_wifi_untrackSignificantWifiChange} 733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}; 734155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeint register_android_net_wifi_WifiNative(JNIEnv* env) { 736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return AndroidRuntime::registerNativeMethods(env, 737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods)); 738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/* User to register native functions */ 742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeextern "C" 743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandejint Java_com_android_server_wifi_WifiNative_registerNatives(JNIEnv* env, jclass clazz) { 744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return AndroidRuntime::registerNativeMethods(env, 745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods)); 746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}; // namespace android 749