blob: d100060fbdd451cd3db7e3d6f01e74695265680b [file] [log] [blame]
Vinit Deshpande155b9d02014-01-08 23:46:46 +00001/*
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 <ScopedUtfChars.h>
21#include <utils/misc.h>
22#include <android_runtime/AndroidRuntime.h>
23#include <utils/Log.h>
24#include <utils/String16.h>
Vinit Deshapndee4e37502014-05-05 11:32:21 -070025#include <ctype.h>
xinhebe3b27a2015-01-30 17:56:24 -080026#include <sys/socket.h>
27#include <linux/if.h>
Vinit Deshpande155b9d02014-01-08 23:46:46 +000028#include "wifi.h"
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -080029#include "wifi_hal.h"
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -070030#include "jni_helper.h"
xinhe12cf3882015-03-12 18:38:54 -070031#include "rtt.h"
xinhe62819992015-04-03 11:13:59 -070032#include "wifi_hal_stub.h"
Vinit Deshpande155b9d02014-01-08 23:46:46 +000033
34#define REPLY_BUF_SIZE 4096 // wpa_supplicant's maximum size.
35#define EVENT_BUF_SIZE 2048
36
37namespace android {
38
39static jint DBG = false;
40
xinhe62819992015-04-03 11:13:59 -070041//Please put all HAL function call here and call from the function table instead of directly call
42static wifi_hal_fn hal_fn;
43int init_wifi_hal_func_table(wifi_hal_fn *hal_fn) {
44 if (hal_fn == NULL) {
45 return -1;
46 }
47
48 hal_fn->wifi_initialize = wifi_initialize_stub;
49 hal_fn->wifi_cleanup = wifi_cleanup_stub;
50 hal_fn->wifi_event_loop = wifi_event_loop_stub;
51 hal_fn->wifi_get_error_info = wifi_get_error_info_stub;
52 hal_fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set_stub;
53 hal_fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix_stub;
54 hal_fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui_stub;
55 hal_fn->wifi_get_supported_channels = wifi_get_supported_channels_stub;
56 hal_fn->wifi_is_epr_supported = wifi_is_epr_supported_stub;
57 hal_fn->wifi_get_ifaces = wifi_get_ifaces_stub;
58 hal_fn->wifi_get_iface_name = wifi_get_iface_name_stub;
59 hal_fn->wifi_reset_iface_event_handler = wifi_reset_iface_event_handler_stub;
60 hal_fn->wifi_start_gscan = wifi_start_gscan_stub;
61 hal_fn->wifi_stop_gscan = wifi_stop_gscan_stub;
62 hal_fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results_stub;
63 hal_fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist_stub;
64 hal_fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist_stub;
65 hal_fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler_stub;
66 hal_fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler_stub;
67 hal_fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities_stub;
68 hal_fn->wifi_set_link_stats = wifi_set_link_stats_stub;
69 hal_fn->wifi_get_link_stats = wifi_get_link_stats_stub;
70 hal_fn->wifi_clear_link_stats = wifi_clear_link_stats_stub;
71 hal_fn->wifi_get_valid_channels = wifi_get_valid_channels_stub;
72 hal_fn->wifi_rtt_range_request = wifi_rtt_range_request_stub;
73 hal_fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel_stub;
74 hal_fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities_stub;
xinhe62819992015-04-03 11:13:59 -070075 hal_fn->wifi_start_logging = wifi_start_logging_stub;
76 hal_fn->wifi_set_epno_list = wifi_set_epno_list_stub;
77 hal_fn->wifi_set_country_code = wifi_set_country_code_stub;
xinhed57f6302015-04-15 13:23:43 -070078 hal_fn->wifi_enable_tdls = wifi_enable_tdls_stub;
79 hal_fn->wifi_disable_tdls = wifi_disable_tdls_stub;
80 hal_fn->wifi_get_tdls_status = wifi_get_tdls_status_stub;
81 hal_fn->wifi_get_tdls_capabilities = wifi_get_tdls_capabilities_stub;
xinhe21602b32015-04-24 09:32:13 -070082 hal_fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump_stub;
83 hal_fn->wifi_set_log_handler = wifi_set_log_handler_stub;
84 hal_fn->wifi_set_alert_handler = wifi_set_alert_handler_stub;
85 hal_fn->wifi_get_firmware_version = wifi_get_firmware_version_stub;
86 hal_fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status_stub;
87 hal_fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set_stub;
88 hal_fn->wifi_get_ring_data = wifi_get_ring_data_stub;
89 hal_fn->wifi_get_driver_version = wifi_get_driver_version_stub;
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -070090 hal_fn->wifi_set_ssid_white_list = wifi_set_ssid_white_list_stub;
91 hal_fn->wifi_set_gscan_roam_params = wifi_set_gscan_roam_params_stub;
92 hal_fn->wifi_set_bssid_preference = wifi_set_bssid_preference_stub;
93 hal_fn->wifi_enable_lazy_roam = wifi_enable_lazy_roam_stub;
94 hal_fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist_stub;
xinhe62819992015-04-03 11:13:59 -070095 return 0;
96}
97
98
Vinit Deshpande155b9d02014-01-08 23:46:46 +000099static bool doCommand(JNIEnv* env, jstring javaCommand,
100 char* reply, size_t reply_len) {
101 ScopedUtfChars command(env, javaCommand);
102 if (command.c_str() == NULL) {
103 return false; // ScopedUtfChars already threw on error.
104 }
105
106 if (DBG) {
107 ALOGD("doCommand: %s", command.c_str());
108 }
109
110 --reply_len; // Ensure we have room to add NUL termination.
111 if (::wifi_command(command.c_str(), reply, &reply_len) != 0) {
112 return false;
113 }
114
115 // Strip off trailing newline.
116 if (reply_len > 0 && reply[reply_len-1] == '\n') {
117 reply[reply_len-1] = '\0';
118 } else {
119 reply[reply_len] = '\0';
120 }
121 return true;
122}
123
124static jint doIntCommand(JNIEnv* env, jstring javaCommand) {
125 char reply[REPLY_BUF_SIZE];
126 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
127 return -1;
128 }
129 return static_cast<jint>(atoi(reply));
130}
131
132static jboolean doBooleanCommand(JNIEnv* env, jstring javaCommand) {
133 char reply[REPLY_BUF_SIZE];
134 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
135 return JNI_FALSE;
136 }
137 return (strcmp(reply, "OK") == 0);
138}
139
140// Send a command to the supplicant, and return the reply as a String.
141static jstring doStringCommand(JNIEnv* env, jstring javaCommand) {
142 char reply[REPLY_BUF_SIZE];
143 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
144 return NULL;
145 }
146 return env->NewStringUTF(reply);
147}
148
149static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject)
150{
151 return (::is_wifi_driver_loaded() == 1);
152}
153
154static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
155{
156 return (::wifi_load_driver() == 0);
157}
158
159static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
160{
161 return (::wifi_unload_driver() == 0);
162}
163
164static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
165{
166 return (::wifi_start_supplicant(p2pSupported) == 0);
167}
168
169static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
170{
171 return (::wifi_stop_supplicant(p2pSupported) == 0);
172}
173
174static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject)
175{
176 return (::wifi_connect_to_supplicant() == 0);
177}
178
179static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject)
180{
181 ::wifi_close_supplicant_connection();
182}
183
184static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject)
185{
186 char buf[EVENT_BUF_SIZE];
187 int nread = ::wifi_wait_for_event(buf, sizeof buf);
188 if (nread > 0) {
189 return env->NewStringUTF(buf);
190 } else {
191 return NULL;
192 }
193}
194
195static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) {
196 return doBooleanCommand(env, javaCommand);
197}
198
199static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) {
200 return doIntCommand(env, javaCommand);
201}
202
203static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) {
204 return doStringCommand(env,javaCommand);
205}
206
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700207/* wifi_hal <==> WifiNative bridge */
208
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700209static jclass mCls; /* saved WifiNative object */
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700210static JavaVM *mVM; /* saved JVM pointer */
211
vandwalleaabe7a92014-05-09 18:11:02 -0700212static const char *WifiHandleVarName = "sWifiHalHandle";
213static const char *WifiIfaceHandleVarName = "sWifiIfaceHandles";
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700214static jmethodID OnScanResultsMethodID;
215
216static JNIEnv *getEnv() {
217 JNIEnv *env = NULL;
218 mVM->AttachCurrentThread(&env, NULL);
219 return env;
220}
221
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700222static wifi_handle getWifiHandle(JNIEnv *env, jclass cls) {
223 return (wifi_handle) getStaticLongField(env, cls, WifiHandleVarName);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700224}
225
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700226static wifi_interface_handle getIfaceHandle(JNIEnv *env, jclass cls, jint index) {
227 return (wifi_interface_handle) getStaticLongArrayField(env, cls, WifiIfaceHandleVarName, index);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700228}
229
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700230static jobject createScanResult(JNIEnv *env, wifi_scan_result *result) {
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700231
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700232 // ALOGD("creating scan result");
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700233
234 jobject scanResult = createObject(env, "android/net/wifi/ScanResult");
235 if (scanResult == NULL) {
236 ALOGE("Error in creating scan result");
237 return NULL;
238 }
239
Vinit Deshpande31ecd262015-04-23 15:06:46 -0700240 ALOGV("setting SSID to %s", result->ssid);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700241 //jstring jssid = env->NewStringUTF(result->ssid);
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700242 setStringField(env, scanResult, "SSID", result->ssid);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700243
244 char bssid[32];
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700245 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->bssid[0], result->bssid[1],
246 result->bssid[2], result->bssid[3], result->bssid[4], result->bssid[5]);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700247 //jstring jbssid = env->NewStringUTF(bssid);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700248
249 setStringField(env, scanResult, "BSSID", bssid);
250
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700251 setIntField(env, scanResult, "level", result->rssi);
252 setIntField(env, scanResult, "frequency", result->channel);
253 setLongField(env, scanResult, "timestamp", result->ts);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700254
255 return scanResult;
256}
257
xinhebe3b27a2015-01-30 17:56:24 -0800258int set_iface_flags(const char *ifname, int dev_up) {
259 struct ifreq ifr;
260 int ret;
xinhebe3b27a2015-01-30 17:56:24 -0800261 int sock = socket(PF_INET, SOCK_DGRAM, 0);
262 if (sock < 0) {
263 ALOGD("Bad socket: %d\n", sock);
264 return -errno;
265 }
266
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700267 //ALOGD("setting interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
xinhebe3b27a2015-01-30 17:56:24 -0800268
269 memset(&ifr, 0, sizeof(ifr));
270 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
271
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700272 //ALOGD("reading old value\n");
xinhebe3b27a2015-01-30 17:56:24 -0800273
274 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
275 ret = errno ? -errno : -999;
Vinit Deshpande70be7f12015-04-10 18:10:29 -0700276 ALOGE("Could not read interface %s flags: %d\n", ifname, errno);
xinhebe3b27a2015-01-30 17:56:24 -0800277 close(sock);
278 return ret;
279 } else {
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700280 //ALOGD("writing new value\n");
xinhebe3b27a2015-01-30 17:56:24 -0800281 }
282
283 if (dev_up) {
284 if (ifr.ifr_flags & IFF_UP) {
Vinit Deshpande70be7f12015-04-10 18:10:29 -0700285 // ALOGD("interface %s is already up\n", ifname);
xinhebe3b27a2015-01-30 17:56:24 -0800286 close(sock);
287 return 0;
288 }
289 ifr.ifr_flags |= IFF_UP;
290 } else {
291 if (!(ifr.ifr_flags & IFF_UP)) {
Vinit Deshpande70be7f12015-04-10 18:10:29 -0700292 // ALOGD("interface %s is already down\n", ifname);
xinhebe3b27a2015-01-30 17:56:24 -0800293 close(sock);
294 return 0;
295 }
296 ifr.ifr_flags &= ~IFF_UP;
297 }
298
299 if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
Vinit Deshpande70be7f12015-04-10 18:10:29 -0700300 ALOGE("Could not set interface %s flags \n", ifname);
xinhebe3b27a2015-01-30 17:56:24 -0800301 close(sock);
302 return ret;
303 } else {
304 ALOGD("set interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
305 }
306 close(sock);
307 return 0;
308}
309
xinheb830d762015-02-11 17:14:17 -0800310static jboolean android_net_wifi_toggle_interface(JNIEnv* env, jclass cls, int toggle) {
311 return(set_iface_flags("wlan0", toggle) == 0);
312}
313
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700314static jboolean android_net_wifi_startHal(JNIEnv* env, jclass cls) {
315 wifi_handle halHandle = getWifiHandle(env, cls);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800316 if (halHandle == NULL) {
xinhe62819992015-04-03 11:13:59 -0700317
318 if(init_wifi_hal_func_table(&hal_fn) != 0 ) {
319 ALOGD("Can not initialize the basic function pointer table");
320 return false;
321 }
322
323 wifi_error res = init_wifi_vendor_hal_func_table(&hal_fn);
324 if (res != WIFI_SUCCESS) {
325 ALOGD("Can not initialize the vendor function pointer table");
326 return false;
327 }
328
xinhebe3b27a2015-01-30 17:56:24 -0800329 int ret = set_iface_flags("wlan0", 1);
330 if(ret != 0) {
331 return false;
332 }
xinhe62819992015-04-03 11:13:59 -0700333
334 res = hal_fn.wifi_initialize(&halHandle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700335 if (res == WIFI_SUCCESS) {
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700336 setStaticLongField(env, cls, WifiHandleVarName, (jlong)halHandle);
vandwalleaabe7a92014-05-09 18:11:02 -0700337 ALOGD("Did set static halHandle = %p", halHandle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700338 }
339 env->GetJavaVM(&mVM);
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700340 mCls = (jclass) env->NewGlobalRef(cls);
341 ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800342 return res == WIFI_SUCCESS;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700343 } else {
xinhe82628222015-02-04 16:39:45 -0800344 return (set_iface_flags("wlan0", 1) == 0);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800345 }
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800346}
347
348void android_net_wifi_hal_cleaned_up_handler(wifi_handle handle) {
349 ALOGD("In wifi cleaned up handler");
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700350
351 JNIEnv * env = getEnv();
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700352 setStaticLongField(env, mCls, WifiHandleVarName, 0);
353 env->DeleteGlobalRef(mCls);
354 mCls = NULL;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700355 mVM = NULL;
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800356}
357
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700358static void android_net_wifi_stopHal(JNIEnv* env, jclass cls) {
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800359 ALOGD("In wifi stop Hal");
xinheb830d762015-02-11 17:14:17 -0800360
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700361 wifi_handle halHandle = getWifiHandle(env, cls);
Vinit Deshpandef49a59b2015-05-27 11:24:47 -0700362 if (halHandle == NULL)
363 return;
364
365 ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls);
xinhe62819992015-04-03 11:13:59 -0700366 hal_fn.wifi_cleanup(halHandle, android_net_wifi_hal_cleaned_up_handler);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800367}
368
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700369static void android_net_wifi_waitForHalEvents(JNIEnv* env, jclass cls) {
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700370
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700371 ALOGD("waitForHalEvents called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700372
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700373 wifi_handle halHandle = getWifiHandle(env, cls);
xinhe62819992015-04-03 11:13:59 -0700374 hal_fn.wifi_event_loop(halHandle);
Vinit Deshpandef49a59b2015-05-27 11:24:47 -0700375 set_iface_flags("wlan0", 0);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800376}
377
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700378static int android_net_wifi_getInterfaces(JNIEnv *env, jclass cls) {
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700379 int n = 0;
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700380 wifi_handle halHandle = getWifiHandle(env, cls);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700381 wifi_interface_handle *ifaceHandles = NULL;
xinhe62819992015-04-03 11:13:59 -0700382 int result = hal_fn.wifi_get_ifaces(halHandle, &n, &ifaceHandles);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700383 if (result < 0) {
384 return result;
385 }
386
Vinit Deshpande07ce33c2014-08-14 12:04:35 -0700387 if (n < 0) {
388 THROW(env, "android_net_wifi_getInterfaces no interfaces");
vandwalleaabe7a92014-05-09 18:11:02 -0700389 return 0;
390 }
391
392 if (ifaceHandles == NULL) {
393 THROW(env, "android_net_wifi_getInterfaces null interface array");
394 return 0;
395 }
396
Vinit Deshpande07ce33c2014-08-14 12:04:35 -0700397 if (n > 8) {
398 THROW(env, "Too many interfaces");
399 return 0;
400 }
401
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700402 jlongArray array = (env)->NewLongArray(n);
403 if (array == NULL) {
404 THROW(env, "Error in accessing array");
405 return 0;
406 }
407
408 jlong elems[8];
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700409 for (int i = 0; i < n; i++) {
410 elems[i] = reinterpret_cast<jlong>(ifaceHandles[i]);
411 }
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700412 env->SetLongArrayRegion(array, 0, n, elems);
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700413 setStaticLongArrayField(env, cls, WifiIfaceHandleVarName, array);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700414
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700415 return (result < 0) ? result : n;
416}
417
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700418static jstring android_net_wifi_getInterfaceName(JNIEnv *env, jclass cls, jint i) {
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700419 char buf[EVENT_BUF_SIZE];
420
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700421 jlong value = getStaticLongArrayField(env, cls, WifiIfaceHandleVarName, i);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700422 wifi_interface_handle handle = (wifi_interface_handle) value;
xinhe62819992015-04-03 11:13:59 -0700423 int result = hal_fn.wifi_get_iface_name(handle, buf, sizeof(buf));
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700424 if (result < 0) {
425 return NULL;
426 } else {
427 return env->NewStringUTF(buf);
428 }
429}
430
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700431
Vinit Deshapnde766cb4b2014-05-07 18:00:44 -0700432static void onScanResultsAvailable(wifi_request_id id, unsigned num_results) {
433
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700434 JNIEnv *env = NULL;
435 mVM->AttachCurrentThread(&env, NULL);
436
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700437 ALOGD("onScanResultsAvailable called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshapnde766cb4b2014-05-07 18:00:44 -0700438
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700439 reportEvent(env, mCls, "onScanResultsAvailable", "(I)V", id);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700440}
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700441
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700442static void onScanEvent(wifi_scan_event event, unsigned status) {
443 JNIEnv *env = NULL;
444 mVM->AttachCurrentThread(&env, NULL);
445
446 ALOGD("onScanStatus called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
447
Navtej Singh Mann827bc402015-03-18 17:29:31 -0700448 reportEvent(env, mCls, "onScanStatus", "(I)V", event);
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700449}
450
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700451static void onFullScanResult(wifi_request_id id, wifi_scan_result *result) {
452
453 JNIEnv *env = NULL;
454 mVM->AttachCurrentThread(&env, NULL);
455
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700456 ALOGD("onFullScanResult called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700457
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700458 jobject scanResult = createScanResult(env, result);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700459
460 ALOGD("Creating a byte array of length %d", result->ie_length);
461
462 jbyteArray elements = env->NewByteArray(result->ie_length);
463 if (elements == NULL) {
464 ALOGE("Error in allocating array");
465 return;
466 }
467
468 ALOGE("Setting byte array");
469
470 jbyte *bytes = (jbyte *)&(result->ie_data[0]);
471 env->SetByteArrayRegion(elements, 0, result->ie_length, bytes);
472
473 ALOGE("Returning result");
474
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700475 reportEvent(env, mCls, "onFullScanResult", "(ILandroid/net/wifi/ScanResult;[B)V", id,
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700476 scanResult, elements);
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700477
478 env->DeleteLocalRef(scanResult);
479 env->DeleteLocalRef(elements);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700480}
481
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700482static jboolean android_net_wifi_startScan(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700483 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700484
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700485 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700486 // ALOGD("starting scan on interface[%d] = %p", iface, handle);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700487
488 wifi_scan_cmd_params params;
489 memset(&params, 0, sizeof(params));
vandwalleaabe7a92014-05-09 18:11:02 -0700490
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700491 params.base_period = getIntField(env, settings, "base_period_ms");
492 params.max_ap_per_scan = getIntField(env, settings, "max_ap_per_scan");
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700493 params.report_threshold_percent = getIntField(env, settings, "report_threshold_percent");
494 params.report_threshold_num_scans = getIntField(env, settings, "report_threshold_num_scans");
vandwalleaabe7a92014-05-09 18:11:02 -0700495
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700496 ALOGD("Initialized common fields %d, %d, %d, %d", params.base_period, params.max_ap_per_scan,
497 params.report_threshold_percent, params.report_threshold_num_scans);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700498
499 const char *bucket_array_type = "[Lcom/android/server/wifi/WifiNative$BucketSettings;";
500 const char *channel_array_type = "[Lcom/android/server/wifi/WifiNative$ChannelSettings;";
vandwalleaabe7a92014-05-09 18:11:02 -0700501
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700502 jobjectArray buckets = (jobjectArray)getObjectField(env, settings, "buckets", bucket_array_type);
503 params.num_buckets = getIntField(env, settings, "num_buckets");
vandwalleaabe7a92014-05-09 18:11:02 -0700504
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700505 // ALOGD("Initialized num_buckets to %d", params.num_buckets);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700506
507 for (int i = 0; i < params.num_buckets; i++) {
508 jobject bucket = getObjectArrayField(env, settings, "buckets", bucket_array_type, i);
vandwalleaabe7a92014-05-09 18:11:02 -0700509
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700510 params.buckets[i].bucket = getIntField(env, bucket, "bucket");
511 params.buckets[i].band = (wifi_band) getIntField(env, bucket, "band");
512 params.buckets[i].period = getIntField(env, bucket, "period_ms");
vandwalleaabe7a92014-05-09 18:11:02 -0700513
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700514 int report_events = getIntField(env, bucket, "report_events");
515 params.buckets[i].report_events = report_events;
vandwalleaabe7a92014-05-09 18:11:02 -0700516
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700517 ALOGD("bucket[%d] = %d:%d:%d:%d", i, params.buckets[i].bucket,
518 params.buckets[i].band, params.buckets[i].period, report_events);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700519
520 jobjectArray channels = (jobjectArray)getObjectField(
521 env, bucket, "channels", channel_array_type);
vandwalleaabe7a92014-05-09 18:11:02 -0700522
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700523 params.buckets[i].num_channels = getIntField(env, bucket, "num_channels");
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700524 // ALOGD("Initialized num_channels to %d", params.buckets[i].num_channels);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700525
526 for (int j = 0; j < params.buckets[i].num_channels; j++) {
527 jobject channel = getObjectArrayField(env, bucket, "channels", channel_array_type, j);
vandwalleaabe7a92014-05-09 18:11:02 -0700528
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700529 params.buckets[i].channels[j].channel = getIntField(env, channel, "frequency");
530 params.buckets[i].channels[j].dwellTimeMs = getIntField(env, channel, "dwell_time_ms");
vandwalleaabe7a92014-05-09 18:11:02 -0700531
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700532 bool passive = getBoolField(env, channel, "passive");
533 params.buckets[i].channels[j].passive = (passive ? 1 : 0);
534
Vinit Deshpande70be7f12015-04-10 18:10:29 -0700535 // ALOGD("Initialized channel %d", params.buckets[i].channels[j].channel);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700536 }
537 }
538
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700539 // ALOGD("Initialized all fields");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700540
541 wifi_scan_result_handler handler;
542 memset(&handler, 0, sizeof(handler));
543 handler.on_scan_results_available = &onScanResultsAvailable;
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700544 handler.on_full_scan_result = &onFullScanResult;
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700545 handler.on_scan_event = &onScanEvent;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700546
xinhe62819992015-04-03 11:13:59 -0700547 return hal_fn.wifi_start_gscan(id, handle, params, handler) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700548}
549
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700550static jboolean android_net_wifi_stopScan(JNIEnv *env, jclass cls, jint iface, jint id) {
551 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700552 // ALOGD("stopping scan on interface[%d] = %p", iface, handle);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700553
xinhe62819992015-04-03 11:13:59 -0700554 return hal_fn.wifi_stop_gscan(id, handle) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700555}
556
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700557static int compare_scan_result_timestamp(const void *v1, const void *v2) {
558 const wifi_scan_result *result1 = static_cast<const wifi_scan_result *>(v1);
559 const wifi_scan_result *result2 = static_cast<const wifi_scan_result *>(v2);
560 return result1->ts - result2->ts;
561}
562
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700563static jobject android_net_wifi_getScanResults(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700564 JNIEnv *env, jclass cls, jint iface, jboolean flush) {
Navtej Singh Mannc8b61ce2015-04-16 18:54:10 -0700565
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700566 wifi_cached_scan_results scan_data[64];
567 int num_scan_data = 64;
Navtej Singh Mannc8b61ce2015-04-16 18:54:10 -0700568
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700569 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700570 ALOGD("getting scan results on interface[%d] = %p", iface, handle);
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700571
Navtej Singh Mannc8b61ce2015-04-16 18:54:10 -0700572 byte b = flush ? 0xFF : 0;
xinhe62819992015-04-03 11:13:59 -0700573 int result = hal_fn.wifi_get_cached_gscan_results(handle, b, num_scan_data, scan_data, &num_scan_data);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700574 if (result == WIFI_SUCCESS) {
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700575 jobjectArray scanData = createObjectArray(env,
576 "android/net/wifi/WifiScanner$ScanData", num_scan_data);
577 if (scanData == NULL) {
578 ALOGE("Error in allocating array of scanData");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700579 return NULL;
580 }
581
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700582 for (int i = 0; i < num_scan_data; i++) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700583
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700584 jobject data = createObject(env, "android/net/wifi/WifiScanner$ScanData");
585 if (data == NULL) {
586 ALOGE("Error in allocating scanData");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700587 return NULL;
588 }
589
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700590 setIntField(env, data, "mId", scan_data[i].scan_id);
591 setIntField(env, data, "mFlags", scan_data[i].flags);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700592
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700593 /* sort all scan results by timestamp */
594 qsort(scan_data[i].results, scan_data[i].num_results,
595 sizeof(wifi_scan_result), compare_scan_result_timestamp);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700596
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700597 jobjectArray scanResults = createObjectArray(env,
598 "android/net/wifi/ScanResult", scan_data[i].num_results);
599 if (scanResults == NULL) {
600 ALOGE("Error in allocating scanResult array");
601 return NULL;
602 }
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700603
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700604 wifi_scan_result *results = scan_data[i].results;
605 for (int j = 0; j < scan_data[i].num_results; j++) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700606
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700607 jobject scanResult = createObject(env, "android/net/wifi/ScanResult");
608 if (scanResult == NULL) {
609 ALOGE("Error in creating scan result");
610 return NULL;
611 }
612
613 setStringField(env, scanResult, "SSID", results[j].ssid);
614
615 char bssid[32];
616 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", results[j].bssid[0],
617 results[j].bssid[1], results[j].bssid[2], results[j].bssid[3],
618 results[j].bssid[4], results[j].bssid[5]);
619
620 setStringField(env, scanResult, "BSSID", bssid);
621
622 setIntField(env, scanResult, "level", results[j].rssi);
623 setIntField(env, scanResult, "frequency", results[j].channel);
624 setLongField(env, scanResult, "timestamp", results[j].ts);
625
626 env->SetObjectArrayElement(scanResults, j, scanResult);
627 env->DeleteLocalRef(scanResult);
628 }
629
630 setObjectField(env, data, "mResults", "[Landroid/net/wifi/ScanResult;", scanResults);
631 env->SetObjectArrayElement(scanData, i, data);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700632 }
633
Vinit Deshpande83a674a2014-10-31 11:15:26 -0700634 return scanData;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700635 } else {
636 return NULL;
637 }
638}
639
640
641static jboolean android_net_wifi_getScanCapabilities(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700642 JNIEnv *env, jclass cls, jint iface, jobject capabilities) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700643
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700644 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700645 ALOGD("getting scan capabilities on interface[%d] = %p", iface, handle);
646
647 wifi_gscan_capabilities c;
648 memset(&c, 0, sizeof(c));
xinhe62819992015-04-03 11:13:59 -0700649 int result = hal_fn.wifi_get_gscan_capabilities(handle, &c);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700650 if (result != WIFI_SUCCESS) {
651 ALOGD("failed to get capabilities : %d", result);
652 return JNI_FALSE;
653 }
654
655 setIntField(env, capabilities, "max_scan_cache_size", c.max_scan_cache_size);
656 setIntField(env, capabilities, "max_scan_buckets", c.max_scan_buckets);
657 setIntField(env, capabilities, "max_ap_cache_per_scan", c.max_ap_cache_per_scan);
658 setIntField(env, capabilities, "max_rssi_sample_size", c.max_rssi_sample_size);
659 setIntField(env, capabilities, "max_scan_reporting_threshold", c.max_scan_reporting_threshold);
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700660 setIntField(env, capabilities, "max_hotlist_bssids", c.max_hotlist_bssids);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700661 setIntField(env, capabilities, "max_significant_wifi_change_aps",
662 c.max_significant_wifi_change_aps);
663
664 return JNI_TRUE;
665}
666
667
668static byte parseHexChar(char ch) {
669 if (isdigit(ch))
670 return ch - '0';
671 else if ('A' <= ch && ch <= 'F')
672 return ch - 'A' + 10;
673 else if ('a' <= ch && ch <= 'f')
674 return ch - 'a' + 10;
675 else {
676 ALOGE("invalid character in bssid %c", ch);
677 return 0;
678 }
679}
680
681static byte parseHexByte(const char * &str) {
682 byte b = parseHexChar(str[0]);
683 if (str[1] == ':' || str[1] == '\0') {
684 str += 2;
685 return b;
686 } else {
687 b = b << 4 | parseHexChar(str[1]);
688 str += 3;
689 return b;
690 }
691}
692
693static void parseMacAddress(const char *str, mac_addr addr) {
694 addr[0] = parseHexByte(str);
695 addr[1] = parseHexByte(str);
696 addr[2] = parseHexByte(str);
697 addr[3] = parseHexByte(str);
698 addr[4] = parseHexByte(str);
699 addr[5] = parseHexByte(str);
700}
701
Vinit Deshpande14365732014-06-30 15:23:23 -0700702static bool parseMacAddress(JNIEnv *env, jobject obj, mac_addr addr) {
703 jstring macAddrString = (jstring) getObjectField(
704 env, obj, "bssid", "Ljava/lang/String;");
705
706 if (macAddrString == NULL) {
707 ALOGE("Error getting bssid field");
708 return false;
709 }
710
711 const char *bssid = env->GetStringUTFChars(macAddrString, NULL);
712 if (bssid == NULL) {
713 ALOGE("Error getting bssid");
714 return false;
715 }
716
717 parseMacAddress(bssid, addr);
718 return true;
719}
720
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700721static void onHotlistApFound(wifi_request_id id,
722 unsigned num_results, wifi_scan_result *results) {
723
724 JNIEnv *env = NULL;
725 mVM->AttachCurrentThread(&env, NULL);
726
727 ALOGD("onHotlistApFound called, vm = %p, obj = %p, env = %p, num_results = %d",
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700728 mVM, mCls, env, num_results);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700729
730 jclass clsScanResult = (env)->FindClass("android/net/wifi/ScanResult");
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700731 if (clsScanResult == NULL) {
732 ALOGE("Error in accessing class");
733 return;
734 }
735
736 jobjectArray scanResults = env->NewObjectArray(num_results, clsScanResult, NULL);
737 if (scanResults == NULL) {
738 ALOGE("Error in allocating array");
739 return;
740 }
741
742 for (unsigned i = 0; i < num_results; i++) {
743
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700744 jobject scanResult = createObject(env, "android/net/wifi/ScanResult");
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700745 if (scanResult == NULL) {
746 ALOGE("Error in creating scan result");
747 return;
748 }
749
750 setStringField(env, scanResult, "SSID", results[i].ssid);
751
752 char bssid[32];
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700753 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", results[i].bssid[0], results[i].bssid[1],
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700754 results[i].bssid[2], results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]);
755
756 setStringField(env, scanResult, "BSSID", bssid);
757
758 setIntField(env, scanResult, "level", results[i].rssi);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700759 setIntField(env, scanResult, "frequency", results[i].channel);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700760 setLongField(env, scanResult, "timestamp", results[i].ts);
761
762 env->SetObjectArrayElement(scanResults, i, scanResult);
763
764 ALOGD("Found AP %32s %s", results[i].ssid, bssid);
765 }
766
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700767 reportEvent(env, mCls, "onHotlistApFound", "(I[Landroid/net/wifi/ScanResult;)V",
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700768 id, scanResults);
769}
770
Vinit Deshpanded4762402014-08-11 21:51:25 -0700771static void onHotlistApLost(wifi_request_id id,
772 unsigned num_results, wifi_scan_result *results) {
773
774 JNIEnv *env = NULL;
775 mVM->AttachCurrentThread(&env, NULL);
776
777 ALOGD("onHotlistApLost called, vm = %p, obj = %p, env = %p, num_results = %d",
778 mVM, mCls, env, num_results);
779
780 jclass clsScanResult = (env)->FindClass("android/net/wifi/ScanResult");
781 if (clsScanResult == NULL) {
782 ALOGE("Error in accessing class");
783 return;
784 }
785
786 jobjectArray scanResults = env->NewObjectArray(num_results, clsScanResult, NULL);
787 if (scanResults == NULL) {
788 ALOGE("Error in allocating array");
789 return;
790 }
791
792 for (unsigned i = 0; i < num_results; i++) {
793
794 jobject scanResult = createObject(env, "android/net/wifi/ScanResult");
795 if (scanResult == NULL) {
796 ALOGE("Error in creating scan result");
797 return;
798 }
799
800 setStringField(env, scanResult, "SSID", results[i].ssid);
801
802 char bssid[32];
803 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", results[i].bssid[0], results[i].bssid[1],
804 results[i].bssid[2], results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]);
805
806 setStringField(env, scanResult, "BSSID", bssid);
807
808 setIntField(env, scanResult, "level", results[i].rssi);
809 setIntField(env, scanResult, "frequency", results[i].channel);
810 setLongField(env, scanResult, "timestamp", results[i].ts);
811
812 env->SetObjectArrayElement(scanResults, i, scanResult);
813
814 ALOGD("Lost AP %32s %s", results[i].ssid, bssid);
815 }
816
817 reportEvent(env, mCls, "onHotlistApLost", "(I[Landroid/net/wifi/ScanResult;)V",
818 id, scanResults);
819}
820
821
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700822static jboolean android_net_wifi_setHotlist(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700823 JNIEnv *env, jclass cls, jint iface, jint id, jobject ap) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700824
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700825 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700826 ALOGD("setting hotlist on interface[%d] = %p", iface, handle);
827
828 wifi_bssid_hotlist_params params;
829 memset(&params, 0, sizeof(params));
830
Vinit Deshpanded4762402014-08-11 21:51:25 -0700831 params.lost_ap_sample_size = getIntField(env, ap, "apLostThreshold");
832
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700833 jobjectArray array = (jobjectArray) getObjectField(env, ap,
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700834 "bssidInfos", "[Landroid/net/wifi/WifiScanner$BssidInfo;");
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700835 params.num_bssid = env->GetArrayLength(array);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700836
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700837 if (params.num_bssid == 0) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700838 ALOGE("Error in accesing array");
839 return false;
840 }
841
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700842 for (int i = 0; i < params.num_bssid; i++) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700843 jobject objAp = env->GetObjectArrayElement(array, i);
844
845 jstring macAddrString = (jstring) getObjectField(
846 env, objAp, "bssid", "Ljava/lang/String;");
847 if (macAddrString == NULL) {
848 ALOGE("Error getting bssid field");
849 return false;
850 }
851
852 const char *bssid = env->GetStringUTFChars(macAddrString, NULL);
853 if (bssid == NULL) {
854 ALOGE("Error getting bssid");
855 return false;
856 }
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700857 parseMacAddress(bssid, params.ap[i].bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700858
859 mac_addr addr;
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700860 memcpy(addr, params.ap[i].bssid, sizeof(mac_addr));
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700861
862 char bssidOut[32];
863 sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1],
864 addr[2], addr[3], addr[4], addr[5]);
865
866 ALOGD("Added bssid %s", bssidOut);
867
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700868 params.ap[i].low = getIntField(env, objAp, "low");
869 params.ap[i].high = getIntField(env, objAp, "high");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700870 }
871
872 wifi_hotlist_ap_found_handler handler;
873 memset(&handler, 0, sizeof(handler));
874
875 handler.on_hotlist_ap_found = &onHotlistApFound;
Vinit Deshpanded4762402014-08-11 21:51:25 -0700876 handler.on_hotlist_ap_lost = &onHotlistApLost;
xinhe62819992015-04-03 11:13:59 -0700877 return hal_fn.wifi_set_bssid_hotlist(id, handle, params, handler) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700878}
879
880static jboolean android_net_wifi_resetHotlist(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700881 JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700882
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700883 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700884 ALOGD("resetting hotlist on interface[%d] = %p", iface, handle);
885
xinhe62819992015-04-03 11:13:59 -0700886 return hal_fn.wifi_reset_bssid_hotlist(id, handle) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700887}
888
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700889void onSignificantWifiChange(wifi_request_id id,
890 unsigned num_results, wifi_significant_change_result **results) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700891 JNIEnv *env = NULL;
892 mVM->AttachCurrentThread(&env, NULL);
893
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700894 ALOGD("onSignificantWifiChange called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700895
896 jclass clsScanResult = (env)->FindClass("android/net/wifi/ScanResult");
897 if (clsScanResult == NULL) {
898 ALOGE("Error in accessing class");
899 return;
900 }
901
902 jobjectArray scanResults = env->NewObjectArray(num_results, clsScanResult, NULL);
903 if (scanResults == NULL) {
904 ALOGE("Error in allocating array");
905 return;
906 }
907
908 for (unsigned i = 0; i < num_results; i++) {
909
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700910 wifi_significant_change_result result = *(results[i]);
911
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700912 jobject scanResult = createObject(env, "android/net/wifi/ScanResult");
913 if (scanResult == NULL) {
914 ALOGE("Error in creating scan result");
915 return;
916 }
917
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700918 // setStringField(env, scanResult, "SSID", results[i].ssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700919
920 char bssid[32];
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700921 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result.bssid[0], result.bssid[1],
922 result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700923
924 setStringField(env, scanResult, "BSSID", bssid);
925
Vinit Deshpande4dbfefd2014-08-10 18:19:13 -0700926 setIntField(env, scanResult, "level", result.rssi[0]);
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700927 setIntField(env, scanResult, "frequency", result.channel);
928 // setLongField(env, scanResult, "timestamp", result.ts);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700929
930 env->SetObjectArrayElement(scanResults, i, scanResult);
931 }
932
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700933 reportEvent(env, mCls, "onSignificantWifiChange", "(I[Landroid/net/wifi/ScanResult;)V",
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700934 id, scanResults);
935
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700936}
937
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700938static jboolean android_net_wifi_trackSignificantWifiChange(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700939 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) {
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700940
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700941 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700942 ALOGD("tracking significant wifi change on interface[%d] = %p", iface, handle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700943
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700944 wifi_significant_change_params params;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700945 memset(&params, 0, sizeof(params));
946
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700947 params.rssi_sample_size = getIntField(env, settings, "rssiSampleSize");
948 params.lost_ap_sample_size = getIntField(env, settings, "lostApSampleSize");
949 params.min_breaching = getIntField(env, settings, "minApsBreachingThreshold");
950
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700951 const char *bssid_info_array_type = "[Landroid/net/wifi/WifiScanner$BssidInfo;";
952 jobjectArray bssids = (jobjectArray)getObjectField(
953 env, settings, "bssidInfos", bssid_info_array_type);
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700954 params.num_bssid = env->GetArrayLength(bssids);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700955
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700956 if (params.num_bssid == 0) {
vandwalleaabe7a92014-05-09 18:11:02 -0700957 ALOGE("Error in accessing array");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700958 return false;
959 }
960
961 ALOGD("Initialized common fields %d, %d, %d, %d", params.rssi_sample_size,
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700962 params.lost_ap_sample_size, params.min_breaching, params.num_bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700963
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700964 for (int i = 0; i < params.num_bssid; i++) {
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700965 jobject objAp = env->GetObjectArrayElement(bssids, i);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700966
967 jstring macAddrString = (jstring) getObjectField(
968 env, objAp, "bssid", "Ljava/lang/String;");
969 if (macAddrString == NULL) {
970 ALOGE("Error getting bssid field");
971 return false;
972 }
973
974 const char *bssid = env->GetStringUTFChars(macAddrString, NULL);
975 if (bssid == NULL) {
976 ALOGE("Error getting bssid");
977 return false;
978 }
979
980 mac_addr addr;
981 parseMacAddress(bssid, addr);
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700982 memcpy(params.ap[i].bssid, addr, sizeof(mac_addr));
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700983
984 char bssidOut[32];
Vinit Deshpande4dbfefd2014-08-10 18:19:13 -0700985 sprintf(bssidOut, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1],
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700986 addr[2], addr[3], addr[4], addr[5]);
987
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700988 params.ap[i].low = getIntField(env, objAp, "low");
989 params.ap[i].high = getIntField(env, objAp, "high");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700990
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700991 ALOGD("Added bssid %s, [%04d, %04d]", bssidOut, params.ap[i].low, params.ap[i].high);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700992 }
993
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700994 ALOGD("Added %d bssids", params.num_bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700995
996 wifi_significant_change_handler handler;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700997 memset(&handler, 0, sizeof(handler));
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700998
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700999 handler.on_significant_change = &onSignificantWifiChange;
xinhe62819992015-04-03 11:13:59 -07001000 return hal_fn.wifi_set_significant_change_handler(id, handle, params, handler) == WIFI_SUCCESS;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001001}
1002
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001003static jboolean android_net_wifi_untrackSignificantWifiChange(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -07001004 JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001005
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -07001006 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001007 ALOGD("resetting significant wifi change on interface[%d] = %p", iface, handle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001008
xinhe62819992015-04-03 11:13:59 -07001009 return hal_fn.wifi_reset_significant_change_handler(id, handle) == WIFI_SUCCESS;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001010}
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -08001011
vandwalleaabe7a92014-05-09 18:11:02 -07001012wifi_iface_stat link_stat;
vandwalle200e8ee2014-07-18 18:44:32 -07001013wifi_radio_stat radio_stat; // L release has support for only one radio
vandwalleaabe7a92014-05-09 18:11:02 -07001014
1015void onLinkStatsResults(wifi_request_id id, wifi_iface_stat *iface_stat,
vandwalle200e8ee2014-07-18 18:44:32 -07001016 int num_radios, wifi_radio_stat *radio_stats)
vandwalleaabe7a92014-05-09 18:11:02 -07001017{
vandwalle200e8ee2014-07-18 18:44:32 -07001018 if (iface_stat != 0) {
1019 memcpy(&link_stat, iface_stat, sizeof(wifi_iface_stat));
1020 } else {
1021 memset(&link_stat, 0, sizeof(wifi_iface_stat));
1022 }
vandwalle200e8ee2014-07-18 18:44:32 -07001023
1024 if (num_radios > 0 && radio_stats != 0) {
1025 memcpy(&radio_stat, radio_stats, sizeof(wifi_radio_stat));
1026 } else {
1027 memset(&radio_stat, 0, sizeof(wifi_radio_stat));
1028 }
vandwalleaabe7a92014-05-09 18:11:02 -07001029}
1030
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -07001031static jobject android_net_wifi_getLinkLayerStats (JNIEnv *env, jclass cls, jint iface) {
vandwalleaabe7a92014-05-09 18:11:02 -07001032
1033 wifi_stats_result_handler handler;
1034 memset(&handler, 0, sizeof(handler));
1035 handler.on_link_stats_results = &onLinkStatsResults;
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -07001036 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
xinhe62819992015-04-03 11:13:59 -07001037 int result = hal_fn.wifi_get_link_stats(0, handle, handler);
vandwalleaabe7a92014-05-09 18:11:02 -07001038 if (result < 0) {
vandwalle200e8ee2014-07-18 18:44:32 -07001039 ALOGE("android_net_wifi_getLinkLayerStats: failed to get link statistics\n");
vandwalleaabe7a92014-05-09 18:11:02 -07001040 return NULL;
1041 }
1042
1043 jobject wifiLinkLayerStats = createObject(env, "android/net/wifi/WifiLinkLayerStats");
1044 if (wifiLinkLayerStats == NULL) {
1045 ALOGE("Error in allocating wifiLinkLayerStats");
1046 return NULL;
1047 }
1048
1049 setIntField(env, wifiLinkLayerStats, "beacon_rx", link_stat.beacon_rx);
1050 setIntField(env, wifiLinkLayerStats, "rssi_mgmt", link_stat.rssi_mgmt);
1051 setLongField(env, wifiLinkLayerStats, "rxmpdu_be", link_stat.ac[WIFI_AC_BE].rx_mpdu);
1052 setLongField(env, wifiLinkLayerStats, "rxmpdu_bk", link_stat.ac[WIFI_AC_BK].rx_mpdu);
1053 setLongField(env, wifiLinkLayerStats, "rxmpdu_vi", link_stat.ac[WIFI_AC_VI].rx_mpdu);
1054 setLongField(env, wifiLinkLayerStats, "rxmpdu_vo", link_stat.ac[WIFI_AC_VO].rx_mpdu);
1055 setLongField(env, wifiLinkLayerStats, "txmpdu_be", link_stat.ac[WIFI_AC_BE].tx_mpdu);
1056 setLongField(env, wifiLinkLayerStats, "txmpdu_bk", link_stat.ac[WIFI_AC_BK].tx_mpdu);
1057 setLongField(env, wifiLinkLayerStats, "txmpdu_vi", link_stat.ac[WIFI_AC_VI].tx_mpdu);
1058 setLongField(env, wifiLinkLayerStats, "txmpdu_vo", link_stat.ac[WIFI_AC_VO].tx_mpdu);
1059 setLongField(env, wifiLinkLayerStats, "lostmpdu_be", link_stat.ac[WIFI_AC_BE].mpdu_lost);
1060 setLongField(env, wifiLinkLayerStats, "lostmpdu_bk", link_stat.ac[WIFI_AC_BK].mpdu_lost);
1061 setLongField(env, wifiLinkLayerStats, "lostmpdu_vi", link_stat.ac[WIFI_AC_VI].mpdu_lost);
1062 setLongField(env, wifiLinkLayerStats, "lostmpdu_vo", link_stat.ac[WIFI_AC_VO].mpdu_lost);
1063 setLongField(env, wifiLinkLayerStats, "retries_be", link_stat.ac[WIFI_AC_BE].retries);
1064 setLongField(env, wifiLinkLayerStats, "retries_bk", link_stat.ac[WIFI_AC_BK].retries);
1065 setLongField(env, wifiLinkLayerStats, "retries_vi", link_stat.ac[WIFI_AC_VI].retries);
1066 setLongField(env, wifiLinkLayerStats, "retries_vo", link_stat.ac[WIFI_AC_VO].retries);
1067
vandwalle200e8ee2014-07-18 18:44:32 -07001068
1069 setIntField(env, wifiLinkLayerStats, "on_time", radio_stat.on_time);
1070 setIntField(env, wifiLinkLayerStats, "tx_time", radio_stat.tx_time);
1071 setIntField(env, wifiLinkLayerStats, "rx_time", radio_stat.rx_time);
1072 setIntField(env, wifiLinkLayerStats, "on_time_scan", radio_stat.on_time_scan);
1073
vandwalleaabe7a92014-05-09 18:11:02 -07001074 return wifiLinkLayerStats;
1075}
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001076
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001077static jint android_net_wifi_getSupportedFeatures(JNIEnv *env, jclass cls, jint iface) {
1078 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001079 feature_set set = 0;
1080
1081 wifi_error result = WIFI_SUCCESS;
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001082 /*
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001083 set = WIFI_FEATURE_INFRA
1084 | WIFI_FEATURE_INFRA_5G
1085 | WIFI_FEATURE_HOTSPOT
1086 | WIFI_FEATURE_P2P
1087 | WIFI_FEATURE_SOFT_AP
1088 | WIFI_FEATURE_GSCAN
1089 | WIFI_FEATURE_PNO
1090 | WIFI_FEATURE_TDLS
1091 | WIFI_FEATURE_EPR;
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001092 */
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001093
xinhe62819992015-04-03 11:13:59 -07001094 result = hal_fn.wifi_get_supported_feature_set(handle, &set);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001095 if (result == WIFI_SUCCESS) {
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001096 ALOGD("wifi_get_supported_feature_set returned set = 0x%x", set);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001097 return set;
1098 } else {
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001099 ALOGD("wifi_get_supported_feature_set returned error = 0x%x", result);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001100 return 0;
1101 }
1102}
1103
xinhe06a3eba2015-03-18 20:17:17 -07001104static void onRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* results[]) {
Vinit Deshpande14365732014-06-30 15:23:23 -07001105 JNIEnv *env = NULL;
1106 mVM->AttachCurrentThread(&env, NULL);
1107
1108 ALOGD("onRttResults called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
1109
1110 jclass clsRttResult = (env)->FindClass("android/net/wifi/RttManager$RttResult");
1111 if (clsRttResult == NULL) {
1112 ALOGE("Error in accessing class");
1113 return;
1114 }
1115
1116 jobjectArray rttResults = env->NewObjectArray(num_results, clsRttResult, NULL);
1117 if (rttResults == NULL) {
1118 ALOGE("Error in allocating array");
1119 return;
1120 }
1121
1122 for (unsigned i = 0; i < num_results; i++) {
1123
xinhe06a3eba2015-03-18 20:17:17 -07001124 wifi_rtt_result *result = results[i];
Vinit Deshpande14365732014-06-30 15:23:23 -07001125
1126 jobject rttResult = createObject(env, "android/net/wifi/RttManager$RttResult");
1127 if (rttResult == NULL) {
1128 ALOGE("Error in creating rtt result");
1129 return;
1130 }
1131
Vinit Deshpande14365732014-06-30 15:23:23 -07001132 char bssid[32];
xinhe06a3eba2015-03-18 20:17:17 -07001133 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->addr[0], result->addr[1],
1134 result->addr[2], result->addr[3], result->addr[4], result->addr[5]);
Vinit Deshpande14365732014-06-30 15:23:23 -07001135
1136 setStringField(env, rttResult, "bssid", bssid);
xinhe06a3eba2015-03-18 20:17:17 -07001137 setIntField(env, rttResult, "burstNumber", result->burst_num);
1138 setIntField(env, rttResult, "measurementFrameNumber", result->measurement_number);
1139 setIntField(env, rttResult, "successMeasurementFrameNumber", result->success_number);
1140 setIntField(env, rttResult, "frameNumberPerBurstPeer", result->number_per_burst_peer);
1141 setIntField(env, rttResult, "status", result->status);
1142 setIntField(env, rttResult, "measurementType", result->type);
1143 setIntField(env, rttResult, "retryAfterDuration", result->retry_after_duration);
1144 setLongField(env, rttResult, "ts", result->ts);
1145 setIntField(env, rttResult, "rssi", result->rssi);
1146 setIntField(env, rttResult, "rssiSpread", result->rssi_spread);
1147 setIntField(env, rttResult, "txRate", result->tx_rate.bitrate);
1148 setIntField(env, rttResult, "rxRate", result->rx_rate.bitrate);
1149 setLongField(env, rttResult, "rtt", result->rtt);
1150 setLongField(env, rttResult, "rttStandardDeviation", result->rtt_sd);
xinhe06a3eba2015-03-18 20:17:17 -07001151 setIntField(env, rttResult, "distance", result->distance);
1152 setIntField(env, rttResult, "distanceStandardDeviation", result->distance_sd);
1153 setIntField(env, rttResult, "distanceSpread", result->distance_spread);
1154 setIntField(env, rttResult, "burstDuration", result->burst_duration);
xinhec96feb82015-04-01 18:52:59 -07001155 setIntField(env, rttResult, "negotiatedBurstNum", result->negotiated_burst_num);
1156 jobject LCI = createObject(env, "android/net/wifi/RttManager$WifiInformationElement");
1157 if (result->LCI != NULL && result->LCI->len > 0) {
1158 ALOGD("Add LCI in result");
1159 setByteField(env, LCI, "id", result->LCI->id);
1160 jbyteArray elements = env->NewByteArray(result->LCI->len);
1161 jbyte *bytes = (jbyte *)&(result->LCI->data[0]);
1162 env->SetByteArrayRegion(elements, 0, result->LCI->len, bytes);
1163 setObjectField(env, LCI, "data", "[B", elements);
xinhe93a1dbd2015-04-10 09:43:26 -07001164 env->DeleteLocalRef(elements);
xinhec96feb82015-04-01 18:52:59 -07001165 } else {
1166 ALOGD("No LCI in result");
1167 setByteField(env, LCI, "id", (byte)(0xff));
1168 }
1169 setObjectField(env, rttResult, "LCI",
1170 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCI);
xinhe12cf3882015-03-12 18:38:54 -07001171
xinhec96feb82015-04-01 18:52:59 -07001172 jobject LCR = createObject(env, "android/net/wifi/RttManager$WifiInformationElement");
1173 if (result->LCR != NULL && result->LCR->len > 0) {
1174 ALOGD("Add LCR in result");
1175 setByteField(env, LCR, "id", result->LCR->id);
1176 jbyteArray elements = env->NewByteArray(result->LCI->len);
1177 jbyte *bytes = (jbyte *)&(result->LCR->data[0]);
1178 env->SetByteArrayRegion(elements, 0, result->LCI->len, bytes);
1179 setObjectField(env, LCR, "data", "[B", elements);
xinhe93a1dbd2015-04-10 09:43:26 -07001180 env->DeleteLocalRef(elements);
xinhec96feb82015-04-01 18:52:59 -07001181 } else {
xinhe93a1dbd2015-04-10 09:43:26 -07001182 ALOGD("No LCR in result");
xinhec96feb82015-04-01 18:52:59 -07001183 setByteField(env, LCR, "id", (byte)(0xff));
1184 }
1185 setObjectField(env, rttResult, "LCR",
1186 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCR);
Vinit Deshpande14365732014-06-30 15:23:23 -07001187
1188 env->SetObjectArrayElement(rttResults, i, rttResult);
xinhe93a1dbd2015-04-10 09:43:26 -07001189 env->DeleteLocalRef(LCI);
1190 env->DeleteLocalRef(LCR);
1191 env->DeleteLocalRef(rttResult);
Vinit Deshpande14365732014-06-30 15:23:23 -07001192 }
1193
1194 reportEvent(env, mCls, "onRttResults", "(I[Landroid/net/wifi/RttManager$RttResult;)V",
1195 id, rttResults);
xinhe93a1dbd2015-04-10 09:43:26 -07001196
1197 //clean the local reference
1198 env->DeleteLocalRef(rttResults);
1199 env->DeleteLocalRef(clsRttResult);
1200
Vinit Deshpande14365732014-06-30 15:23:23 -07001201}
1202
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001203const int MaxRttConfigs = 16;
1204
Vinit Deshpande14365732014-06-30 15:23:23 -07001205static jboolean android_net_wifi_requestRange(
1206 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) {
1207
1208 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1209 ALOGD("sending rtt request [%d] = %p", id, handle);
1210
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001211 wifi_rtt_config configs[MaxRttConfigs];
1212 memset(&configs, 0, sizeof(configs));
Vinit Deshpande14365732014-06-30 15:23:23 -07001213
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001214 int len = env->GetArrayLength((jobjectArray)params);
1215 if (len > MaxRttConfigs) {
1216 return false;
1217 }
1218
1219 for (int i = 0; i < len; i++) {
1220
1221 jobject param = env->GetObjectArrayElement((jobjectArray)params, i);
1222 if (param == NULL) {
1223 ALOGD("could not get element %d", i);
1224 continue;
1225 }
1226
1227 wifi_rtt_config &config = configs[i];
1228
1229 parseMacAddress(env, param, config.addr);
1230 config.type = (wifi_rtt_type)getIntField(env, param, "requestType");
xinhec96feb82015-04-01 18:52:59 -07001231 config.peer = (rtt_peer_type)getIntField(env, param, "deviceType");
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001232 config.channel.center_freq = getIntField(env, param, "frequency");
xinhe12cf3882015-03-12 18:38:54 -07001233 config.channel.width = (wifi_channel_width) getIntField(env, param, "channelWidth");
1234 config.channel.center_freq0 = getIntField(env, param, "centerFreq0");
1235 config.channel.center_freq1 = getIntField(env, param, "centerFreq1");
1236
1237 config.num_burst = getIntField(env, param, "numberBurst");
xinhec96feb82015-04-01 18:52:59 -07001238 config.burst_period = (unsigned) getIntField(env, param, "interval");
xinhe12cf3882015-03-12 18:38:54 -07001239 config.num_frames_per_burst = (unsigned) getIntField(env, param, "numSamplesPerBurst");
xinhec96feb82015-04-01 18:52:59 -07001240 config.num_retries_per_rtt_frame = (unsigned) getIntField(env, param,
xinhe12cf3882015-03-12 18:38:54 -07001241 "numRetriesPerMeasurementFrame");
1242 config.num_retries_per_ftmr = (unsigned) getIntField(env, param, "numRetriesPerFTMR");
1243 config.LCI_request = getBoolField(env, param, "LCIRequest") ? 1 : 0;
1244 config.LCR_request = getBoolField(env, param, "LCRRequest") ? 1 : 0;
xinhec96feb82015-04-01 18:52:59 -07001245 config.burst_duration = (unsigned) getIntField(env, param, "burstTimeout");
1246 config.preamble = (wifi_rtt_preamble) getIntField(env, param, "preamble");
1247 config.bw = (wifi_rtt_bw) getIntField(env, param, "bandwidth");
xinhe12cf3882015-03-12 18:38:54 -07001248
1249 ALOGD("RTT request destination %d: type is %d, peer is %d, bw is %d, center_freq is %d ", i,
1250 config.type,config.peer, config.channel.width, config.channel.center_freq0);
1251 ALOGD("center_freq0 is %d, center_freq1 is %d, num_burst is %d,interval is %d",
1252 config.channel.center_freq0, config.channel.center_freq1, config.num_burst,
xinhec96feb82015-04-01 18:52:59 -07001253 config.burst_period);
xinhe12cf3882015-03-12 18:38:54 -07001254 ALOGD("frames_per_burst is %d, retries of measurement frame is %d, retries_per_ftmr is %d",
xinhec96feb82015-04-01 18:52:59 -07001255 config.num_frames_per_burst, config.num_retries_per_rtt_frame,
xinhe12cf3882015-03-12 18:38:54 -07001256 config.num_retries_per_ftmr);
1257 ALOGD("LCI_requestis %d, LCR_request is %d, burst_timeout is %d, preamble is %d, bw is %d",
xinhec96feb82015-04-01 18:52:59 -07001258 config.LCI_request, config.LCR_request, config.burst_duration, config.preamble,
xinhe12cf3882015-03-12 18:38:54 -07001259 config.bw);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001260 }
Vinit Deshpande14365732014-06-30 15:23:23 -07001261
1262 wifi_rtt_event_handler handler;
1263 handler.on_rtt_results = &onRttResults;
1264
xinhe62819992015-04-03 11:13:59 -07001265 return hal_fn.wifi_rtt_range_request(id, handle, len, configs, handler) == WIFI_SUCCESS;
Vinit Deshpande14365732014-06-30 15:23:23 -07001266}
1267
1268static jboolean android_net_wifi_cancelRange(
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001269 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) {
Vinit Deshpande14365732014-06-30 15:23:23 -07001270
1271 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1272 ALOGD("cancelling rtt request [%d] = %p", id, handle);
1273
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001274 mac_addr addrs[MaxRttConfigs];
1275 memset(&addrs, 0, sizeof(addrs));
Vinit Deshpande14365732014-06-30 15:23:23 -07001276
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001277 int len = env->GetArrayLength((jobjectArray)params);
1278 if (len > MaxRttConfigs) {
1279 return false;
1280 }
Vinit Deshpande14365732014-06-30 15:23:23 -07001281
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001282 for (int i = 0; i < len; i++) {
1283
1284 jobject param = env->GetObjectArrayElement((jobjectArray)params, i);
1285 if (param == NULL) {
1286 ALOGD("could not get element %d", i);
1287 continue;
1288 }
1289
1290 parseMacAddress(env, param, addrs[i]);
1291 }
1292
xinhe62819992015-04-03 11:13:59 -07001293 return hal_fn.wifi_rtt_range_cancel(id, handle, len, addrs) == WIFI_SUCCESS;
Vinit Deshpande14365732014-06-30 15:23:23 -07001294}
1295
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001296static jboolean android_net_wifi_setScanningMacOui(JNIEnv *env, jclass cls,
1297 jint iface, jbyteArray param) {
1298
1299 wifi_interface_handle handle = getIfaceHandle(env, 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 = env->GetArrayLength(param);
1304 if (len != oui_len) {
1305 ALOGE("invalid oui length %d", len);
1306 return false;
1307 }
1308
1309 jbyte* bytes = env->GetByteArrayElements(param, NULL);
1310 if (bytes == NULL) {
1311 ALOGE("failed to get array");
1312 return false;
1313 }
1314
xinhe62819992015-04-03 11:13:59 -07001315 return hal_fn.wifi_set_scanning_mac_oui(handle, (byte *)bytes) == WIFI_SUCCESS;
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001316}
1317
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001318static jintArray android_net_wifi_getValidChannels(JNIEnv *env, jclass cls,
1319 jint iface, jint band) {
1320
1321 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1322 ALOGD("getting valid channels %p", handle);
1323
1324 static const int MaxChannels = 64;
1325 wifi_channel channels[64];
1326 int num_channels = 0;
xinhe62819992015-04-03 11:13:59 -07001327 wifi_error result = hal_fn.wifi_get_valid_channels(handle, band, MaxChannels,
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001328 channels, &num_channels);
1329
1330 if (result == WIFI_SUCCESS) {
1331 jintArray channelArray = env->NewIntArray(num_channels);
1332 if (channelArray == NULL) {
1333 ALOGE("failed to allocate channel list");
1334 return NULL;
1335 }
1336
1337 env->SetIntArrayRegion(channelArray, 0, num_channels, channels);
1338 return channelArray;
1339 } else {
1340 ALOGE("failed to get channel list : %d", result);
1341 return NULL;
1342 }
1343}
1344
Vinit Deshpande0465ff52014-10-13 13:21:47 -07001345static jboolean android_net_wifi_setDfsFlag(JNIEnv *env, jclass cls, jint iface, jboolean dfs) {
1346 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1347 ALOGD("setting dfs flag to %s, %p", dfs ? "true" : "false", handle);
1348
1349 u32 nodfs = dfs ? 0 : 1;
xinhe62819992015-04-03 11:13:59 -07001350 wifi_error result = hal_fn.wifi_set_nodfs_flag(handle, nodfs);
Vinit Deshpande0465ff52014-10-13 13:21:47 -07001351 return result == WIFI_SUCCESS;
1352}
1353
xinhe12cf3882015-03-12 18:38:54 -07001354static jobject android_net_wifi_get_rtt_capabilities(JNIEnv *env, jclass cls, jint iface) {
1355 wifi_rtt_capabilities rtt_capabilities;
1356 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
xinhe62819992015-04-03 11:13:59 -07001357 wifi_error ret = hal_fn.wifi_get_rtt_capabilities(handle, &rtt_capabilities);
xinhe12cf3882015-03-12 18:38:54 -07001358
1359 if(WIFI_SUCCESS == ret) {
1360 jobject capabilities = createObject(env, "android/net/wifi/RttManager$RttCapabilities");
1361 setBooleanField(env, capabilities, "oneSidedRttSupported",
1362 rtt_capabilities.rtt_one_sided_supported == 1);
1363 setBooleanField(env, capabilities, "twoSided11McRttSupported",
1364 rtt_capabilities.rtt_ftm_supported == 1);
1365 setBooleanField(env, capabilities, "lciSupported",
1366 rtt_capabilities.lci_support);
1367 setBooleanField(env,capabilities, "lcrSupported",
1368 rtt_capabilities.lcr_support);
1369 setIntField(env, capabilities, "preambleSupported",
1370 rtt_capabilities.preamble_support);
1371 setIntField(env, capabilities, "bwSupported",
1372 rtt_capabilities.bw_support);
1373 ALOGD("One side RTT is: %s", rtt_capabilities.rtt_one_sided_supported ==1 ? "support" :
1374 "not support");
1375 ALOGD("Two side RTT is: %s", rtt_capabilities.rtt_ftm_supported == 1 ? "support" :
1376 "not support");
1377 ALOGD("LCR is: %s", rtt_capabilities.lcr_support == 1 ? "support" : "not support");
1378
1379 ALOGD("LCI is: %s", rtt_capabilities.lci_support == 1 ? "support" : "not support");
1380
1381 ALOGD("Support Preamble is : %d support BW is %d", rtt_capabilities.preamble_support,
1382 rtt_capabilities.bw_support);
1383 return capabilities;
1384 } else {
1385 return NULL;
1386 }
1387}
1388
xinhe939177f2015-03-23 14:43:03 -07001389static jboolean android_net_wifi_set_Country_Code_Hal(JNIEnv *env,jclass cls, jint iface,
1390 jstring country_code) {
1391
1392 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1393 const char *country = env->GetStringUTFChars(country_code, NULL);
1394
1395 ALOGD("set country code: %s", country);
xinhe62819992015-04-03 11:13:59 -07001396 wifi_error res = hal_fn.wifi_set_country_code(handle, country);
xinhe939177f2015-03-23 14:43:03 -07001397 env->ReleaseStringUTFChars(country_code, country);
1398
1399 return res == WIFI_SUCCESS;
1400}
xinhed57f6302015-04-15 13:23:43 -07001401
1402static jboolean android_net_wifi_enable_disable_tdls(JNIEnv *env,jclass cls, jint iface,
1403 jboolean enable, jstring addr) {
1404 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1405
1406 mac_addr address;
1407 parseMacAddress(env, addr, address);
1408 wifi_tdls_handler tdls_handler;
1409 //tdls_handler.on_tdls_state_changed = &on_tdls_state_changed;
1410
1411 if(enable) {
1412 return (hal_fn.wifi_enable_tdls(handle, address, NULL, tdls_handler) == WIFI_SUCCESS);
1413 } else {
1414 return (hal_fn.wifi_disable_tdls(handle, address) == WIFI_SUCCESS);
1415 }
1416}
1417
1418static void on_tdls_state_changed(mac_addr addr, wifi_tdls_status status) {
1419 JNIEnv *env = NULL;
1420 mVM->AttachCurrentThread(&env, NULL);
1421
1422 ALOGD("on_tdls_state_changed is called: vm = %p, obj = %p, env = %p", mVM, mCls, env);
1423
1424 char mac[32];
1425 sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4],
1426 addr[5]);
1427
1428 jstring mac_address = env->NewStringUTF(mac);
1429 reportEvent(env, mCls, "onTdlsStatus", "(Ljava/lang/StringII;)V",
1430 mac_address, status.state, status.reason);
1431
1432}
1433
1434static jobject android_net_wifi_get_tdls_status(JNIEnv *env,jclass cls, jint iface,jstring addr) {
1435 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1436
1437 mac_addr address;
1438 parseMacAddress(env, addr, address);
1439
1440 wifi_tdls_status status;
1441
1442 wifi_error ret;
1443 ret = hal_fn.wifi_get_tdls_status(handle, address, &status );
1444
1445 if (ret != WIFI_SUCCESS) {
1446 return NULL;
1447 } else {
1448 jobject tdls_status = createObject(env, "com/android/server/wifi/WifiNative$TdlsStatus");
1449 setIntField(env, tdls_status, "channel", status.channel);
1450 setIntField(env, tdls_status, "global_operating_class", status.global_operating_class);
1451 setIntField(env, tdls_status, "state", status.state);
1452 setIntField(env, tdls_status, "reason", status.reason);
1453 return tdls_status;
1454 }
1455}
1456
1457static jobject android_net_wifi_get_tdls_capabilities(JNIEnv *env, jclass cls, jint iface) {
1458 wifi_tdls_capabilities tdls_capabilities;
1459 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1460 wifi_error ret = hal_fn.wifi_get_tdls_capabilities(handle, &tdls_capabilities);
1461
1462 if(WIFI_SUCCESS == ret) {
1463 jobject capabilities = createObject(env,
1464 "com/android/server/wifi/WifiNative$TdlsCapabilities");
1465 setIntField(env, capabilities, "maxConcurrentTdlsSessionNumber",
1466 tdls_capabilities.max_concurrent_tdls_session_num);
1467 setBooleanField(env, capabilities, "isGlobalTdlsSupported",
1468 tdls_capabilities.is_global_tdls_supported == 1);
1469 setBooleanField(env, capabilities, "isPerMacTdlsSupported",
1470 tdls_capabilities.is_per_mac_tdls_supported == 1);
1471 setBooleanField(env,capabilities, "isOffChannelTdlsSupported",
1472 tdls_capabilities.is_off_channel_tdls_supported);
1473
1474 ALOGD("TDLS Max Concurrent Tdls Session Number is: %d",
1475 tdls_capabilities.max_concurrent_tdls_session_num);
1476 ALOGD("Global Tdls is: %s", tdls_capabilities.is_global_tdls_supported == 1 ? "support" :
1477 "not support");
1478 ALOGD("Per Mac Tdls is: %s", tdls_capabilities.is_per_mac_tdls_supported == 1 ? "support" :
1479 "not support");
1480 ALOGD("Off Channel Tdls is: %s", tdls_capabilities.is_off_channel_tdls_supported == 1 ?
1481 "support" : "not support");
1482
1483 return capabilities;
1484 } else {
1485 return NULL;
1486 }
1487}
1488
Vinit Deshpande155b9d02014-01-08 23:46:46 +00001489// ----------------------------------------------------------------------------
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001490// Debug framework
1491// ----------------------------------------------------------------------------
1492
Pierre Vandwalle5faa29d2015-04-10 14:19:41 -07001493static void onRingBufferData(char * ring_name, char * buffer,
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001494int buffer_size, wifi_ring_buffer_status *status) {
1495 JNIEnv *env = NULL;
1496 mVM->AttachCurrentThread(&env, NULL);
1497
1498 ALOGD("onRingBufferData called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
1499
1500 reportEvent(env, mCls, "onDataAvailable", "(I[Landroid/net/wifi/WiFiLogger$LogData;)V",
1501 0, 0);
1502}
1503
xinhe03ba4a52015-04-28 14:40:44 -07001504static jint android_net_wifi_get_supported_logger_feature(JNIEnv *env, jclass cls, jint iface){
1505 //Not implemented yet
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001506 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001507 return -1;
1508}
1509
1510static jobject android_net_wifi_get_driver_version(JNIEnv *env, jclass cls, jint iface) {
1511 //Need to be fixed. The memory should be allocated from lower layer
1512 //char *buffer = NULL;
1513 int buffer_length = 256;
xinhe6d0cd102015-05-05 11:10:08 -07001514 char *buffer = (char *)malloc(buffer_length);
1515 if (!buffer) return NULL;
1516 memset(buffer, 0, buffer_length);
xinhe03ba4a52015-04-28 14:40:44 -07001517 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1518
1519 ALOGD("android_net_wifi_get_driver_version = %p", handle);
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001520
1521 if (handle == 0) {
xinhe03ba4a52015-04-28 14:40:44 -07001522 return NULL;
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001523 }
xinhe03ba4a52015-04-28 14:40:44 -07001524
xinhe6d0cd102015-05-05 11:10:08 -07001525 wifi_error result = hal_fn.wifi_get_driver_version(handle, buffer, buffer_length);
xinhe03ba4a52015-04-28 14:40:44 -07001526
1527 if (result == WIFI_SUCCESS) {
1528 ALOGD("buffer is %p, length is %d", buffer, buffer_length);
1529 jstring driver_version = env->NewStringUTF(buffer);
1530 free(buffer);
1531 return driver_version;
1532 } else {
1533 ALOGD("Fail to get driver version");
1534 return NULL;
1535 }
1536}
1537
1538static jobject android_net_wifi_get_firmware_version(JNIEnv *env, jclass cls, jint iface) {
1539
1540 //char *buffer = NULL;
1541 int buffer_length = 256;
1542 char *buffer = (char *)malloc(buffer_length);
xinhe6d0cd102015-05-05 11:10:08 -07001543 if (!buffer) return NULL;
1544 memset(buffer, 0, buffer_length);
xinhe03ba4a52015-04-28 14:40:44 -07001545 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1546
1547 ALOGD("android_net_wifi_get_firmware_version = %p", handle);
1548
1549 if (handle == 0) {
1550 return NULL;
1551 }
1552
xinhe6d0cd102015-05-05 11:10:08 -07001553 wifi_error result = hal_fn.wifi_get_firmware_version(handle, buffer, buffer_length);
xinhe03ba4a52015-04-28 14:40:44 -07001554
1555 if (result == WIFI_SUCCESS) {
1556 ALOGD("buffer is %p, length is %d", buffer, buffer_length);
1557 jstring firmware_version = env->NewStringUTF(buffer);
1558 free(buffer);
1559 return firmware_version;
1560 } else {
1561 ALOGD("Fail to get Firmware version");
1562 return NULL;
1563 }
1564}
1565
1566static jobject android_net_wifi_get_ring_buffer_status (JNIEnv *env, jclass cls, jint iface) {
1567
1568 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1569
1570 ALOGD(" android_net_wifi_get_ring_buffer_status = %p", handle);
1571
1572 if (handle == 0) {
1573 return NULL;
1574 }
1575
1576 //wifi_ring_buffer_status *status = NULL;
1577 u32 num_rings = 10;
1578 wifi_ring_buffer_status *status =
1579 (wifi_ring_buffer_status *)malloc(sizeof(wifi_ring_buffer_status) * num_rings);
xinhe6d0cd102015-05-05 11:10:08 -07001580 if (!status) return NULL;
1581 memset(status, 0, sizeof(wifi_ring_buffer_status) * num_rings);
1582 wifi_error result = hal_fn.wifi_get_ring_buffers_status(handle, &num_rings, status);
xinhe03ba4a52015-04-28 14:40:44 -07001583 if (result == WIFI_SUCCESS) {
1584 ALOGD("status is %p, number is %d", status, num_rings);
1585 jclass clsRingBufferStatus =
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001586 (env)->FindClass("com/android/server/wifi/WifiNative$RingBufferStatus");
xinhe03ba4a52015-04-28 14:40:44 -07001587 if (clsRingBufferStatus == NULL) {
1588 ALOGE("Error in accessing class");
1589 free(status);
1590 return NULL;
1591 }
1592 jobjectArray ringBuffersStatus = env->NewObjectArray(num_rings,clsRingBufferStatus, NULL);
1593 wifi_ring_buffer_status *tmp = status;
1594
1595 for(u32 i = 0; i < num_rings; i++, tmp++) {
1596 jobject ringStatus = createObject(env,
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001597 "com/android/server/wifi/WifiNative$RingBufferStatus");
xinhe03ba4a52015-04-28 14:40:44 -07001598 if (ringStatus == NULL) {
1599 ALOGE("Error in creating ringBufferStatus");
1600 free(status);
1601 return NULL;
1602 }
1603 char name[32];
1604 for(int j = 0; j < 32; j++) {
1605 name[j] = tmp->name[j];
1606 }
1607 setStringField(env, ringStatus, "name", name);
1608 setIntField(env, ringStatus, "flag", tmp->flags);
1609 setIntField(env, ringStatus, "ringBufferId", tmp->ring_id);
1610 setIntField(env, ringStatus, "ringBufferByteSize", tmp->ring_buffer_byte_size);
1611 setIntField(env, ringStatus, "verboseLevel", tmp->verbose_level);
1612 setIntField(env, ringStatus, "writtenBytes", tmp->written_bytes);
1613 setIntField(env, ringStatus, "readBytes", tmp->read_bytes);
1614 setIntField(env, ringStatus, "writtenRecords", tmp->written_records);
1615 env->SetObjectArrayElement(ringBuffersStatus, i, ringStatus);
1616 }
1617 free(status);
1618 return ringBuffersStatus;
1619 } else {
xinhe6d0cd102015-05-05 11:10:08 -07001620 free(status);
xinhe03ba4a52015-04-28 14:40:44 -07001621 return NULL;
1622 }
1623}
1624
1625static void on_ring_buffer_data(char *ring_name, char *buffer, int buffer_size,
1626 wifi_ring_buffer_status *status) {
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001627
Jerry Lee6111ff72015-05-11 15:10:03 -07001628 if (!ring_name || !buffer || !status ||
1629 (unsigned int)buffer_size <= sizeof(wifi_ring_buffer_entry)) {
xinhe03ba4a52015-04-28 14:40:44 -07001630 ALOGE("Error input for on_ring_buffer_data!");
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001631 return;
xinhe03ba4a52015-04-28 14:40:44 -07001632 }
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001633
xinhe03ba4a52015-04-28 14:40:44 -07001634 JNIEnv *env = NULL;
1635 mVM->AttachCurrentThread(&env, NULL);
1636 ALOGD("on_ring_buffer_data called, vm = %p, obj = %p, env = %p buffer size = %d", mVM,
1637 mCls, env, buffer_size);
1638
xinhe03ba4a52015-04-28 14:40:44 -07001639 jobject ringStatus = createObject(env,
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001640 "com/android/server/wifi/WifiNative$RingBufferStatus");
xinhe03ba4a52015-04-28 14:40:44 -07001641 if (status == NULL) {
1642 ALOGE("Error in creating ringBufferStatus");
1643 return;
1644 }
1645
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001646 setStringField(env, ringStatus, "name", ring_name);
xinhe03ba4a52015-04-28 14:40:44 -07001647 setIntField(env, ringStatus, "flag", status->flags);
1648 setIntField(env, ringStatus, "ringBufferId", status->ring_id);
1649 setIntField(env, ringStatus, "ringBufferByteSize", status->ring_buffer_byte_size);
1650 setIntField(env, ringStatus, "verboseLevel", status->verbose_level);
1651 setIntField(env, ringStatus, "writtenBytes", status->written_bytes);
1652 setIntField(env, ringStatus, "readBytes", status->read_bytes);
1653 setIntField(env, ringStatus, "writtenRecords", status->written_records);
xinhe03ba4a52015-04-28 14:40:44 -07001654
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001655 jbyteArray bytes = env->NewByteArray(buffer_size);
1656 env->SetByteArrayRegion(bytes, 0, buffer_size, (jbyte*)buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001657
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001658 reportEvent(env, mCls,"onRingBufferData",
1659 "(Lcom/android/server/wifi/WifiNative$RingBufferStatus;[B)V", ringStatus, bytes);
1660
1661 env->DeleteLocalRef(bytes);
xinhe03ba4a52015-04-28 14:40:44 -07001662 env->DeleteLocalRef(ringStatus);
xinhe03ba4a52015-04-28 14:40:44 -07001663}
1664
1665static void on_alert_data(wifi_request_id id, char *buffer, int buffer_size, int err_code){
1666 JNIEnv *env = NULL;
1667 mVM->AttachCurrentThread(&env, NULL);
1668 ALOGD(" on_alert_data called, vm = %p, obj = %p, env = %p buffer_size = %d, error code = %d"
1669 , mVM, mCls, env, buffer_size, err_code);
1670
1671 if (buffer_size > 0) {
1672 jbyteArray records = env->NewByteArray(buffer_size);
1673 jbyte *bytes = (jbyte *) buffer;
1674 env->SetByteArrayRegion(records, 0,buffer_size, bytes);
1675 reportEvent(env, mCls,"onWifiAlert","([B;I)V", records, err_code);
1676 env->DeleteLocalRef(records);
1677 } else {
1678 reportEvent(env, mCls,"onWifiAlert","([B;I)V", NULL, err_code);
1679 }
1680}
1681
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07001682
xinhe03ba4a52015-04-28 14:40:44 -07001683static jboolean android_net_wifi_start_logging_ring_buffer(JNIEnv *env, jclass cls, jint iface,
1684 jint verbose_level,jint flags, jint max_interval,jint min_data_size, jstring ring_name) {
1685
1686 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1687
1688 ALOGD("android_net_wifi_start_logging_ring_buffer = %p", handle);
1689
1690 if (handle == 0) {
1691 return false;
1692 }
1693
1694 //set logging handler
1695
1696 //initialize the handler on first time
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001697 wifi_ring_buffer_data_handler handler;
xinhe03ba4a52015-04-28 14:40:44 -07001698 handler.on_ring_buffer_data = &on_ring_buffer_data;
1699 int result = hal_fn.wifi_set_log_handler(0, handle, handler);
1700 if (result != WIFI_SUCCESS) {
1701 ALOGE("Fail to set logging handler");
1702 return false;
1703 } else {
1704 ALOGE(" Successfully set on_ring_buffer_data");
1705 }
1706 //set alter handler
1707 wifi_alert_handler alert_handler;
1708 alert_handler.on_alert = &on_alert_data;
1709 result = hal_fn.wifi_set_alert_handler(0, handle, alert_handler);
1710 if (result != WIFI_SUCCESS) {
1711 ALOGE(" Fail to set logging handler");
1712 return false;
1713 } else {
1714 ALOGE(" Successfully set on_alert");
1715 }
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001716
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001717
xinhe03ba4a52015-04-28 14:40:44 -07001718 const char* ring_name_const_char = env->GetStringUTFChars(ring_name, JNI_FALSE);
1719 int len;
1720 for(len = 0; ring_name_const_char[len] != 0; len++);
1721
1722 char* ring_name_char = (char*) malloc(len+1);
1723 memcpy(ring_name_char, ring_name_const_char, len+1);
1724
1725 int ret = hal_fn.wifi_start_logging(handle, verbose_level, flags, max_interval, min_data_size,
1726 ring_name_char);
1727
1728 if (ret != WIFI_SUCCESS) {
1729 ALOGE("Fail to start logging for ring %s", ring_name);
1730 } else {
1731 ALOGD("start logging for ring %s", ring_name);
1732 }
1733 env->ReleaseStringUTFChars(ring_name, ring_name_char);
1734 return ret == WIFI_SUCCESS;
1735}
1736
1737static jboolean android_net_wifi_get_ring_buffer_data(JNIEnv *env, jclass cls, jint iface,
1738 jstring ring_name) {
1739 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1740 ALOGD("android_net_wifi_get_ring_buffer_data = %p", handle);
1741
1742
1743 const char* ring_name_const_char = env->GetStringUTFChars(ring_name, JNI_FALSE);
1744 int len;
1745 for(len = 0; ring_name_const_char[len] != 0; len++);
1746 char* ring_name_char = (char*) malloc(len+1);
1747 memcpy(ring_name_char, ring_name_const_char, len+1);
1748
1749 int result = hal_fn.wifi_get_ring_data(handle, ring_name_char);
1750
1751 if (result == WIFI_SUCCESS)
1752 ALOGD("Get Ring data command success\n");
1753 else
1754 ALOGE("Failed to execute get ring data command\n");
1755
1756 env->ReleaseStringUTFChars(ring_name, ring_name_char);
1757 return result == WIFI_SUCCESS;
1758}
1759
1760
1761void on_firmware_memory_dump(char *buffer, int buffer_size) {
1762 JNIEnv *env = NULL;
1763 mVM->AttachCurrentThread(&env, NULL);
1764 ALOGD("on_firmware_memory_dump called, vm = %p, obj = %p, env = %p buffer_size = %d"
1765 , mVM, mCls, env, buffer_size);
1766
1767 if (buffer_size > 0) {
1768 jbyteArray dump = env->NewByteArray(buffer_size);
1769 jbyte *bytes = (jbyte *) (buffer);
1770 env->SetByteArrayRegion(dump, 0, buffer_size, bytes);
1771 reportEvent(env, mCls,"onWifiFwMemoryAvailable","([B)V", dump);
1772 env->DeleteLocalRef(dump);
1773 }
1774
1775}
1776
1777static jboolean android_net_wifi_get_fw_memory_dump(JNIEnv *env, jclass cls, jint iface){
1778 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1779 ALOGD("android_net_wifi_get_fw_memory_dump = %p", handle);
1780
1781 if (handle == NULL) {
1782 ALOGE("Can not get wifi_interface_handle");
1783 return false;
1784 }
1785
1786 wifi_firmware_memory_dump_handler fw_dump_handle;
1787 fw_dump_handle.on_firmware_memory_dump = on_firmware_memory_dump;
1788 int result = hal_fn.wifi_get_firmware_memory_dump(handle, fw_dump_handle);
1789 return result == WIFI_SUCCESS;
1790
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001791}
1792
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001793// ----------------------------------------------------------------------------
1794// ePno framework
1795// ----------------------------------------------------------------------------
1796
1797
1798static void onPnoNetworkFound(wifi_request_id id,
1799 unsigned num_results, wifi_scan_result *results) {
1800 JNIEnv *env = NULL;
1801 mVM->AttachCurrentThread(&env, NULL);
1802
1803 ALOGD("onPnoNetworkFound called, vm = %p, obj = %p, env = %p, num_results %u",
1804 mVM, mCls, env, num_results);
1805
1806 if (results == 0 || num_results == 0) {
1807 ALOGE("onPnoNetworkFound: Error no results");
1808 return;
1809 }
1810
1811 jobject scanResult;
1812 jbyte *bytes;
1813 jobjectArray scanResults;
1814 //jbyteArray elements;
1815
1816 for (unsigned i=0; i<num_results; i++) {
1817
1818 scanResult = createScanResult(env, &results[i]);
1819 if (i == 0) {
1820 scanResults = env->NewObjectArray(num_results,
1821 env->FindClass("android/net/wifi/ScanResult"), scanResult);
1822 if (scanResults == 0) {
1823 ALOGD("cant allocate array");
1824 } else {
1825 ALOGD("allocated array %u", env->GetArrayLength(scanResults));
1826 }
1827 } else {
1828 env->SetObjectArrayElement(scanResults, i, scanResult);
1829 }
1830
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07001831 ALOGD("Scan result with ie length %d, i %u, <%s> rssi=%d %02x:%02x:%02x:%02x:%02x:%02x",
xinhe6d0cd102015-05-05 11:10:08 -07001832 results->ie_length, i, results[i].ssid, results[i].rssi, results[i].bssid[0],
1833 results[i].bssid[1],results[i].bssid[2], results[i].bssid[3], results[i].bssid[4],
1834 results[i].bssid[5]);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001835
1836 /*elements = env->NewByteArray(results->ie_length);
1837 if (elements == NULL) {
1838 ALOGE("Error in allocating array");
1839 return;
1840 }*/
1841
1842 //ALOGD("onPnoNetworkFound: Setting byte array");
1843
1844 //bytes = (jbyte *)&(results->ie_data[0]);
1845 //env->SetByteArrayRegion(elements, 0, results->ie_length, bytes);
1846
1847 //ALOGD("onPnoNetworkFound: Returning result");
1848 }
1849
1850
1851 ALOGD("calling report");
1852
1853 reportEvent(env, mCls, "onPnoNetworkFound", "(I[Landroid/net/wifi/ScanResult;)V", id,
1854 scanResults);
1855 ALOGD("free ref");
1856
1857 env->DeleteLocalRef(scanResults);
1858 //env->DeleteLocalRef(elements);
1859}
1860
1861static jboolean android_net_wifi_setPnoListNative(
1862 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {
1863
1864 wifi_epno_handler handler;
1865 handler.on_network_found = &onPnoNetworkFound;
1866
1867 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1868 ALOGD("configure ePno list request [%d] = %p", id, handle);
1869
1870 if (list == NULL) {
1871 // stop pno
1872 int result = hal_fn.wifi_set_epno_list(id, handle, 0, NULL, handler);
1873 ALOGE(" setPnoListNative: STOP result = %d", result);
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07001874 return result >= 0;
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001875 }
1876
1877 wifi_epno_network net_list[MAX_PNO_SSID];
1878 memset(&net_list, 0, sizeof(net_list));
1879
1880 size_t len = env->GetArrayLength((jobjectArray)list);
1881 if (len > (size_t)MAX_PNO_SSID) {
1882 return false;
1883 }
1884
1885 for (unsigned int i = 0; i < len; i++) {
1886
1887 jobject pno_net = env->GetObjectArrayElement((jobjectArray)list, i);
1888 if (pno_net == NULL) {
1889 ALOGD("setPnoListNative: could not get element %d", i);
1890 continue;
1891 }
1892
1893 jstring sssid = (jstring) getObjectField(
1894 env, pno_net, "SSID", "Ljava/lang/String;");
1895 if (sssid == NULL) {
1896 ALOGE("Error setPnoListNative: getting ssid field");
1897 return false;
1898 }
1899
1900 const char *ssid = env->GetStringUTFChars(sssid, NULL);
1901 if (ssid == NULL) {
1902 ALOGE("Error setPnoListNative: getting ssid");
1903 return false;
1904 }
1905 int ssid_len = strnlen((const char*)ssid, 33);
1906 if (ssid_len > 32) {
1907 ALOGE("Error setPnoListNative: long ssid %u", strnlen((const char*)ssid, 256));
1908 return false;
1909 }
1910 if (ssid_len > 1 && ssid[0] == '"' && ssid[ssid_len-1])
1911 {
1912 // strip leading and trailing '"'
1913 ssid++;
1914 ssid_len-=2;
1915 }
1916 if (ssid_len == 0) {
1917 ALOGE("Error setPnoListNative: zero length ssid, skip it");
1918 continue;
1919 }
1920 memcpy(net_list[i].ssid, ssid, ssid_len);
1921
1922 int rssit = getIntField(env, pno_net, "rssi_threshold");
1923 net_list[i].rssi_threshold = (byte)rssit;
1924 int a = getIntField(env, pno_net, "auth");
1925 net_list[i].auth_bit_field = a;
1926 int f = getIntField(env, pno_net, "flags");
1927 net_list[i].flags = f;
xinhe03ba4a52015-04-28 14:40:44 -07001928 ALOGE(" setPnoListNative: idx %u rssi %d/%d auth %x/%x flags %x/%x [%s]", i,
1929 (signed byte)net_list[i].rssi_threshold, net_list[i].rssi_threshold,
1930 net_list[i].auth_bit_field, a, net_list[i].flags, f, net_list[i].ssid);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001931 }
1932
1933 int result = hal_fn.wifi_set_epno_list(id, handle, len, net_list, handler);
1934 ALOGE(" setPnoListNative: result %d", result);
1935
1936 return result >= 0;
1937}
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001938
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07001939static jboolean android_net_wifi_setLazyRoam(
1940 JNIEnv *env, jclass cls, jint iface, jint id, jboolean enabled, jobject roam_param) {
1941
Vinit Deshpandef49a59b2015-05-27 11:24:47 -07001942 wifi_error status = WIFI_SUCCESS;
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07001943 wifi_roam_params params;
1944 memset(&params, 0, sizeof(params));
1945
1946 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
1947 ALOGD("configure lazy roam request [%d] = %p", id, handle);
1948
1949 if (roam_param != NULL) {
1950 params.A_band_boost_threshold = getIntField(env, roam_param, "A_band_boost_threshold");
1951 params.A_band_penalty_threshold = getIntField(env, roam_param, "A_band_penalty_threshold");
1952 params.A_band_boost_factor = getIntField(env, roam_param, "A_band_boost_factor");
1953 params.A_band_penalty_factor = getIntField(env, roam_param, "A_band_penalty_factor");
1954 params.A_band_max_boost = getIntField(env, roam_param, "A_band_max_boost");
1955 params.lazy_roam_hysteresis = getIntField(env, roam_param, "lazy_roam_hysteresis");
1956 params.alert_roam_rssi_trigger = getIntField(env, roam_param, "alert_roam_rssi_trigger");
1957 status = hal_fn.wifi_set_gscan_roam_params(id, handle, &params);
1958 }
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07001959 ALOGE("android_net_wifi_setLazyRoam configured params status=%d\n", status);
1960
1961 if (status >= 0) {
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07001962 int doEnable = enabled ? 1 : 0;
1963 status = hal_fn.wifi_enable_lazy_roam(id, handle, doEnable);
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07001964 ALOGE("android_net_wifi_setLazyRoam enabled roam status=%d\n", status);
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07001965 }
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07001966 return status >= 0;
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07001967}
1968
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07001969static jboolean android_net_wifi_setBssidBlacklist(
1970 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {
1971
1972 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07001973 ALOGD("configure BSSID black list request [%d] = %p", id, handle);
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07001974
1975 wifi_bssid_params params;
1976 memset(&params, 0, sizeof(params));
1977
1978 if (list != NULL) {
1979 size_t len = env->GetArrayLength((jobjectArray)list);
1980 if (len > (size_t)MAX_BLACKLIST_BSSID) {
1981 return false;
1982 }
1983 for (unsigned int i = 0; i < len; i++) {
1984
1985 jstring jbssid = (jstring)env->GetObjectArrayElement((jobjectArray)list, i);
1986 if (jbssid == NULL) {
1987 ALOGD("configure BSSID blacklist: could not get element %d", i);
1988 continue;
1989 }
1990 const char *bssid = env->GetStringUTFChars(jbssid, NULL);
1991 if (bssid == NULL) {
1992 ALOGE("Error getting bssid");
1993 return false;
1994 }
1995
1996 mac_addr addr;
1997 parseMacAddress(bssid, addr);
1998 memcpy(params.bssids[i], addr, sizeof(mac_addr));
1999
2000 char bssidOut[32];
2001 sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1],
2002 addr[2], addr[3], addr[4], addr[5]);
2003
2004 ALOGD("BSSID blacklist: added bssid %s", bssidOut);
2005
2006 params.num_bssid++;
2007
2008 }
2009 }
2010
2011 ALOGD("Added %d bssids", params.num_bssid);
2012 return hal_fn.wifi_set_bssid_blacklist(id, handle, params) == WIFI_SUCCESS;
2013}
2014
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002015static jboolean android_net_wifi_setSsidWhitelist(
2016 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {
2017
2018 wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
2019 ALOGD("configure SSID white list request [%d] = %p", id, handle);
2020 wifi_ssid *ssids = NULL;
2021 int num_ssids = 0;
2022 if (list != NULL) {
2023 size_t len = env->GetArrayLength((jobjectArray)list);
2024 if (len > 0) {
2025 ssids = (wifi_ssid *)malloc(len * sizeof (wifi_ssid));
2026 if (!ssids) return false;
2027 memset(ssids, 0, len * sizeof (wifi_ssid));
2028 for (unsigned int i = 0; i < len; i++) {
2029
2030 jstring jssid = (jstring)env->GetObjectArrayElement((jobjectArray)list, i);
2031 if (jssid == NULL) {
2032 ALOGD("configure SSID whitelist: could not get element %d", i);
2033 free(ssids);
2034 return false;
2035 }
2036 const char *ssid = env->GetStringUTFChars(jssid, NULL);
2037 if (ssid == NULL) {
2038 ALOGE("Error getting sssid");
2039 free(ssids);
2040 return false;
2041 }
2042 int slen = strnlen(ssid, 33);
2043 if (slen <= 0 || slen > 32) {
2044 ALOGE("Error wrong ssid length %d", slen);
2045 free(ssids);
2046 return false;
2047 }
2048
2049 memcpy(ssids[i].ssid, ssid, slen);
Pierre Vandwallebe2981a2015-05-20 18:20:45 -07002050 num_ssids++;
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002051 ALOGD("SSID white list: added ssid %s", ssid);
2052 }
2053 }
2054 }
2055
2056 ALOGD("android_net_wifi_setSsidWhitelist Added %d sssids", num_ssids);
2057 return hal_fn.wifi_set_ssid_white_list(id, handle, num_ssids, ssids) == WIFI_SUCCESS;
2058}
2059
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07002060// ----------------------------------------------------------------------------
Vinit Deshpande155b9d02014-01-08 23:46:46 +00002061
2062/*
2063 * JNI registration.
2064 */
2065static JNINativeMethod gWifiMethods[] = {
2066 /* name, signature, funcPtr */
2067
2068 { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
2069 { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded },
2070 { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
2071 { "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant },
2072 { "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant },
2073 { "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant },
2074 { "closeSupplicantConnectionNative", "()V",
2075 (void *)android_net_wifi_closeSupplicantConnection },
2076 { "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForEvent },
2077 { "doBooleanCommandNative", "(Ljava/lang/String;)Z", (void*)android_net_wifi_doBooleanCommand },
2078 { "doIntCommandNative", "(Ljava/lang/String;)I", (void*)android_net_wifi_doIntCommand },
2079 { "doStringCommandNative", "(Ljava/lang/String;)Ljava/lang/String;",
2080 (void*) android_net_wifi_doStringCommand },
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -08002081 { "startHalNative", "()Z", (void*) android_net_wifi_startHal },
2082 { "stopHalNative", "()V", (void*) android_net_wifi_stopHal },
2083 { "waitForHalEventNative", "()V", (void*) android_net_wifi_waitForHalEvents },
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07002084 { "getInterfacesNative", "()I", (void*) android_net_wifi_getInterfaces},
2085 { "getInterfaceNameNative", "(I)Ljava/lang/String;", (void*) android_net_wifi_getInterfaceName},
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002086 { "getScanCapabilitiesNative", "(ILcom/android/server/wifi/WifiNative$ScanCapabilities;)Z",
2087 (void *) android_net_wifi_getScanCapabilities},
2088 { "startScanNative", "(IILcom/android/server/wifi/WifiNative$ScanSettings;)Z",
2089 (void*) android_net_wifi_startScan},
2090 { "stopScanNative", "(II)Z", (void*) android_net_wifi_stopScan},
Vinit Deshpande83a674a2014-10-31 11:15:26 -07002091 { "getScanResultsNative", "(IZ)[Landroid/net/wifi/WifiScanner$ScanData;",
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002092 (void *) android_net_wifi_getScanResults},
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002093 { "setHotlistNative", "(IILandroid/net/wifi/WifiScanner$HotlistSettings;)Z",
2094 (void*) android_net_wifi_setHotlist},
2095 { "resetHotlistNative", "(II)Z", (void*) android_net_wifi_resetHotlist},
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002096 { "trackSignificantWifiChangeNative", "(IILandroid/net/wifi/WifiScanner$WifiChangeSettings;)Z",
2097 (void*) android_net_wifi_trackSignificantWifiChange},
2098 { "untrackSignificantWifiChangeNative", "(II)Z",
vandwalleaabe7a92014-05-09 18:11:02 -07002099 (void*) android_net_wifi_untrackSignificantWifiChange},
2100 { "getWifiLinkLayerStatsNative", "(I)Landroid/net/wifi/WifiLinkLayerStats;",
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07002101 (void*) android_net_wifi_getLinkLayerStats},
Vinit Deshpandec35361d2014-08-07 16:24:10 -07002102 { "getSupportedFeatureSetNative", "(I)I",
Vinit Deshpande14365732014-06-30 15:23:23 -07002103 (void*) android_net_wifi_getSupportedFeatures},
2104 { "requestRangeNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z",
2105 (void*) android_net_wifi_requestRange},
2106 { "cancelRangeRequestNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z",
Vinit Deshpande042c54b2014-08-21 13:52:21 -07002107 (void*) android_net_wifi_cancelRange},
Vinit Deshpande0465ff52014-10-13 13:21:47 -07002108 { "setScanningMacOuiNative", "(I[B)Z", (void*) android_net_wifi_setScanningMacOui},
2109 { "getChannelsForBandNative", "(II)[I", (void*) android_net_wifi_getValidChannels},
xinheb830d762015-02-11 17:14:17 -08002110 { "setDfsFlagNative", "(IZ)Z", (void*) android_net_wifi_setDfsFlag},
xinhe12cf3882015-03-12 18:38:54 -07002111 { "toggleInterfaceNative", "(I)Z", (void*) android_net_wifi_toggle_interface},
2112 { "getRttCapabilitiesNative", "(I)Landroid/net/wifi/RttManager$RttCapabilities;",
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07002113 (void*) android_net_wifi_get_rtt_capabilities},
xinhe939177f2015-03-23 14:43:03 -07002114 {"setCountryCodeHalNative", "(ILjava/lang/String;)Z",
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07002115 (void*) android_net_wifi_set_Country_Code_Hal},
2116 { "setPnoListNative", "(II[Lcom/android/server/wifi/WifiNative$WifiPnoNetwork;)Z",
xinhed57f6302015-04-15 13:23:43 -07002117 (void*) android_net_wifi_setPnoListNative},
2118 {"enableDisableTdlsNative", "(IZLjava/lang/String;)Z",
2119 (void*) android_net_wifi_enable_disable_tdls},
2120 {"getTdlsStatusNative", "(ILjava/lang/String;)Lcom/android/server/wifi/WifiNative$TdlsStatus;",
2121 (void*) android_net_wifi_get_tdls_status},
2122 {"getTdlsCapabilitiesNative", "(I)Lcom/android/server/wifi/WifiNative$TdlsCapabilities;",
xinhe03ba4a52015-04-28 14:40:44 -07002123 (void*) android_net_wifi_get_tdls_capabilities},
2124 {"getSupportedLoggerFeatureSetNative","(I)I",
2125 (void*) android_net_wifi_get_supported_logger_feature},
2126 {"getDriverVersionNative", "(I)Ljava/lang/String;",
2127 (void*) android_net_wifi_get_driver_version},
2128 {"getFirmwareVersionNative", "(I)Ljava/lang/String;",
2129 (void*) android_net_wifi_get_firmware_version},
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07002130 {"getRingBufferStatusNative", "(I)[Lcom/android/server/wifi/WifiNative$RingBufferStatus;",
xinhe03ba4a52015-04-28 14:40:44 -07002131 (void*) android_net_wifi_get_ring_buffer_status},
2132 {"startLoggingRingBufferNative", "(IIIIILjava/lang/String;)Z",
2133 (void*) android_net_wifi_start_logging_ring_buffer},
2134 {"getRingBufferDataNative", "(ILjava/lang/String;)Z",
2135 (void*) android_net_wifi_get_ring_buffer_data},
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002136 {"getFwMemoryDumpNative","(I)Z", (void*) android_net_wifi_get_fw_memory_dump},
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002137 { "setLazyRoamNative", "(IIZLcom/android/server/wifi/WifiNative$WifiLazyRoamParams;)Z",
2138 (void*) android_net_wifi_setLazyRoam},
2139 { "setBssidBlacklistNative", "(II[Ljava/lang/String;)Z",
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002140 (void*)android_net_wifi_setBssidBlacklist},
2141 { "setSsidWhitelistNative", "(II[Ljava/lang/String;)Z",
2142 (void*)android_net_wifi_setSsidWhitelist}
Vinit Deshpande155b9d02014-01-08 23:46:46 +00002143};
2144
2145int register_android_net_wifi_WifiNative(JNIEnv* env) {
2146 return AndroidRuntime::registerNativeMethods(env,
2147 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods));
2148}
2149
2150
2151/* User to register native functions */
2152extern "C"
2153jint Java_com_android_server_wifi_WifiNative_registerNatives(JNIEnv* env, jclass clazz) {
2154 return AndroidRuntime::registerNativeMethods(env,
2155 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods));
2156}
2157
2158}; // namespace android