blob: a2912a9bbc7c6d22f1ac7f34181da3f99787cd60 [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"
Vinit Deshpande7d519b62015-08-04 16:43:09 -070020#include "JniConstants.h"
Vinit Deshpande155b9d02014-01-08 23:46:46 +000021#include <ScopedUtfChars.h>
Vinit Deshpande7d519b62015-08-04 16:43:09 -070022#include <ScopedBytes.h>
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +053023//#include <utils/misc.h>
Vinit Deshpande155b9d02014-01-08 23:46:46 +000024#include <android_runtime/AndroidRuntime.h>
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +053025//#include <utils/Log.h>
26//#include <utils/String16.h>
Vinit Deshapndee4e37502014-05-05 11:32:21 -070027#include <ctype.h>
xinhebe3b27a2015-01-30 17:56:24 -080028#include <sys/socket.h>
29#include <linux/if.h>
Vinit Deshpande155b9d02014-01-08 23:46:46 +000030#include "wifi.h"
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -080031#include "wifi_hal.h"
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -070032#include "jni_helper.h"
xinhe12cf3882015-03-12 18:38:54 -070033#include "rtt.h"
xinheec61e772015-03-30 18:39:12 -070034#include "wifi_hal_stub.h"
Vinit Deshpande155b9d02014-01-08 23:46:46 +000035#define REPLY_BUF_SIZE 4096 // wpa_supplicant's maximum size.
36#define EVENT_BUF_SIZE 2048
37
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +053038#define CONVERT_LINE_LEN 2048
39#define CHARSET_CN ("gbk")
40
41#include "com_android_server_wifi_Gbk2Utf.h"
42
Vinit Deshpande155b9d02014-01-08 23:46:46 +000043namespace android {
44
45static jint DBG = false;
46
xinheec61e772015-03-30 18:39:12 -070047//Please put all HAL function call here and call from the function table instead of directly call
48static wifi_hal_fn hal_fn;
49int init_wifi_hal_func_table(wifi_hal_fn *hal_fn) {
50 if (hal_fn == NULL) {
51 return -1;
52 }
53 hal_fn->wifi_initialize = wifi_initialize_stub;
54 hal_fn->wifi_cleanup = wifi_cleanup_stub;
55 hal_fn->wifi_event_loop = wifi_event_loop_stub;
56 hal_fn->wifi_get_error_info = wifi_get_error_info_stub;
57 hal_fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set_stub;
58 hal_fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix_stub;
59 hal_fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui_stub;
60 hal_fn->wifi_get_supported_channels = wifi_get_supported_channels_stub;
61 hal_fn->wifi_is_epr_supported = wifi_is_epr_supported_stub;
62 hal_fn->wifi_get_ifaces = wifi_get_ifaces_stub;
63 hal_fn->wifi_get_iface_name = wifi_get_iface_name_stub;
64 hal_fn->wifi_reset_iface_event_handler = wifi_reset_iface_event_handler_stub;
65 hal_fn->wifi_start_gscan = wifi_start_gscan_stub;
66 hal_fn->wifi_stop_gscan = wifi_stop_gscan_stub;
xin He6f7fe1c2015-04-02 21:10:12 +000067 hal_fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results_stub;
xinheec61e772015-03-30 18:39:12 -070068 hal_fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist_stub;
69 hal_fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist_stub;
70 hal_fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler_stub;
71 hal_fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler_stub;
72 hal_fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities_stub;
73 hal_fn->wifi_set_link_stats = wifi_set_link_stats_stub;
74 hal_fn->wifi_get_link_stats = wifi_get_link_stats_stub;
75 hal_fn->wifi_clear_link_stats = wifi_clear_link_stats_stub;
76 hal_fn->wifi_get_valid_channels = wifi_get_valid_channels_stub;
77 hal_fn->wifi_rtt_range_request = wifi_rtt_range_request_stub;
78 hal_fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel_stub;
79 hal_fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities_stub;
xinheec61e772015-03-30 18:39:12 -070080 hal_fn->wifi_start_logging = wifi_start_logging_stub;
81 hal_fn->wifi_set_epno_list = wifi_set_epno_list_stub;
82 hal_fn->wifi_set_country_code = wifi_set_country_code_stub;
xinhed57f6302015-04-15 13:23:43 -070083 hal_fn->wifi_enable_tdls = wifi_enable_tdls_stub;
84 hal_fn->wifi_disable_tdls = wifi_disable_tdls_stub;
85 hal_fn->wifi_get_tdls_status = wifi_get_tdls_status_stub;
86 hal_fn->wifi_get_tdls_capabilities = wifi_get_tdls_capabilities_stub;
Vinit Deshpande6f59b022015-05-05 11:39:47 -070087 hal_fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag_stub;
xinhe21602b32015-04-24 09:32:13 -070088 hal_fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump_stub;
89 hal_fn->wifi_set_log_handler = wifi_set_log_handler_stub;
JerryLee32cbc7a2015-06-17 19:19:30 -070090 hal_fn->wifi_reset_log_handler = wifi_reset_log_handler_stub;
xinhe21602b32015-04-24 09:32:13 -070091 hal_fn->wifi_set_alert_handler = wifi_set_alert_handler_stub;
Jerry Lee370ad502015-07-13 13:42:21 -070092 hal_fn->wifi_reset_alert_handler = wifi_reset_alert_handler_stub;
xinhe21602b32015-04-24 09:32:13 -070093 hal_fn->wifi_get_firmware_version = wifi_get_firmware_version_stub;
94 hal_fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status_stub;
95 hal_fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set_stub;
96 hal_fn->wifi_get_ring_data = wifi_get_ring_data_stub;
97 hal_fn->wifi_get_driver_version = wifi_get_driver_version_stub;
Vinit Deshpandee5bf4b82015-05-13 18:38:10 -070098 hal_fn->wifi_set_ssid_white_list = wifi_set_ssid_white_list_stub;
99 hal_fn->wifi_set_gscan_roam_params = wifi_set_gscan_roam_params_stub;
100 hal_fn->wifi_set_bssid_preference = wifi_set_bssid_preference_stub;
101 hal_fn->wifi_enable_lazy_roam = wifi_enable_lazy_roam_stub;
102 hal_fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist_stub;
Ecco Park2723d992015-06-18 17:08:23 -0700103 hal_fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet_stub;
104 hal_fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet_stub;
xinheec61e772015-03-30 18:39:12 -0700105 return 0;
106}
107
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530108extern struct accessPointObjectItem *g_pItemList;
109extern struct accessPointObjectItem *g_pLastNode;
110extern pthread_mutex_t *g_pItemListMutex;
111extern String8 *g_pCurrentSSID;
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000112static bool doCommand(JNIEnv* env, jstring javaCommand,
113 char* reply, size_t reply_len) {
114 ScopedUtfChars command(env, javaCommand);
115 if (command.c_str() == NULL) {
116 return false; // ScopedUtfChars already threw on error.
117 }
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530118 if(strstr(command.c_str(), "SET_NETWORK")) {
119 if(!setNetworkVariable((char *)command.c_str())) {
120 return false;
121 }
122 }
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000123 if (DBG) {
124 ALOGD("doCommand: %s", command.c_str());
125 }
126
127 --reply_len; // Ensure we have room to add NUL termination.
128 if (::wifi_command(command.c_str(), reply, &reply_len) != 0) {
129 return false;
130 }
131
132 // Strip off trailing newline.
133 if (reply_len > 0 && reply[reply_len-1] == '\n') {
134 reply[reply_len-1] = '\0';
135 } else {
136 reply[reply_len] = '\0';
137 }
138 return true;
139}
140
141static jint doIntCommand(JNIEnv* env, jstring javaCommand) {
142 char reply[REPLY_BUF_SIZE];
143 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
144 return -1;
145 }
146 return static_cast<jint>(atoi(reply));
147}
148
149static jboolean doBooleanCommand(JNIEnv* env, jstring javaCommand) {
150 char reply[REPLY_BUF_SIZE];
151 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
152 return JNI_FALSE;
153 }
154 return (strcmp(reply, "OK") == 0);
155}
156
157// Send a command to the supplicant, and return the reply as a String.
158static jstring doStringCommand(JNIEnv* env, jstring javaCommand) {
159 char reply[REPLY_BUF_SIZE];
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530160 ScopedUtfChars command(env, javaCommand);
161 if (command.c_str() == NULL) {
162 return NULL;
163 }
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000164 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
165 return NULL;
166 }
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530167 if (DBG) ALOGD("cmd = %s, reply: %s", command.c_str(), reply);
168 String16 str;
169 if (strstr(command.c_str(),"BSS RANGE=")) {
170 parseScanResults(str,reply);
171 } else if (strstr(command.c_str(),"GET_NETWORK") &&
172 strstr(command.c_str(),"ssid") && !strstr(command.c_str(),"bssid")
173 && !strstr(command.c_str(),"scan_ssid")){
174 constructSsid(str, reply);
175 } else {
176 str += String16((char *)reply);
177 }
178 return env->NewString((const jchar *)str.string(), str.size());
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000179}
180
181static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject)
182{
183 return (::is_wifi_driver_loaded() == 1);
184}
185
186static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
187{
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530188 g_pItemListMutex = new pthread_mutex_t;
189 if (NULL == g_pItemListMutex) {
190 ALOGE("Failed to allocate memory for g_pItemListMutex!");
191 return JNI_FALSE;
192 }
193 pthread_mutex_init(g_pItemListMutex, NULL);
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000194 return (::wifi_load_driver() == 0);
195}
196
197static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
198{
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530199 if (g_pItemListMutex != NULL) {
200 pthread_mutex_lock(g_pItemListMutex);
201 struct accessPointObjectItem *pCurrentNode = g_pItemList;
202 struct accessPointObjectItem *pNextNode = NULL;
203 while (pCurrentNode) {
204 pNextNode = pCurrentNode->pNext;
205 if (NULL != pCurrentNode->ssid) {
206 delete pCurrentNode->ssid;
207 pCurrentNode->ssid = NULL;
208 }
209 if (NULL != pCurrentNode->ssid_utf8) {
210 delete pCurrentNode->ssid_utf8;
211 pCurrentNode->ssid_utf8 = NULL;
212 }
213 delete pCurrentNode;
214 pCurrentNode = pNextNode;
215 }
216 g_pItemList = NULL;
217 g_pLastNode = NULL;
218 pthread_mutex_unlock(g_pItemListMutex);
219 pthread_mutex_destroy(g_pItemListMutex);
220 delete g_pItemListMutex;
221 g_pItemListMutex = NULL;
222 }
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000223 return (::wifi_unload_driver() == 0);
224}
225
226static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
227{
228 return (::wifi_start_supplicant(p2pSupported) == 0);
229}
230
231static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
232{
233 return (::wifi_stop_supplicant(p2pSupported) == 0);
234}
235
236static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject)
237{
238 return (::wifi_connect_to_supplicant() == 0);
239}
240
241static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject)
242{
243 ::wifi_close_supplicant_connection();
244}
245
246static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject)
247{
248 char buf[EVENT_BUF_SIZE];
249 int nread = ::wifi_wait_for_event(buf, sizeof buf);
250 if (nread > 0) {
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530251 if (strstr(buf, " SSID=") || strstr(buf, " SSID ")){
252 constructEventSsid(buf);
253 }
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000254 return env->NewStringUTF(buf);
255 } else {
256 return NULL;
257 }
258}
259
260static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) {
261 return doBooleanCommand(env, javaCommand);
262}
263
264static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) {
265 return doIntCommand(env, javaCommand);
266}
267
268static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) {
269 return doStringCommand(env,javaCommand);
270}
271
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700272/* wifi_hal <==> WifiNative bridge */
273
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700274static jclass mCls; /* saved WifiNative object */
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700275static JavaVM *mVM; /* saved JVM pointer */
276
vandwalleaabe7a92014-05-09 18:11:02 -0700277static const char *WifiHandleVarName = "sWifiHalHandle";
278static const char *WifiIfaceHandleVarName = "sWifiIfaceHandles";
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700279static jmethodID OnScanResultsMethodID;
280
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700281static wifi_handle getWifiHandle(JNIHelper &helper, jclass cls) {
282 return (wifi_handle) helper.getStaticLongField(cls, WifiHandleVarName);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700283}
284
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700285static wifi_interface_handle getIfaceHandle(JNIHelper &helper, jclass cls, jint index) {
286 return (wifi_interface_handle) helper.getStaticLongArrayField(cls, WifiIfaceHandleVarName, index);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700287}
288
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700289jboolean setSSIDField(JNIHelper helper, jobject scanResult, const char *rawSsid) {
xinhe5cfd8d82015-07-28 16:34:37 -0700290
291 int len = strlen(rawSsid);
292
293 if (len > 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700294 JNIObject<jbyteArray> ssidBytes = helper.newByteArray(len);
295 helper.setByteArrayRegion(ssidBytes, 0, len, (jbyte *) rawSsid);
296 jboolean ret = helper.callStaticMethod(mCls,
297 "setSsid", "([BLandroid/net/wifi/ScanResult;)Z", ssidBytes.get(), scanResult);
xinhe5cfd8d82015-07-28 16:34:37 -0700298 return ret;
299 } else {
300 //empty SSID or SSID start with \0
301 return true;
302 }
303}
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700304static JNIObject<jobject> createScanResult(JNIHelper &helper, wifi_scan_result *result) {
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700305
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700306 // ALOGD("creating scan result");
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700307
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700308 JNIObject<jobject> scanResult = helper.createObject("android/net/wifi/ScanResult");
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700309 if (scanResult == NULL) {
310 ALOGE("Error in creating scan result");
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700311 return JNIObject<jobject>(helper, NULL);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700312 }
313
Vinit Deshpandee73629f2015-04-23 15:06:46 -0700314 ALOGV("setting SSID to %s", result->ssid);
xinhe5cfd8d82015-07-28 16:34:37 -0700315
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700316 if (!setSSIDField(helper, scanResult, result->ssid)) {
xinhe5cfd8d82015-07-28 16:34:37 -0700317 ALOGE("Error on set SSID");
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700318 return JNIObject<jobject>(helper, NULL);
xinhe5cfd8d82015-07-28 16:34:37 -0700319 }
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700320
321 char bssid[32];
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700322 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->bssid[0], result->bssid[1],
323 result->bssid[2], result->bssid[3], result->bssid[4], result->bssid[5]);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700324
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700325 helper.setStringField(scanResult, "BSSID", bssid);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700326
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700327 helper.setIntField(scanResult, "level", result->rssi);
328 helper.setIntField(scanResult, "frequency", result->channel);
329 helper.setLongField(scanResult, "timestamp", result->ts);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700330
331 return scanResult;
332}
333
xinhebe3b27a2015-01-30 17:56:24 -0800334int set_iface_flags(const char *ifname, int dev_up) {
335 struct ifreq ifr;
336 int ret;
xinhebe3b27a2015-01-30 17:56:24 -0800337 int sock = socket(PF_INET, SOCK_DGRAM, 0);
338 if (sock < 0) {
339 ALOGD("Bad socket: %d\n", sock);
340 return -errno;
341 }
342
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700343 //ALOGD("setting interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
xinhebe3b27a2015-01-30 17:56:24 -0800344
345 memset(&ifr, 0, sizeof(ifr));
346 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
347
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700348 //ALOGD("reading old value\n");
xinhebe3b27a2015-01-30 17:56:24 -0800349
350 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
351 ret = errno ? -errno : -999;
Vinit Deshpandebb6942c2015-04-10 18:10:29 -0700352 ALOGE("Could not read interface %s flags: %d\n", ifname, errno);
xinhebe3b27a2015-01-30 17:56:24 -0800353 close(sock);
354 return ret;
355 } else {
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700356 //ALOGD("writing new value\n");
xinhebe3b27a2015-01-30 17:56:24 -0800357 }
358
359 if (dev_up) {
360 if (ifr.ifr_flags & IFF_UP) {
Vinit Deshpandebb6942c2015-04-10 18:10:29 -0700361 // ALOGD("interface %s is already up\n", ifname);
xinhebe3b27a2015-01-30 17:56:24 -0800362 close(sock);
363 return 0;
364 }
365 ifr.ifr_flags |= IFF_UP;
366 } else {
367 if (!(ifr.ifr_flags & IFF_UP)) {
Vinit Deshpandebb6942c2015-04-10 18:10:29 -0700368 // ALOGD("interface %s is already down\n", ifname);
xinhebe3b27a2015-01-30 17:56:24 -0800369 close(sock);
370 return 0;
371 }
372 ifr.ifr_flags &= ~IFF_UP;
373 }
374
375 if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
Vinit Deshpande64143012015-06-25 12:41:57 -0700376 ALOGE("Could not set interface %s flags: %d\n", ifname, errno);
377 ret = errno ? -errno : -999;
xinhebe3b27a2015-01-30 17:56:24 -0800378 close(sock);
379 return ret;
380 } else {
381 ALOGD("set interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
382 }
383 close(sock);
384 return 0;
385}
386
xinheb830d762015-02-11 17:14:17 -0800387static jboolean android_net_wifi_toggle_interface(JNIEnv* env, jclass cls, int toggle) {
388 return(set_iface_flags("wlan0", toggle) == 0);
389}
390
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700391static jboolean android_net_wifi_startHal(JNIEnv* env, jclass cls) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700392 JNIHelper helper(env);
393 wifi_handle halHandle = getWifiHandle(helper, cls);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800394 if (halHandle == NULL) {
xinheec61e772015-03-30 18:39:12 -0700395
396 if(init_wifi_hal_func_table(&hal_fn) != 0 ) {
397 ALOGD("Can not initialize the basic function pointer table");
398 return false;
399 }
400
401 wifi_error res = init_wifi_vendor_hal_func_table(&hal_fn);
402 if (res != WIFI_SUCCESS) {
403 ALOGD("Can not initialize the vendor function pointer table");
404 return false;
405 }
406
xinhebe3b27a2015-01-30 17:56:24 -0800407 int ret = set_iface_flags("wlan0", 1);
408 if(ret != 0) {
409 return false;
410 }
xinheec61e772015-03-30 18:39:12 -0700411
412 res = hal_fn.wifi_initialize(&halHandle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700413 if (res == WIFI_SUCCESS) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700414 helper.setStaticLongField(cls, WifiHandleVarName, (jlong)halHandle);
vandwalleaabe7a92014-05-09 18:11:02 -0700415 ALOGD("Did set static halHandle = %p", halHandle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700416 }
417 env->GetJavaVM(&mVM);
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700418 mCls = (jclass) env->NewGlobalRef(cls);
419 ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800420 return res == WIFI_SUCCESS;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700421 } else {
xinhe82628222015-02-04 16:39:45 -0800422 return (set_iface_flags("wlan0", 1) == 0);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800423 }
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800424}
425
426void android_net_wifi_hal_cleaned_up_handler(wifi_handle handle) {
427 ALOGD("In wifi cleaned up handler");
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700428
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700429 JNIHelper helper(mVM);
430 helper.setStaticLongField(mCls, WifiHandleVarName, 0);
431
432 helper.deleteGlobalRef(mCls);
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700433 mCls = NULL;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700434 mVM = NULL;
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800435}
436
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700437static void android_net_wifi_stopHal(JNIEnv* env, jclass cls) {
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800438 ALOGD("In wifi stop Hal");
xinheb830d762015-02-11 17:14:17 -0800439
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700440 JNIHelper helper(env);
441 wifi_handle halHandle = getWifiHandle(helper, cls);
Vinit Deshpandef49a59b2015-05-27 11:24:47 -0700442 if (halHandle == NULL)
443 return;
444
445 ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls);
xinheec61e772015-03-30 18:39:12 -0700446 hal_fn.wifi_cleanup(halHandle, android_net_wifi_hal_cleaned_up_handler);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800447}
448
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700449static void android_net_wifi_waitForHalEvents(JNIEnv* env, jclass cls) {
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700450
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700451 ALOGD("waitForHalEvents called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700452
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700453 JNIHelper helper(env);
454 wifi_handle halHandle = getWifiHandle(helper, cls);
xinheec61e772015-03-30 18:39:12 -0700455 hal_fn.wifi_event_loop(halHandle);
Vinit Deshpandef49a59b2015-05-27 11:24:47 -0700456 set_iface_flags("wlan0", 0);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800457}
458
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700459static int android_net_wifi_getInterfaces(JNIEnv *env, jclass cls) {
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700460 int n = 0;
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700461
462 JNIHelper helper(env);
463
464 wifi_handle halHandle = getWifiHandle(helper, cls);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700465 wifi_interface_handle *ifaceHandles = NULL;
xinheec61e772015-03-30 18:39:12 -0700466 int result = hal_fn.wifi_get_ifaces(halHandle, &n, &ifaceHandles);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700467 if (result < 0) {
468 return result;
469 }
470
Vinit Deshpande07ce33c2014-08-14 12:04:35 -0700471 if (n < 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700472 THROW(helper,"android_net_wifi_getInterfaces no interfaces");
vandwalleaabe7a92014-05-09 18:11:02 -0700473 return 0;
474 }
475
476 if (ifaceHandles == NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700477 THROW(helper,"android_net_wifi_getInterfaces null interface array");
vandwalleaabe7a92014-05-09 18:11:02 -0700478 return 0;
479 }
480
Vinit Deshpande07ce33c2014-08-14 12:04:35 -0700481 if (n > 8) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700482 THROW(helper,"Too many interfaces");
Vinit Deshpande07ce33c2014-08-14 12:04:35 -0700483 return 0;
484 }
485
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700486 jlongArray array = (env)->NewLongArray(n);
487 if (array == NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700488 THROW(helper,"Error in accessing array");
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700489 return 0;
490 }
491
492 jlong elems[8];
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700493 for (int i = 0; i < n; i++) {
494 elems[i] = reinterpret_cast<jlong>(ifaceHandles[i]);
495 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700496
497 helper.setLongArrayRegion(array, 0, n, elems);
498 helper.setStaticLongArrayField(cls, WifiIfaceHandleVarName, array);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700499
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700500 return (result < 0) ? result : n;
501}
502
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700503static jstring android_net_wifi_getInterfaceName(JNIEnv *env, jclass cls, jint i) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700504
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700505 char buf[EVENT_BUF_SIZE];
506
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700507 JNIHelper helper(env);
508
509 jlong value = helper.getStaticLongArrayField(cls, WifiIfaceHandleVarName, i);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700510 wifi_interface_handle handle = (wifi_interface_handle) value;
xinheec61e772015-03-30 18:39:12 -0700511 int result = hal_fn.wifi_get_iface_name(handle, buf, sizeof(buf));
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700512 if (result < 0) {
513 return NULL;
514 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700515 JNIObject<jstring> name = helper.newStringUTF(buf);
516 return name.detach();
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700517 }
518}
519
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700520
Vinit Deshapnde766cb4b2014-05-07 18:00:44 -0700521static void onScanResultsAvailable(wifi_request_id id, unsigned num_results) {
522
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700523 JNIHelper helper(mVM);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700524
Vinit Deshpandec5cdba42015-06-03 15:51:55 -0700525 // ALOGD("onScanResultsAvailable called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshapnde766cb4b2014-05-07 18:00:44 -0700526
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700527 helper.reportEvent(mCls, "onScanResultsAvailable", "(I)V", id);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700528}
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700529
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700530static void onScanEvent(wifi_scan_event event, unsigned status) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700531
532 JNIHelper helper(mVM);
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700533
Vinit Deshpandec5cdba42015-06-03 15:51:55 -0700534 // ALOGD("onScanStatus called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700535
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700536 helper.reportEvent(mCls, "onScanStatus", "(I)V", event);
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700537}
538
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700539static void onFullScanResult(wifi_request_id id, wifi_scan_result *result) {
540
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700541 JNIHelper helper(mVM);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700542
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700543 //ALOGD("onFullScanResult called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700544
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700545 JNIObject<jobject> scanResult = createScanResult(helper, result);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700546
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700547 //ALOGD("Creating a byte array of length %d", result->ie_length);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700548
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700549 JNIObject<jbyteArray> elements = helper.newByteArray(result->ie_length);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700550 if (elements == NULL) {
551 ALOGE("Error in allocating array");
552 return;
553 }
554
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700555 // ALOGD("Setting byte array");
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700556
557 jbyte *bytes = (jbyte *)&(result->ie_data[0]);
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700558 helper.setByteArrayRegion(elements, 0, result->ie_length, bytes);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700559
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700560 // ALOGD("Returning result");
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700561
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700562 helper.reportEvent(mCls, "onFullScanResult", "(ILandroid/net/wifi/ScanResult;[B)V", id,
563 scanResult.get(), elements.get());
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700564}
565
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700566static jboolean android_net_wifi_startScan(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700567 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700568
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700569 JNIHelper helper(env);
570 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700571 // ALOGD("starting scan on interface[%d] = %p", iface, handle);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700572
573 wifi_scan_cmd_params params;
574 memset(&params, 0, sizeof(params));
vandwalleaabe7a92014-05-09 18:11:02 -0700575
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700576 params.base_period = helper.getIntField(settings, "base_period_ms");
577 params.max_ap_per_scan = helper.getIntField(settings, "max_ap_per_scan");
578 params.report_threshold_percent = helper.getIntField(settings, "report_threshold_percent");
579 params.report_threshold_num_scans = helper.getIntField(settings, "report_threshold_num_scans");
vandwalleaabe7a92014-05-09 18:11:02 -0700580
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700581 ALOGD("Initialized common fields %d, %d, %d, %d", params.base_period, params.max_ap_per_scan,
582 params.report_threshold_percent, params.report_threshold_num_scans);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700583
584 const char *bucket_array_type = "[Lcom/android/server/wifi/WifiNative$BucketSettings;";
585 const char *channel_array_type = "[Lcom/android/server/wifi/WifiNative$ChannelSettings;";
vandwalleaabe7a92014-05-09 18:11:02 -0700586
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700587 params.num_buckets = helper.getIntField(settings, "num_buckets");
vandwalleaabe7a92014-05-09 18:11:02 -0700588
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700589 // ALOGD("Initialized num_buckets to %d", params.num_buckets);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700590
591 for (int i = 0; i < params.num_buckets; i++) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700592 JNIObject<jobject> bucket = helper.getObjectArrayField(
593 settings, "buckets", bucket_array_type, i);
vandwalleaabe7a92014-05-09 18:11:02 -0700594
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700595 params.buckets[i].bucket = helper.getIntField(bucket, "bucket");
596 params.buckets[i].band = (wifi_band) helper.getIntField(bucket, "band");
597 params.buckets[i].period = helper.getIntField(bucket, "period_ms");
vandwalleaabe7a92014-05-09 18:11:02 -0700598
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700599 int report_events = helper.getIntField(bucket, "report_events");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700600 params.buckets[i].report_events = report_events;
vandwalleaabe7a92014-05-09 18:11:02 -0700601
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700602 ALOGD("bucket[%d] = %d:%d:%d:%d", i, params.buckets[i].bucket,
603 params.buckets[i].band, params.buckets[i].period, report_events);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700604
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700605 params.buckets[i].num_channels = helper.getIntField(bucket, "num_channels");
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700606 // ALOGD("Initialized num_channels to %d", params.buckets[i].num_channels);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700607
608 for (int j = 0; j < params.buckets[i].num_channels; j++) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700609 JNIObject<jobject> channel = helper.getObjectArrayField(
610 bucket, "channels", channel_array_type, j);
vandwalleaabe7a92014-05-09 18:11:02 -0700611
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700612 params.buckets[i].channels[j].channel = helper.getIntField(channel, "frequency");
613 params.buckets[i].channels[j].dwellTimeMs = helper.getIntField(channel, "dwell_time_ms");
vandwalleaabe7a92014-05-09 18:11:02 -0700614
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700615 bool passive = helper.getBoolField(channel, "passive");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700616 params.buckets[i].channels[j].passive = (passive ? 1 : 0);
617
Vinit Deshpandebb6942c2015-04-10 18:10:29 -0700618 // ALOGD("Initialized channel %d", params.buckets[i].channels[j].channel);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700619 }
620 }
621
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700622 // ALOGD("Initialized all fields");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700623
624 wifi_scan_result_handler handler;
625 memset(&handler, 0, sizeof(handler));
626 handler.on_scan_results_available = &onScanResultsAvailable;
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700627 handler.on_full_scan_result = &onFullScanResult;
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700628 handler.on_scan_event = &onScanEvent;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700629
xinheec61e772015-03-30 18:39:12 -0700630 return hal_fn.wifi_start_gscan(id, handle, params, handler) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700631}
632
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700633static jboolean android_net_wifi_stopScan(JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700634
635 JNIHelper helper(env);
636 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700637 // ALOGD("stopping scan on interface[%d] = %p", iface, handle);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700638
xinheec61e772015-03-30 18:39:12 -0700639 return hal_fn.wifi_stop_gscan(id, handle) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700640}
641
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700642static int compare_scan_result_timestamp(const void *v1, const void *v2) {
643 const wifi_scan_result *result1 = static_cast<const wifi_scan_result *>(v1);
644 const wifi_scan_result *result2 = static_cast<const wifi_scan_result *>(v2);
645 return result1->ts - result2->ts;
646}
647
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700648static jobject android_net_wifi_getScanResults(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700649 JNIEnv *env, jclass cls, jint iface, jboolean flush) {
Navtej Singh Mannc8b61ce2015-04-16 18:54:10 -0700650
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700651 JNIHelper helper(env);
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700652 wifi_cached_scan_results scan_data[64];
653 int num_scan_data = 64;
Navtej Singh Mannc8b61ce2015-04-16 18:54:10 -0700654
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700655 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700656 // ALOGD("getting scan results on interface[%d] = %p", iface, handle);
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700657
Navtej Singh Mannc8b61ce2015-04-16 18:54:10 -0700658 byte b = flush ? 0xFF : 0;
xinheec61e772015-03-30 18:39:12 -0700659 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 -0700660 if (result == WIFI_SUCCESS) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700661 JNIObject<jobjectArray> scanData = helper.createObjectArray(
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700662 "android/net/wifi/WifiScanner$ScanData", num_scan_data);
663 if (scanData == NULL) {
664 ALOGE("Error in allocating array of scanData");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700665 return NULL;
666 }
667
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700668 for (int i = 0; i < num_scan_data; i++) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700669
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700670 JNIObject<jobject> data = helper.createObject("android/net/wifi/WifiScanner$ScanData");
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700671 if (data == NULL) {
672 ALOGE("Error in allocating scanData");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700673 return NULL;
674 }
675
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700676 helper.setIntField(data, "mId", scan_data[i].scan_id);
677 helper.setIntField(data, "mFlags", scan_data[i].flags);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700678
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700679 /* sort all scan results by timestamp */
680 qsort(scan_data[i].results, scan_data[i].num_results,
681 sizeof(wifi_scan_result), compare_scan_result_timestamp);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700682
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700683 JNIObject<jobjectArray> scanResults = helper.createObjectArray(
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700684 "android/net/wifi/ScanResult", scan_data[i].num_results);
685 if (scanResults == NULL) {
686 ALOGE("Error in allocating scanResult array");
687 return NULL;
688 }
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700689
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700690 wifi_scan_result *results = scan_data[i].results;
691 for (int j = 0; j < scan_data[i].num_results; j++) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700692
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700693 JNIObject<jobject> scanResult = createScanResult(helper, &results[j]);
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700694 if (scanResult == NULL) {
695 ALOGE("Error in creating scan result");
696 return NULL;
697 }
698
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700699 helper.setObjectArrayElement(scanResults, j, scanResult);
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700700 }
701
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700702 helper.setObjectField(data, "mResults", "[Landroid/net/wifi/ScanResult;", scanResults);
703 helper.setObjectArrayElement(scanData, i, data);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700704 }
705
Vinit Deshpandec5cdba42015-06-03 15:51:55 -0700706 // ALOGD("retrieved %d scan data from interface[%d] = %p", num_scan_data, iface, handle);
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700707 return scanData.detach();
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700708 } else {
709 return NULL;
710 }
711}
712
713
714static jboolean android_net_wifi_getScanCapabilities(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700715 JNIEnv *env, jclass cls, jint iface, jobject capabilities) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700716
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700717 JNIHelper helper(env);
718 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700719 // ALOGD("getting scan capabilities on interface[%d] = %p", iface, handle);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700720
721 wifi_gscan_capabilities c;
722 memset(&c, 0, sizeof(c));
xinheec61e772015-03-30 18:39:12 -0700723 int result = hal_fn.wifi_get_gscan_capabilities(handle, &c);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700724 if (result != WIFI_SUCCESS) {
725 ALOGD("failed to get capabilities : %d", result);
726 return JNI_FALSE;
727 }
728
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700729 helper.setIntField(capabilities, "max_scan_cache_size", c.max_scan_cache_size);
730 helper.setIntField(capabilities, "max_scan_buckets", c.max_scan_buckets);
731 helper.setIntField(capabilities, "max_ap_cache_per_scan", c.max_ap_cache_per_scan);
732 helper.setIntField(capabilities, "max_rssi_sample_size", c.max_rssi_sample_size);
733 helper.setIntField(capabilities, "max_scan_reporting_threshold", c.max_scan_reporting_threshold);
734 helper.setIntField(capabilities, "max_hotlist_bssids", c.max_hotlist_bssids);
735 helper.setIntField(capabilities, "max_significant_wifi_change_aps",
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700736 c.max_significant_wifi_change_aps);
737
738 return JNI_TRUE;
739}
740
741
742static byte parseHexChar(char ch) {
743 if (isdigit(ch))
744 return ch - '0';
745 else if ('A' <= ch && ch <= 'F')
746 return ch - 'A' + 10;
747 else if ('a' <= ch && ch <= 'f')
748 return ch - 'a' + 10;
749 else {
750 ALOGE("invalid character in bssid %c", ch);
751 return 0;
752 }
753}
754
755static byte parseHexByte(const char * &str) {
756 byte b = parseHexChar(str[0]);
757 if (str[1] == ':' || str[1] == '\0') {
758 str += 2;
759 return b;
760 } else {
761 b = b << 4 | parseHexChar(str[1]);
762 str += 3;
763 return b;
764 }
765}
766
767static void parseMacAddress(const char *str, mac_addr addr) {
768 addr[0] = parseHexByte(str);
769 addr[1] = parseHexByte(str);
770 addr[2] = parseHexByte(str);
771 addr[3] = parseHexByte(str);
772 addr[4] = parseHexByte(str);
773 addr[5] = parseHexByte(str);
774}
775
Vinit Deshpande14365732014-06-30 15:23:23 -0700776static bool parseMacAddress(JNIEnv *env, jobject obj, mac_addr addr) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700777 JNIHelper helper(env);
778 JNIObject<jstring> macAddrString = helper.getStringField(obj, "bssid");
Vinit Deshpande14365732014-06-30 15:23:23 -0700779 if (macAddrString == NULL) {
780 ALOGE("Error getting bssid field");
781 return false;
782 }
783
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700784 ScopedUtfChars chars(env, macAddrString);
785 const char *bssid = chars.c_str();
Vinit Deshpande14365732014-06-30 15:23:23 -0700786 if (bssid == NULL) {
787 ALOGE("Error getting bssid");
788 return false;
789 }
790
791 parseMacAddress(bssid, addr);
792 return true;
793}
794
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700795static void onHotlistApFound(wifi_request_id id,
796 unsigned num_results, wifi_scan_result *results) {
797
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700798 JNIHelper helper(mVM);
799 ALOGD("onHotlistApFound called, vm = %p, obj = %p, num_results = %d", mVM, mCls, num_results);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700800
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700801 JNIObject<jobjectArray> scanResults = helper.newObjectArray(num_results,
802 "android/net/wifi/ScanResult", NULL);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700803 if (scanResults == NULL) {
804 ALOGE("Error in allocating array");
805 return;
806 }
807
808 for (unsigned i = 0; i < num_results; i++) {
809
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700810 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700811 if (scanResult == NULL) {
812 ALOGE("Error in creating scan result");
813 return;
814 }
815
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700816 helper.setObjectArrayElement(scanResults, i, scanResult);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700817
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700818 ALOGD("Found AP %32s", results[i].ssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700819 }
820
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700821 helper.reportEvent(mCls, "onHotlistApFound", "(I[Landroid/net/wifi/ScanResult;)V",
822 id, scanResults.get());
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700823}
824
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700825static void onHotlistApLost(wifi_request_id id,
826 unsigned num_results, wifi_scan_result *results) {
827
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700828 JNIHelper helper(mVM);
829 ALOGD("onHotlistApLost called, vm = %p, obj = %p, num_results = %d", mVM, mCls, num_results);
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700830
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700831 JNIObject<jobjectArray> scanResults = helper.newObjectArray(num_results,
832 "android/net/wifi/ScanResult", NULL);
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700833 if (scanResults == NULL) {
834 ALOGE("Error in allocating array");
835 return;
836 }
837
838 for (unsigned i = 0; i < num_results; i++) {
839
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700840 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]);
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700841 if (scanResult == NULL) {
842 ALOGE("Error in creating scan result");
843 return;
844 }
845
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700846 helper.setObjectArrayElement(scanResults, i, scanResult);
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700847
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700848 ALOGD("Lost AP %32s", results[i].ssid);
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700849 }
850
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700851 helper.reportEvent(mCls, "onHotlistApLost", "(I[Landroid/net/wifi/ScanResult;)V",
852 id, scanResults.get());
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700853}
854
855
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700856static jboolean android_net_wifi_setHotlist(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700857 JNIEnv *env, jclass cls, jint iface, jint id, jobject ap) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700858
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700859 JNIHelper helper(env);
860 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700861 ALOGD("setting hotlist on interface[%d] = %p", iface, handle);
862
863 wifi_bssid_hotlist_params params;
864 memset(&params, 0, sizeof(params));
865
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700866 params.lost_ap_sample_size = helper.getIntField(ap, "apLostThreshold");
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700867
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700868 JNIObject<jobjectArray> array = helper.getArrayField(
869 ap, "bssidInfos", "[Landroid/net/wifi/WifiScanner$BssidInfo;");
870 params.num_bssid = helper.getArrayLength(array);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700871
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700872 if (params.num_bssid == 0) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700873 ALOGE("Error in accesing array");
874 return false;
875 }
876
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700877 for (int i = 0; i < params.num_bssid; i++) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700878 JNIObject<jobject> objAp = helper.getObjectArrayElement(array, i);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700879
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700880 JNIObject<jstring> macAddrString = helper.getStringField(objAp, "bssid");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700881 if (macAddrString == NULL) {
882 ALOGE("Error getting bssid field");
883 return false;
884 }
885
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700886 ScopedUtfChars chars(env, macAddrString);
887 const char *bssid = chars.c_str();
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700888 if (bssid == NULL) {
889 ALOGE("Error getting bssid");
890 return false;
891 }
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700892 parseMacAddress(bssid, params.ap[i].bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700893
894 mac_addr addr;
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700895 memcpy(addr, params.ap[i].bssid, sizeof(mac_addr));
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700896
897 char bssidOut[32];
898 sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1],
899 addr[2], addr[3], addr[4], addr[5]);
900
901 ALOGD("Added bssid %s", bssidOut);
902
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700903 params.ap[i].low = helper.getIntField(objAp, "low");
904 params.ap[i].high = helper.getIntField(objAp, "high");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700905 }
906
907 wifi_hotlist_ap_found_handler handler;
908 memset(&handler, 0, sizeof(handler));
909
910 handler.on_hotlist_ap_found = &onHotlistApFound;
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700911 handler.on_hotlist_ap_lost = &onHotlistApLost;
xinheec61e772015-03-30 18:39:12 -0700912 return hal_fn.wifi_set_bssid_hotlist(id, handle, params, handler) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700913}
914
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700915static jboolean android_net_wifi_resetHotlist(JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700916
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700917 JNIHelper helper(env);
918 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700919 ALOGD("resetting hotlist on interface[%d] = %p", iface, handle);
920
xinheec61e772015-03-30 18:39:12 -0700921 return hal_fn.wifi_reset_bssid_hotlist(id, handle) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700922}
923
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700924void onSignificantWifiChange(wifi_request_id id,
925 unsigned num_results, wifi_significant_change_result **results) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700926
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700927 JNIHelper helper(mVM);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700928
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700929 ALOGD("onSignificantWifiChange called, vm = %p, obj = %p", mVM, mCls);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700930
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700931 JNIObject<jobjectArray> scanResults = helper.newObjectArray(
932 num_results, "android/net/wifi/ScanResult", NULL);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700933 if (scanResults == NULL) {
934 ALOGE("Error in allocating array");
935 return;
936 }
937
938 for (unsigned i = 0; i < num_results; i++) {
939
Greg Hackmannd31a40e2015-02-22 21:39:38 -0800940 wifi_significant_change_result &result = *(results[i]);
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700941
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700942 JNIObject<jobject> scanResult = helper.createObject("android/net/wifi/ScanResult");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700943 if (scanResult == NULL) {
944 ALOGE("Error in creating scan result");
945 return;
946 }
947
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700948 // helper.setStringField(scanResult, "SSID", results[i].ssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700949
950 char bssid[32];
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700951 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result.bssid[0], result.bssid[1],
952 result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700953
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700954 helper.setStringField(scanResult, "BSSID", bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700955
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700956 helper.setIntField(scanResult, "level", result.rssi[0]);
957 helper.setIntField(scanResult, "frequency", result.channel);
958 // helper.setLongField(scanResult, "timestamp", result.ts);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700959
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700960 helper.setObjectArrayElement(scanResults, i, scanResult);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700961 }
962
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700963 helper.reportEvent(mCls, "onSignificantWifiChange", "(I[Landroid/net/wifi/ScanResult;)V",
964 id, scanResults.get());
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700965
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700966}
967
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700968static jboolean android_net_wifi_trackSignificantWifiChange(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700969 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) {
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700970
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700971 JNIHelper helper(env);
972 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700973 ALOGD("tracking significant wifi change on interface[%d] = %p", iface, handle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700974
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700975 wifi_significant_change_params params;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700976 memset(&params, 0, sizeof(params));
977
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700978 params.rssi_sample_size = helper.getIntField(settings, "rssiSampleSize");
979 params.lost_ap_sample_size = helper.getIntField(settings, "lostApSampleSize");
980 params.min_breaching = helper.getIntField(settings, "minApsBreachingThreshold");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700981
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700982 const char *bssid_info_array_type = "[Landroid/net/wifi/WifiScanner$BssidInfo;";
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700983 JNIObject<jobjectArray> bssids = helper.getArrayField(
984 settings, "bssidInfos", bssid_info_array_type);
985 params.num_bssid = helper.getArrayLength(bssids);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700986
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700987 if (params.num_bssid == 0) {
vandwalleaabe7a92014-05-09 18:11:02 -0700988 ALOGE("Error in accessing array");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700989 return false;
990 }
991
992 ALOGD("Initialized common fields %d, %d, %d, %d", params.rssi_sample_size,
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700993 params.lost_ap_sample_size, params.min_breaching, params.num_bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700994
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700995 for (int i = 0; i < params.num_bssid; i++) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700996 JNIObject<jobject> objAp = helper.getObjectArrayElement(bssids, i);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700997
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700998 JNIObject<jstring> macAddrString = helper.getStringField(objAp, "bssid");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700999 if (macAddrString == NULL) {
1000 ALOGE("Error getting bssid field");
1001 return false;
1002 }
1003
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001004 ScopedUtfChars chars(env, macAddrString.get());
1005 const char *bssid = chars.c_str();
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001006 if (bssid == NULL) {
1007 ALOGE("Error getting bssid");
1008 return false;
1009 }
1010
1011 mac_addr addr;
1012 parseMacAddress(bssid, addr);
Vinit Deshpandea59fae62014-05-23 15:59:35 -07001013 memcpy(params.ap[i].bssid, addr, sizeof(mac_addr));
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001014
1015 char bssidOut[32];
Vinit Deshpande4dbfefd2014-08-10 18:19:13 -07001016 sprintf(bssidOut, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1],
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001017 addr[2], addr[3], addr[4], addr[5]);
1018
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001019 params.ap[i].low = helper.getIntField(objAp, "low");
1020 params.ap[i].high = helper.getIntField(objAp, "high");
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001021
Vinit Deshpandea59fae62014-05-23 15:59:35 -07001022 ALOGD("Added bssid %s, [%04d, %04d]", bssidOut, params.ap[i].low, params.ap[i].high);
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001023 }
1024
Pierre Vandwallec03c1462015-03-18 19:16:30 -07001025 ALOGD("Added %d bssids", params.num_bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001026
1027 wifi_significant_change_handler handler;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001028 memset(&handler, 0, sizeof(handler));
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001029
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001030 handler.on_significant_change = &onSignificantWifiChange;
xinheec61e772015-03-30 18:39:12 -07001031 return hal_fn.wifi_set_significant_change_handler(id, handle, params, handler) == WIFI_SUCCESS;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001032}
1033
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001034static jboolean android_net_wifi_untrackSignificantWifiChange(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -07001035 JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001036
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001037 JNIHelper helper(env);
1038 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001039 ALOGD("resetting significant wifi change on interface[%d] = %p", iface, handle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001040
xinheec61e772015-03-30 18:39:12 -07001041 return hal_fn.wifi_reset_significant_change_handler(id, handle) == WIFI_SUCCESS;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001042}
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -08001043
vandwalleaabe7a92014-05-09 18:11:02 -07001044wifi_iface_stat link_stat;
vandwalle200e8ee2014-07-18 18:44:32 -07001045wifi_radio_stat radio_stat; // L release has support for only one radio
vandwalleaabe7a92014-05-09 18:11:02 -07001046
1047void onLinkStatsResults(wifi_request_id id, wifi_iface_stat *iface_stat,
vandwalle200e8ee2014-07-18 18:44:32 -07001048 int num_radios, wifi_radio_stat *radio_stats)
vandwalleaabe7a92014-05-09 18:11:02 -07001049{
vandwalle200e8ee2014-07-18 18:44:32 -07001050 if (iface_stat != 0) {
1051 memcpy(&link_stat, iface_stat, sizeof(wifi_iface_stat));
1052 } else {
1053 memset(&link_stat, 0, sizeof(wifi_iface_stat));
1054 }
vandwalle200e8ee2014-07-18 18:44:32 -07001055
1056 if (num_radios > 0 && radio_stats != 0) {
1057 memcpy(&radio_stat, radio_stats, sizeof(wifi_radio_stat));
1058 } else {
1059 memset(&radio_stat, 0, sizeof(wifi_radio_stat));
1060 }
vandwalleaabe7a92014-05-09 18:11:02 -07001061}
1062
Pierre Vandwalled745a522015-06-11 17:48:58 -07001063static void android_net_wifi_setLinkLayerStats (JNIEnv *env, jclass cls, jint iface, int enable) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001064 JNIHelper helper(env);
1065 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Pierre Vandwalled745a522015-06-11 17:48:58 -07001066
1067 wifi_link_layer_params params;
1068 params.aggressive_statistics_gathering = enable;
1069 params.mpdu_size_threshold = 128;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001070
1071 ALOGD("android_net_wifi_setLinkLayerStats: %u\n", enable);
Pierre Vandwalled745a522015-06-11 17:48:58 -07001072
1073 hal_fn.wifi_set_link_stats(handle, params);
1074}
1075
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -07001076static jobject android_net_wifi_getLinkLayerStats (JNIEnv *env, jclass cls, jint iface) {
vandwalleaabe7a92014-05-09 18:11:02 -07001077
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001078 JNIHelper helper(env);
vandwalleaabe7a92014-05-09 18:11:02 -07001079 wifi_stats_result_handler handler;
1080 memset(&handler, 0, sizeof(handler));
1081 handler.on_link_stats_results = &onLinkStatsResults;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001082 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinheec61e772015-03-30 18:39:12 -07001083 int result = hal_fn.wifi_get_link_stats(0, handle, handler);
vandwalleaabe7a92014-05-09 18:11:02 -07001084 if (result < 0) {
vandwalle200e8ee2014-07-18 18:44:32 -07001085 ALOGE("android_net_wifi_getLinkLayerStats: failed to get link statistics\n");
vandwalleaabe7a92014-05-09 18:11:02 -07001086 return NULL;
1087 }
1088
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001089 JNIObject<jobject> wifiLinkLayerStats = helper.createObject(
1090 "android/net/wifi/WifiLinkLayerStats");
vandwalleaabe7a92014-05-09 18:11:02 -07001091 if (wifiLinkLayerStats == NULL) {
1092 ALOGE("Error in allocating wifiLinkLayerStats");
1093 return NULL;
1094 }
1095
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001096 helper.setIntField(wifiLinkLayerStats, "beacon_rx", link_stat.beacon_rx);
1097 helper.setIntField(wifiLinkLayerStats, "rssi_mgmt", link_stat.rssi_mgmt);
1098 helper.setLongField(wifiLinkLayerStats, "rxmpdu_be", link_stat.ac[WIFI_AC_BE].rx_mpdu);
1099 helper.setLongField(wifiLinkLayerStats, "rxmpdu_bk", link_stat.ac[WIFI_AC_BK].rx_mpdu);
1100 helper.setLongField(wifiLinkLayerStats, "rxmpdu_vi", link_stat.ac[WIFI_AC_VI].rx_mpdu);
1101 helper.setLongField(wifiLinkLayerStats, "rxmpdu_vo", link_stat.ac[WIFI_AC_VO].rx_mpdu);
1102 helper.setLongField(wifiLinkLayerStats, "txmpdu_be", link_stat.ac[WIFI_AC_BE].tx_mpdu);
1103 helper.setLongField(wifiLinkLayerStats, "txmpdu_bk", link_stat.ac[WIFI_AC_BK].tx_mpdu);
1104 helper.setLongField(wifiLinkLayerStats, "txmpdu_vi", link_stat.ac[WIFI_AC_VI].tx_mpdu);
1105 helper.setLongField(wifiLinkLayerStats, "txmpdu_vo", link_stat.ac[WIFI_AC_VO].tx_mpdu);
1106 helper.setLongField(wifiLinkLayerStats, "lostmpdu_be", link_stat.ac[WIFI_AC_BE].mpdu_lost);
1107 helper.setLongField(wifiLinkLayerStats, "lostmpdu_bk", link_stat.ac[WIFI_AC_BK].mpdu_lost);
1108 helper.setLongField(wifiLinkLayerStats, "lostmpdu_vi", link_stat.ac[WIFI_AC_VI].mpdu_lost);
1109 helper.setLongField(wifiLinkLayerStats, "lostmpdu_vo", link_stat.ac[WIFI_AC_VO].mpdu_lost);
1110 helper.setLongField(wifiLinkLayerStats, "retries_be", link_stat.ac[WIFI_AC_BE].retries);
1111 helper.setLongField(wifiLinkLayerStats, "retries_bk", link_stat.ac[WIFI_AC_BK].retries);
1112 helper.setLongField(wifiLinkLayerStats, "retries_vi", link_stat.ac[WIFI_AC_VI].retries);
1113 helper.setLongField(wifiLinkLayerStats, "retries_vo", link_stat.ac[WIFI_AC_VO].retries);
vandwalleaabe7a92014-05-09 18:11:02 -07001114
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001115 helper.setIntField(wifiLinkLayerStats, "on_time", radio_stat.on_time);
1116 helper.setIntField(wifiLinkLayerStats, "tx_time", radio_stat.tx_time);
1117 helper.setIntField(wifiLinkLayerStats, "rx_time", radio_stat.rx_time);
1118 helper.setIntField(wifiLinkLayerStats, "on_time_scan", radio_stat.on_time_scan);
vandwalle200e8ee2014-07-18 18:44:32 -07001119
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001120 return wifiLinkLayerStats.detach();
vandwalleaabe7a92014-05-09 18:11:02 -07001121}
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001122
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001123static jint android_net_wifi_getSupportedFeatures(JNIEnv *env, jclass cls, jint iface) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001124
1125 JNIHelper helper(env);
1126 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001127 feature_set set = 0;
1128
1129 wifi_error result = WIFI_SUCCESS;
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001130 /*
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001131 set = WIFI_FEATURE_INFRA
1132 | WIFI_FEATURE_INFRA_5G
1133 | WIFI_FEATURE_HOTSPOT
1134 | WIFI_FEATURE_P2P
1135 | WIFI_FEATURE_SOFT_AP
1136 | WIFI_FEATURE_GSCAN
1137 | WIFI_FEATURE_PNO
1138 | WIFI_FEATURE_TDLS
1139 | WIFI_FEATURE_EPR;
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001140 */
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001141
xinheec61e772015-03-30 18:39:12 -07001142 result = hal_fn.wifi_get_supported_feature_set(handle, &set);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001143 if (result == WIFI_SUCCESS) {
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -07001144 // ALOGD("wifi_get_supported_feature_set returned set = 0x%x", set);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001145 return set;
1146 } else {
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -07001147 ALOGE("wifi_get_supported_feature_set returned error = 0x%x", result);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001148 return 0;
1149 }
1150}
1151
xinhe06a3eba2015-03-18 20:17:17 -07001152static void onRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* results[]) {
Vinit Deshpande14365732014-06-30 15:23:23 -07001153
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001154 JNIHelper helper(mVM);
Vinit Deshpande14365732014-06-30 15:23:23 -07001155
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001156 ALOGD("onRttResults called, vm = %p, obj = %p", mVM, mCls);
Vinit Deshpande14365732014-06-30 15:23:23 -07001157
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001158 JNIObject<jobjectArray> rttResults = helper.newObjectArray(
1159 num_results, "android/net/wifi/RttManager$RttResult", NULL);
Vinit Deshpande14365732014-06-30 15:23:23 -07001160 if (rttResults == NULL) {
1161 ALOGE("Error in allocating array");
1162 return;
1163 }
1164
1165 for (unsigned i = 0; i < num_results; i++) {
1166
xinhe06a3eba2015-03-18 20:17:17 -07001167 wifi_rtt_result *result = results[i];
Vinit Deshpande14365732014-06-30 15:23:23 -07001168
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001169 JNIObject<jobject> rttResult = helper.createObject("android/net/wifi/RttManager$RttResult");
Vinit Deshpande14365732014-06-30 15:23:23 -07001170 if (rttResult == NULL) {
1171 ALOGE("Error in creating rtt result");
1172 return;
1173 }
1174
Vinit Deshpande14365732014-06-30 15:23:23 -07001175 char bssid[32];
xinhe06a3eba2015-03-18 20:17:17 -07001176 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->addr[0], result->addr[1],
1177 result->addr[2], result->addr[3], result->addr[4], result->addr[5]);
Vinit Deshpande14365732014-06-30 15:23:23 -07001178
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001179 helper.setStringField(rttResult, "bssid", bssid);
1180 helper.setIntField( rttResult, "burstNumber", result->burst_num);
1181 helper.setIntField( rttResult, "measurementFrameNumber", result->measurement_number);
1182 helper.setIntField( rttResult, "successMeasurementFrameNumber", result->success_number);
1183 helper.setIntField(rttResult, "frameNumberPerBurstPeer", result->number_per_burst_peer);
1184 helper.setIntField( rttResult, "status", result->status);
1185 helper.setIntField( rttResult, "measurementType", result->type);
1186 helper.setIntField(rttResult, "retryAfterDuration", result->retry_after_duration);
1187 helper.setLongField(rttResult, "ts", result->ts);
1188 helper.setIntField( rttResult, "rssi", result->rssi);
1189 helper.setIntField( rttResult, "rssiSpread", result->rssi_spread);
1190 helper.setIntField( rttResult, "txRate", result->tx_rate.bitrate);
1191 helper.setIntField( rttResult, "rxRate", result->rx_rate.bitrate);
1192 helper.setLongField(rttResult, "rtt", result->rtt);
1193 helper.setLongField(rttResult, "rttStandardDeviation", result->rtt_sd);
1194 helper.setIntField( rttResult, "distance", result->distance);
1195 helper.setIntField( rttResult, "distanceStandardDeviation", result->distance_sd);
1196 helper.setIntField( rttResult, "distanceSpread", result->distance_spread);
1197 helper.setIntField( rttResult, "burstDuration", result->burst_duration);
1198 helper.setIntField( rttResult, "negotiatedBurstNum", result->negotiated_burst_num);
xinhe12cf3882015-03-12 18:38:54 -07001199
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001200 JNIObject<jobject> LCI = helper.createObject(
1201 "android/net/wifi/RttManager$WifiInformationElement");
1202 if (result->LCI != NULL && result->LCI->len > 0) {
1203 ALOGD("Add LCI in result");
1204 helper.setByteField(LCI, "id", result->LCI->id);
1205 JNIObject<jbyteArray> elements = helper.newByteArray(result->LCI->len);
1206 jbyte *bytes = (jbyte *)&(result->LCI->data[0]);
1207 helper.setByteArrayRegion(elements, 0, result->LCI->len, bytes);
1208 helper.setObjectField(LCI, "data", "[B", elements);
1209 } else {
1210 ALOGD("No LCI in result");
1211 helper.setByteField(LCI, "id", (byte)(0xff));
1212 }
1213 helper.setObjectField(rttResult, "LCI",
1214 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCI);
Vinit Deshpande14365732014-06-30 15:23:23 -07001215
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001216 JNIObject<jobject> LCR = helper.createObject(
1217 "android/net/wifi/RttManager$WifiInformationElement");
1218 if (result->LCR != NULL && result->LCR->len > 0) {
1219 ALOGD("Add LCR in result");
1220 helper.setByteField(LCR, "id", result->LCR->id);
1221 JNIObject<jbyteArray> elements = helper.newByteArray(result->LCI->len);
1222 jbyte *bytes = (jbyte *)&(result->LCR->data[0]);
1223 helper.setByteArrayRegion(elements, 0, result->LCI->len, bytes);
1224 helper.setObjectField(LCR, "data", "[B", elements);
1225 } else {
1226 ALOGD("No LCR in result");
1227 helper.setByteField(LCR, "id", (byte)(0xff));
1228 }
1229 helper.setObjectField(rttResult, "LCR",
1230 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCR);
1231
1232 helper.setObjectArrayElement(rttResults, i, rttResult);
Vinit Deshpande14365732014-06-30 15:23:23 -07001233 }
1234
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001235 helper.reportEvent(mCls, "onRttResults", "(I[Landroid/net/wifi/RttManager$RttResult;)V",
1236 id, rttResults.get());
Vinit Deshpande14365732014-06-30 15:23:23 -07001237}
1238
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001239const int MaxRttConfigs = 16;
1240
Vinit Deshpande14365732014-06-30 15:23:23 -07001241static jboolean android_net_wifi_requestRange(
1242 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) {
1243
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001244 JNIHelper helper(env);
1245
1246 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande14365732014-06-30 15:23:23 -07001247 ALOGD("sending rtt request [%d] = %p", id, handle);
1248
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001249 wifi_rtt_config configs[MaxRttConfigs];
1250 memset(&configs, 0, sizeof(configs));
Vinit Deshpande14365732014-06-30 15:23:23 -07001251
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001252 int len = helper.getArrayLength((jobjectArray)params);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001253 if (len > MaxRttConfigs) {
1254 return false;
1255 }
1256
1257 for (int i = 0; i < len; i++) {
1258
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001259 JNIObject<jobject> param = helper.getObjectArrayElement((jobjectArray)params, i);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001260 if (param == NULL) {
1261 ALOGD("could not get element %d", i);
1262 continue;
1263 }
1264
1265 wifi_rtt_config &config = configs[i];
1266
1267 parseMacAddress(env, param, config.addr);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001268 config.type = (wifi_rtt_type)helper.getIntField(param, "requestType");
1269 config.peer = (rtt_peer_type)helper.getIntField(param, "deviceType");
1270 config.channel.center_freq = helper.getIntField(param, "frequency");
1271 config.channel.width = (wifi_channel_width) helper.getIntField(param, "channelWidth");
1272 config.channel.center_freq0 = helper.getIntField(param, "centerFreq0");
1273 config.channel.center_freq1 = helper.getIntField(param, "centerFreq1");
xinhe12cf3882015-03-12 18:38:54 -07001274
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001275 config.num_burst = helper.getIntField(param, "numberBurst");
1276 config.burst_period = (unsigned) helper.getIntField(param, "interval");
1277 config.num_frames_per_burst = (unsigned) helper.getIntField(param, "numSamplesPerBurst");
1278 config.num_retries_per_rtt_frame = (unsigned) helper.getIntField(param,
xinhe12cf3882015-03-12 18:38:54 -07001279 "numRetriesPerMeasurementFrame");
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001280 config.num_retries_per_ftmr = (unsigned) helper.getIntField(param, "numRetriesPerFTMR");
1281 config.LCI_request = helper.getBoolField(param, "LCIRequest") ? 1 : 0;
1282 config.LCR_request = helper.getBoolField(param, "LCRRequest") ? 1 : 0;
1283 config.burst_duration = (unsigned) helper.getIntField(param, "burstTimeout");
1284 config.preamble = (wifi_rtt_preamble) helper.getIntField(param, "preamble");
1285 config.bw = (wifi_rtt_bw) helper.getIntField(param, "bandwidth");
xinhe12cf3882015-03-12 18:38:54 -07001286
1287 ALOGD("RTT request destination %d: type is %d, peer is %d, bw is %d, center_freq is %d ", i,
Wei Wang3cd3ccd2015-06-09 14:00:57 -07001288 config.type,config.peer, config.channel.width, config.channel.center_freq);
xinhe12cf3882015-03-12 18:38:54 -07001289 ALOGD("center_freq0 is %d, center_freq1 is %d, num_burst is %d,interval is %d",
1290 config.channel.center_freq0, config.channel.center_freq1, config.num_burst,
xinhec96feb82015-04-01 18:52:59 -07001291 config.burst_period);
xinhe12cf3882015-03-12 18:38:54 -07001292 ALOGD("frames_per_burst is %d, retries of measurement frame is %d, retries_per_ftmr is %d",
xinhec96feb82015-04-01 18:52:59 -07001293 config.num_frames_per_burst, config.num_retries_per_rtt_frame,
xinhe12cf3882015-03-12 18:38:54 -07001294 config.num_retries_per_ftmr);
1295 ALOGD("LCI_requestis %d, LCR_request is %d, burst_timeout is %d, preamble is %d, bw is %d",
xinhec96feb82015-04-01 18:52:59 -07001296 config.LCI_request, config.LCR_request, config.burst_duration, config.preamble,
xinhe12cf3882015-03-12 18:38:54 -07001297 config.bw);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001298 }
Vinit Deshpande14365732014-06-30 15:23:23 -07001299
1300 wifi_rtt_event_handler handler;
1301 handler.on_rtt_results = &onRttResults;
1302
xinheec61e772015-03-30 18:39:12 -07001303 return hal_fn.wifi_rtt_range_request(id, handle, len, configs, handler) == WIFI_SUCCESS;
Vinit Deshpande14365732014-06-30 15:23:23 -07001304}
1305
1306static jboolean android_net_wifi_cancelRange(
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001307 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) {
Vinit Deshpande14365732014-06-30 15:23:23 -07001308
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001309 JNIHelper helper(env);
1310 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande14365732014-06-30 15:23:23 -07001311 ALOGD("cancelling rtt request [%d] = %p", id, handle);
1312
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001313 mac_addr addrs[MaxRttConfigs];
1314 memset(&addrs, 0, sizeof(addrs));
Vinit Deshpande14365732014-06-30 15:23:23 -07001315
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001316 int len = helper.getArrayLength((jobjectArray)params);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001317 if (len > MaxRttConfigs) {
1318 return false;
1319 }
Vinit Deshpande14365732014-06-30 15:23:23 -07001320
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001321 for (int i = 0; i < len; i++) {
1322
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001323 JNIObject<jobject> param = helper.getObjectArrayElement(params, i);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001324 if (param == NULL) {
1325 ALOGD("could not get element %d", i);
1326 continue;
1327 }
1328
1329 parseMacAddress(env, param, addrs[i]);
1330 }
1331
xinheec61e772015-03-30 18:39:12 -07001332 return hal_fn.wifi_rtt_range_cancel(id, handle, len, addrs) == WIFI_SUCCESS;
Vinit Deshpande14365732014-06-30 15:23:23 -07001333}
1334
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001335static jboolean android_net_wifi_setScanningMacOui(JNIEnv *env, jclass cls,
1336 jint iface, jbyteArray param) {
1337
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001338 JNIHelper helper(env);
1339 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001340 ALOGD("setting scan oui %p", handle);
1341
1342 static const unsigned oui_len = 3; /* OUI is upper 3 bytes of mac_address */
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001343 int len = helper.getArrayLength(param);
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001344 if (len != oui_len) {
1345 ALOGE("invalid oui length %d", len);
1346 return false;
1347 }
1348
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001349 ScopedBytesRO paramBytes(env, param);
1350 const jbyte* bytes = paramBytes.get();
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001351 if (bytes == NULL) {
1352 ALOGE("failed to get array");
1353 return false;
1354 }
1355
xinheec61e772015-03-30 18:39:12 -07001356 return hal_fn.wifi_set_scanning_mac_oui(handle, (byte *)bytes) == WIFI_SUCCESS;
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001357}
1358
xinheee0a0132015-08-04 14:27:27 -07001359static jboolean android_net_wifi_is_get_channels_for_band_supported(JNIEnv *env, jclass cls){
1360 return (hal_fn.wifi_get_valid_channels == wifi_get_valid_channels_stub);
1361}
1362
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001363static jintArray android_net_wifi_getValidChannels(JNIEnv *env, jclass cls,
1364 jint iface, jint band) {
1365
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001366 JNIHelper helper(env);
1367 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001368 ALOGD("getting valid channels %p", handle);
1369
1370 static const int MaxChannels = 64;
1371 wifi_channel channels[64];
1372 int num_channels = 0;
xinheec61e772015-03-30 18:39:12 -07001373 wifi_error result = hal_fn.wifi_get_valid_channels(handle, band, MaxChannels,
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001374 channels, &num_channels);
1375
1376 if (result == WIFI_SUCCESS) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001377 JNIObject<jintArray> channelArray = helper.newIntArray(num_channels);
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001378 if (channelArray == NULL) {
1379 ALOGE("failed to allocate channel list");
1380 return NULL;
1381 }
1382
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001383 helper.setIntArrayRegion(channelArray, 0, num_channels, channels);
1384 return channelArray.detach();
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001385 } else {
1386 ALOGE("failed to get channel list : %d", result);
1387 return NULL;
1388 }
1389}
1390
Vinit Deshpande90b902d2014-10-13 13:21:47 -07001391static jboolean android_net_wifi_setDfsFlag(JNIEnv *env, jclass cls, jint iface, jboolean dfs) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001392
1393 JNIHelper helper(env);
1394 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande90b902d2014-10-13 13:21:47 -07001395 ALOGD("setting dfs flag to %s, %p", dfs ? "true" : "false", handle);
1396
1397 u32 nodfs = dfs ? 0 : 1;
xinheec61e772015-03-30 18:39:12 -07001398 wifi_error result = hal_fn.wifi_set_nodfs_flag(handle, nodfs);
Vinit Deshpande90b902d2014-10-13 13:21:47 -07001399 return result == WIFI_SUCCESS;
1400}
1401
xinhe12cf3882015-03-12 18:38:54 -07001402static jobject android_net_wifi_get_rtt_capabilities(JNIEnv *env, jclass cls, jint iface) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001403
1404 JNIHelper helper(env);
xinhe12cf3882015-03-12 18:38:54 -07001405 wifi_rtt_capabilities rtt_capabilities;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001406 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinheec61e772015-03-30 18:39:12 -07001407 wifi_error ret = hal_fn.wifi_get_rtt_capabilities(handle, &rtt_capabilities);
xinhe12cf3882015-03-12 18:38:54 -07001408
1409 if(WIFI_SUCCESS == ret) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001410 JNIObject<jobject> capabilities = helper.createObject(
1411 "android/net/wifi/RttManager$RttCapabilities");
1412 helper.setBooleanField(capabilities, "oneSidedRttSupported",
xinhe12cf3882015-03-12 18:38:54 -07001413 rtt_capabilities.rtt_one_sided_supported == 1);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001414 helper.setBooleanField(capabilities, "twoSided11McRttSupported",
xinhe12cf3882015-03-12 18:38:54 -07001415 rtt_capabilities.rtt_ftm_supported == 1);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001416 helper.setBooleanField(capabilities, "lciSupported",
xinhe12cf3882015-03-12 18:38:54 -07001417 rtt_capabilities.lci_support);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001418 helper.setBooleanField(capabilities, "lcrSupported",
xinhe12cf3882015-03-12 18:38:54 -07001419 rtt_capabilities.lcr_support);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001420 helper.setIntField(capabilities, "preambleSupported",
xinhe12cf3882015-03-12 18:38:54 -07001421 rtt_capabilities.preamble_support);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001422 helper.setIntField(capabilities, "bwSupported",
xinhe12cf3882015-03-12 18:38:54 -07001423 rtt_capabilities.bw_support);
1424 ALOGD("One side RTT is: %s", rtt_capabilities.rtt_one_sided_supported ==1 ? "support" :
1425 "not support");
1426 ALOGD("Two side RTT is: %s", rtt_capabilities.rtt_ftm_supported == 1 ? "support" :
1427 "not support");
1428 ALOGD("LCR is: %s", rtt_capabilities.lcr_support == 1 ? "support" : "not support");
1429
1430 ALOGD("LCI is: %s", rtt_capabilities.lci_support == 1 ? "support" : "not support");
1431
1432 ALOGD("Support Preamble is : %d support BW is %d", rtt_capabilities.preamble_support,
1433 rtt_capabilities.bw_support);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001434 return capabilities.detach();
xinhe12cf3882015-03-12 18:38:54 -07001435 } else {
1436 return NULL;
1437 }
1438}
1439
xinhe939177f2015-03-23 14:43:03 -07001440static jboolean android_net_wifi_set_Country_Code_Hal(JNIEnv *env,jclass cls, jint iface,
1441 jstring country_code) {
1442
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001443 JNIHelper helper(env);
1444 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
1445
1446 ScopedUtfChars chars(env, country_code);
1447 const char *country = chars.c_str();
xinhe939177f2015-03-23 14:43:03 -07001448
1449 ALOGD("set country code: %s", country);
xinhe44787b52015-04-02 09:41:57 -07001450 wifi_error res = hal_fn.wifi_set_country_code(handle, country);
xinhe939177f2015-03-23 14:43:03 -07001451 return res == WIFI_SUCCESS;
1452}
xinhed57f6302015-04-15 13:23:43 -07001453
1454static jboolean android_net_wifi_enable_disable_tdls(JNIEnv *env,jclass cls, jint iface,
1455 jboolean enable, jstring addr) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001456
1457 JNIHelper helper(env);
1458 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhed57f6302015-04-15 13:23:43 -07001459
1460 mac_addr address;
1461 parseMacAddress(env, addr, address);
1462 wifi_tdls_handler tdls_handler;
1463 //tdls_handler.on_tdls_state_changed = &on_tdls_state_changed;
1464
1465 if(enable) {
1466 return (hal_fn.wifi_enable_tdls(handle, address, NULL, tdls_handler) == WIFI_SUCCESS);
1467 } else {
1468 return (hal_fn.wifi_disable_tdls(handle, address) == WIFI_SUCCESS);
1469 }
1470}
1471
1472static void on_tdls_state_changed(mac_addr addr, wifi_tdls_status status) {
xinhed57f6302015-04-15 13:23:43 -07001473
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001474 JNIHelper helper(mVM);
1475
1476 ALOGD("on_tdls_state_changed is called: vm = %p, obj = %p", mVM, mCls);
xinhed57f6302015-04-15 13:23:43 -07001477
1478 char mac[32];
1479 sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4],
1480 addr[5]);
1481
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001482 JNIObject<jstring> mac_address = helper.newStringUTF(mac);
1483 helper.reportEvent(mCls, "onTdlsStatus", "(Ljava/lang/StringII;)V",
1484 mac_address.get(), status.state, status.reason);
xinhed57f6302015-04-15 13:23:43 -07001485
1486}
1487
1488static jobject android_net_wifi_get_tdls_status(JNIEnv *env,jclass cls, jint iface,jstring addr) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001489
1490 JNIHelper helper(env);
1491 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhed57f6302015-04-15 13:23:43 -07001492
1493 mac_addr address;
1494 parseMacAddress(env, addr, address);
1495
1496 wifi_tdls_status status;
1497
1498 wifi_error ret;
1499 ret = hal_fn.wifi_get_tdls_status(handle, address, &status );
1500
1501 if (ret != WIFI_SUCCESS) {
1502 return NULL;
1503 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001504 JNIObject<jobject> tdls_status = helper.createObject(
1505 "com/android/server/wifi/WifiNative$TdlsStatus");
1506 helper.setIntField(tdls_status, "channel", status.channel);
1507 helper.setIntField(tdls_status, "global_operating_class", status.global_operating_class);
1508 helper.setIntField(tdls_status, "state", status.state);
1509 helper.setIntField(tdls_status, "reason", status.reason);
1510 return tdls_status.detach();
xinhed57f6302015-04-15 13:23:43 -07001511 }
1512}
1513
1514static jobject android_net_wifi_get_tdls_capabilities(JNIEnv *env, jclass cls, jint iface) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001515
1516 JNIHelper helper(env);
xinhed57f6302015-04-15 13:23:43 -07001517 wifi_tdls_capabilities tdls_capabilities;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001518 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhed57f6302015-04-15 13:23:43 -07001519 wifi_error ret = hal_fn.wifi_get_tdls_capabilities(handle, &tdls_capabilities);
1520
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001521 if (WIFI_SUCCESS == ret) {
1522 JNIObject<jobject> capabilities = helper.createObject(
xinhed57f6302015-04-15 13:23:43 -07001523 "com/android/server/wifi/WifiNative$TdlsCapabilities");
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001524 helper.setIntField(capabilities, "maxConcurrentTdlsSessionNumber",
xinhed57f6302015-04-15 13:23:43 -07001525 tdls_capabilities.max_concurrent_tdls_session_num);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001526 helper.setBooleanField(capabilities, "isGlobalTdlsSupported",
xinhed57f6302015-04-15 13:23:43 -07001527 tdls_capabilities.is_global_tdls_supported == 1);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001528 helper.setBooleanField(capabilities, "isPerMacTdlsSupported",
xinhed57f6302015-04-15 13:23:43 -07001529 tdls_capabilities.is_per_mac_tdls_supported == 1);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001530 helper.setBooleanField(capabilities, "isOffChannelTdlsSupported",
xinhed57f6302015-04-15 13:23:43 -07001531 tdls_capabilities.is_off_channel_tdls_supported);
1532
1533 ALOGD("TDLS Max Concurrent Tdls Session Number is: %d",
1534 tdls_capabilities.max_concurrent_tdls_session_num);
1535 ALOGD("Global Tdls is: %s", tdls_capabilities.is_global_tdls_supported == 1 ? "support" :
1536 "not support");
1537 ALOGD("Per Mac Tdls is: %s", tdls_capabilities.is_per_mac_tdls_supported == 1 ? "support" :
1538 "not support");
1539 ALOGD("Off Channel Tdls is: %s", tdls_capabilities.is_off_channel_tdls_supported == 1 ?
1540 "support" : "not support");
1541
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001542 return capabilities.detach();
xinhed57f6302015-04-15 13:23:43 -07001543 } else {
1544 return NULL;
1545 }
1546}
1547
Vinit Deshpande155b9d02014-01-08 23:46:46 +00001548// ----------------------------------------------------------------------------
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001549// Debug framework
1550// ----------------------------------------------------------------------------
xinhe03ba4a52015-04-28 14:40:44 -07001551static jint android_net_wifi_get_supported_logger_feature(JNIEnv *env, jclass cls, jint iface){
1552 //Not implemented yet
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001553 JNIHelper helper(env);
1554 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001555 return -1;
1556}
1557
1558static jobject android_net_wifi_get_driver_version(JNIEnv *env, jclass cls, jint iface) {
1559 //Need to be fixed. The memory should be allocated from lower layer
1560 //char *buffer = NULL;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001561 JNIHelper helper(env);
xinhe03ba4a52015-04-28 14:40:44 -07001562 int buffer_length = 256;
xinhe6d0cd102015-05-05 11:10:08 -07001563 char *buffer = (char *)malloc(buffer_length);
1564 if (!buffer) return NULL;
1565 memset(buffer, 0, buffer_length);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001566 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001567
1568 ALOGD("android_net_wifi_get_driver_version = %p", handle);
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001569
1570 if (handle == 0) {
xinhe03ba4a52015-04-28 14:40:44 -07001571 return NULL;
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001572 }
xinhe03ba4a52015-04-28 14:40:44 -07001573
xinhe6d0cd102015-05-05 11:10:08 -07001574 wifi_error result = hal_fn.wifi_get_driver_version(handle, buffer, buffer_length);
xinhe03ba4a52015-04-28 14:40:44 -07001575
1576 if (result == WIFI_SUCCESS) {
1577 ALOGD("buffer is %p, length is %d", buffer, buffer_length);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001578 JNIObject<jstring> driver_version = helper.newStringUTF(buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001579 free(buffer);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001580 return driver_version.detach();
xinhe03ba4a52015-04-28 14:40:44 -07001581 } else {
1582 ALOGD("Fail to get driver version");
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001583 free(buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001584 return NULL;
1585 }
1586}
1587
1588static jobject android_net_wifi_get_firmware_version(JNIEnv *env, jclass cls, jint iface) {
1589
1590 //char *buffer = NULL;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001591 JNIHelper helper(env);
xinhe03ba4a52015-04-28 14:40:44 -07001592 int buffer_length = 256;
1593 char *buffer = (char *)malloc(buffer_length);
xinhe6d0cd102015-05-05 11:10:08 -07001594 if (!buffer) return NULL;
1595 memset(buffer, 0, buffer_length);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001596 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001597
1598 ALOGD("android_net_wifi_get_firmware_version = %p", handle);
1599
1600 if (handle == 0) {
1601 return NULL;
1602 }
1603
xinhe6d0cd102015-05-05 11:10:08 -07001604 wifi_error result = hal_fn.wifi_get_firmware_version(handle, buffer, buffer_length);
xinhe03ba4a52015-04-28 14:40:44 -07001605
1606 if (result == WIFI_SUCCESS) {
1607 ALOGD("buffer is %p, length is %d", buffer, buffer_length);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001608 JNIObject<jstring> firmware_version = helper.newStringUTF(buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001609 free(buffer);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001610 return firmware_version.detach();
xinhe03ba4a52015-04-28 14:40:44 -07001611 } else {
1612 ALOGD("Fail to get Firmware version");
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001613 free(buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001614 return NULL;
1615 }
1616}
1617
1618static jobject android_net_wifi_get_ring_buffer_status (JNIEnv *env, jclass cls, jint iface) {
1619
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001620 JNIHelper helper(env);
1621 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001622
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001623 ALOGD("android_net_wifi_get_ring_buffer_status = %p", handle);
xinhe03ba4a52015-04-28 14:40:44 -07001624
1625 if (handle == 0) {
1626 return NULL;
1627 }
1628
1629 //wifi_ring_buffer_status *status = NULL;
1630 u32 num_rings = 10;
1631 wifi_ring_buffer_status *status =
1632 (wifi_ring_buffer_status *)malloc(sizeof(wifi_ring_buffer_status) * num_rings);
xinhe6d0cd102015-05-05 11:10:08 -07001633 if (!status) return NULL;
1634 memset(status, 0, sizeof(wifi_ring_buffer_status) * num_rings);
1635 wifi_error result = hal_fn.wifi_get_ring_buffers_status(handle, &num_rings, status);
xinhe03ba4a52015-04-28 14:40:44 -07001636 if (result == WIFI_SUCCESS) {
1637 ALOGD("status is %p, number is %d", status, num_rings);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001638
1639 JNIObject<jobjectArray> ringBuffersStatus = helper.newObjectArray(
1640 num_rings, "com/android/server/wifi/WifiNative$RingBufferStatus", NULL);
1641
xinhe03ba4a52015-04-28 14:40:44 -07001642 wifi_ring_buffer_status *tmp = status;
1643
1644 for(u32 i = 0; i < num_rings; i++, tmp++) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001645
1646 JNIObject<jobject> ringStatus = helper.createObject(
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001647 "com/android/server/wifi/WifiNative$RingBufferStatus");
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001648
xinhe03ba4a52015-04-28 14:40:44 -07001649 if (ringStatus == NULL) {
1650 ALOGE("Error in creating ringBufferStatus");
1651 free(status);
1652 return NULL;
1653 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001654
xinhe03ba4a52015-04-28 14:40:44 -07001655 char name[32];
1656 for(int j = 0; j < 32; j++) {
1657 name[j] = tmp->name[j];
1658 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001659
1660 helper.setStringField(ringStatus, "name", name);
1661 helper.setIntField(ringStatus, "flag", tmp->flags);
1662 helper.setIntField(ringStatus, "ringBufferId", tmp->ring_id);
1663 helper.setIntField(ringStatus, "ringBufferByteSize", tmp->ring_buffer_byte_size);
1664 helper.setIntField(ringStatus, "verboseLevel", tmp->verbose_level);
1665 helper.setIntField(ringStatus, "writtenBytes", tmp->written_bytes);
1666 helper.setIntField(ringStatus, "readBytes", tmp->read_bytes);
1667 helper.setIntField(ringStatus, "writtenRecords", tmp->written_records);
1668
1669 helper.setObjectArrayElement(ringBuffersStatus, i, ringStatus);
xinhe03ba4a52015-04-28 14:40:44 -07001670 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001671
xinhe03ba4a52015-04-28 14:40:44 -07001672 free(status);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001673 return ringBuffersStatus.detach();
xinhe03ba4a52015-04-28 14:40:44 -07001674 } else {
xinhe6d0cd102015-05-05 11:10:08 -07001675 free(status);
xinhe03ba4a52015-04-28 14:40:44 -07001676 return NULL;
1677 }
1678}
1679
1680static void on_ring_buffer_data(char *ring_name, char *buffer, int buffer_size,
1681 wifi_ring_buffer_status *status) {
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001682
Jerry Lee6111ff72015-05-11 15:10:03 -07001683 if (!ring_name || !buffer || !status ||
1684 (unsigned int)buffer_size <= sizeof(wifi_ring_buffer_entry)) {
xinhe03ba4a52015-04-28 14:40:44 -07001685 ALOGE("Error input for on_ring_buffer_data!");
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001686 return;
xinhe03ba4a52015-04-28 14:40:44 -07001687 }
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001688
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001689
1690 JNIHelper helper(mVM);
Vinit Deshpande64143012015-06-25 12:41:57 -07001691 /* ALOGD("on_ring_buffer_data called, vm = %p, obj = %p, env = %p buffer size = %d", mVM,
1692 mCls, env, buffer_size); */
xinhe03ba4a52015-04-28 14:40:44 -07001693
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001694 JNIObject<jobject> ringStatus = helper.createObject(
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001695 "com/android/server/wifi/WifiNative$RingBufferStatus");
xinhe03ba4a52015-04-28 14:40:44 -07001696 if (status == NULL) {
1697 ALOGE("Error in creating ringBufferStatus");
1698 return;
1699 }
1700
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001701 helper.setStringField(ringStatus, "name", ring_name);
1702 helper.setIntField(ringStatus, "flag", status->flags);
1703 helper.setIntField(ringStatus, "ringBufferId", status->ring_id);
1704 helper.setIntField(ringStatus, "ringBufferByteSize", status->ring_buffer_byte_size);
1705 helper.setIntField(ringStatus, "verboseLevel", status->verbose_level);
1706 helper.setIntField(ringStatus, "writtenBytes", status->written_bytes);
1707 helper.setIntField(ringStatus, "readBytes", status->read_bytes);
1708 helper.setIntField(ringStatus, "writtenRecords", status->written_records);
xinhe03ba4a52015-04-28 14:40:44 -07001709
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001710 JNIObject<jbyteArray> bytes = helper.newByteArray(buffer_size);
1711 helper.setByteArrayRegion(bytes, 0, buffer_size, (jbyte*)buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001712
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001713 helper.reportEvent(mCls,"onRingBufferData",
1714 "(Lcom/android/server/wifi/WifiNative$RingBufferStatus;[B)V",
1715 ringStatus.get(), bytes.get());
xinhe03ba4a52015-04-28 14:40:44 -07001716}
1717
1718static void on_alert_data(wifi_request_id id, char *buffer, int buffer_size, int err_code){
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001719
1720 JNIHelper helper(mVM);
1721 ALOGD("on_alert_data called, vm = %p, obj = %p, buffer_size = %d, error code = %d"
1722 , mVM, mCls, buffer_size, err_code);
xinhe03ba4a52015-04-28 14:40:44 -07001723
1724 if (buffer_size > 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001725 JNIObject<jbyteArray> records = helper.newByteArray(buffer_size);
xinhe03ba4a52015-04-28 14:40:44 -07001726 jbyte *bytes = (jbyte *) buffer;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001727 helper.setByteArrayRegion(records, 0,buffer_size, bytes);
1728 helper.reportEvent(mCls,"onWifiAlert","([BI)V", records.get(), err_code);
xinhe03ba4a52015-04-28 14:40:44 -07001729 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001730 helper.reportEvent(mCls,"onWifiAlert","([BI)V", NULL, err_code);
xinhe03ba4a52015-04-28 14:40:44 -07001731 }
1732}
1733
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07001734
xinhe03ba4a52015-04-28 14:40:44 -07001735static jboolean android_net_wifi_start_logging_ring_buffer(JNIEnv *env, jclass cls, jint iface,
1736 jint verbose_level,jint flags, jint max_interval,jint min_data_size, jstring ring_name) {
1737
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001738 JNIHelper helper(env);
1739 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001740
1741 ALOGD("android_net_wifi_start_logging_ring_buffer = %p", handle);
1742
1743 if (handle == 0) {
1744 return false;
1745 }
1746
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001747 ScopedUtfChars chars(env, ring_name);
1748 const char* ring_name_const_char = chars.c_str();
1749 int ret = hal_fn.wifi_start_logging(handle, verbose_level,
1750 flags, max_interval, min_data_size, const_cast<char *>(ring_name_const_char));
xinhe03ba4a52015-04-28 14:40:44 -07001751
1752 if (ret != WIFI_SUCCESS) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001753 ALOGE("Fail to start logging for ring %s", ring_name_const_char);
xinhe03ba4a52015-04-28 14:40:44 -07001754 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001755 ALOGD("start logging for ring %s", ring_name_const_char);
xinhe03ba4a52015-04-28 14:40:44 -07001756 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001757
xinhe03ba4a52015-04-28 14:40:44 -07001758 return ret == WIFI_SUCCESS;
1759}
1760
1761static jboolean android_net_wifi_get_ring_buffer_data(JNIEnv *env, jclass cls, jint iface,
1762 jstring ring_name) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001763
1764 JNIHelper helper(env);
1765 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande64143012015-06-25 12:41:57 -07001766 // ALOGD("android_net_wifi_get_ring_buffer_data = %p", handle);
xinhe03ba4a52015-04-28 14:40:44 -07001767
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001768 ScopedUtfChars chars(env, ring_name);
1769 const char* ring_name_const_char = chars.c_str();
1770 int result = hal_fn.wifi_get_ring_data(handle, const_cast<char *>(ring_name_const_char));
xinhe03ba4a52015-04-28 14:40:44 -07001771 return result == WIFI_SUCCESS;
1772}
1773
1774
1775void on_firmware_memory_dump(char *buffer, int buffer_size) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001776
1777 JNIHelper helper(mVM);
Vinit Deshpande64143012015-06-25 12:41:57 -07001778 /* ALOGD("on_firmware_memory_dump called, vm = %p, obj = %p, env = %p buffer_size = %d"
1779 , mVM, mCls, env, buffer_size); */
xinhe03ba4a52015-04-28 14:40:44 -07001780
1781 if (buffer_size > 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001782 JNIObject<jbyteArray> dump = helper.newByteArray(buffer_size);
xinhe03ba4a52015-04-28 14:40:44 -07001783 jbyte *bytes = (jbyte *) (buffer);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001784 helper.setByteArrayRegion(dump, 0, buffer_size, bytes);
1785 helper.reportEvent(mCls,"onWifiFwMemoryAvailable","([B)V", dump.get());
xinhe03ba4a52015-04-28 14:40:44 -07001786 }
xinhe03ba4a52015-04-28 14:40:44 -07001787}
1788
1789static jboolean android_net_wifi_get_fw_memory_dump(JNIEnv *env, jclass cls, jint iface){
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001790
1791 JNIHelper helper(env);
1792 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande64143012015-06-25 12:41:57 -07001793 // ALOGD("android_net_wifi_get_fw_memory_dump = %p", handle);
xinhe03ba4a52015-04-28 14:40:44 -07001794
1795 if (handle == NULL) {
1796 ALOGE("Can not get wifi_interface_handle");
1797 return false;
1798 }
1799
1800 wifi_firmware_memory_dump_handler fw_dump_handle;
1801 fw_dump_handle.on_firmware_memory_dump = on_firmware_memory_dump;
1802 int result = hal_fn.wifi_get_firmware_memory_dump(handle, fw_dump_handle);
1803 return result == WIFI_SUCCESS;
1804
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001805}
1806
xinheb7978932015-06-25 17:57:21 -07001807static jboolean android_net_wifi_set_log_handler(JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001808
1809 JNIHelper helper(env);
1810 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinheb7978932015-06-25 17:57:21 -07001811 ALOGD("android_net_wifi_set_log_handler = %p", handle);
1812
1813 //initialize the handler on first time
1814 wifi_ring_buffer_data_handler handler;
1815 handler.on_ring_buffer_data = &on_ring_buffer_data;
1816 int result = hal_fn.wifi_set_log_handler(id, handle, handler);
1817 if (result != WIFI_SUCCESS) {
1818 ALOGE("Fail to set logging handler");
1819 return false;
1820 }
1821
1822 //set alter handler This will start alert too
1823 wifi_alert_handler alert_handler;
1824 alert_handler.on_alert = &on_alert_data;
1825 result = hal_fn.wifi_set_alert_handler(id, handle, alert_handler);
1826 if (result != WIFI_SUCCESS) {
1827 ALOGE(" Fail to set alert handler");
1828 return false;
1829 }
1830
1831 return true;
1832}
1833
1834static jboolean android_net_wifi_reset_log_handler(JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001835
1836 JNIHelper helper(env);
1837 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Jerry Lee370ad502015-07-13 13:42:21 -07001838
1839 //reset alter handler
1840 ALOGD("android_net_wifi_reset_alert_handler = %p", handle);
1841 int result = hal_fn.wifi_reset_alert_handler(id, handle);
1842 if (result != WIFI_SUCCESS) {
1843 ALOGE(" Fail to reset alert handler");
1844 return false;
1845 }
1846
1847 //reset log handler
xinheb7978932015-06-25 17:57:21 -07001848 ALOGD("android_net_wifi_reset_log_handler = %p", handle);
Jerry Lee370ad502015-07-13 13:42:21 -07001849 result = hal_fn.wifi_reset_log_handler(id, handle);
1850 if (result != WIFI_SUCCESS) {
1851 ALOGE("Fail to reset logging handler");
1852 return false;
1853 }
1854
1855 return true;
xinheb7978932015-06-25 17:57:21 -07001856}
Jerry Lee370ad502015-07-13 13:42:21 -07001857
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001858// ----------------------------------------------------------------------------
1859// ePno framework
1860// ----------------------------------------------------------------------------
1861
1862
1863static void onPnoNetworkFound(wifi_request_id id,
1864 unsigned num_results, wifi_scan_result *results) {
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001865
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001866 JNIHelper helper(mVM);
1867
1868 ALOGD("onPnoNetworkFound called, vm = %p, obj = %p, num_results %u", mVM, mCls, num_results);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001869
1870 if (results == 0 || num_results == 0) {
1871 ALOGE("onPnoNetworkFound: Error no results");
1872 return;
1873 }
1874
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001875 jbyte *bytes;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001876 JNIObject<jobjectArray> scanResults(helper, NULL);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001877 //jbyteArray elements;
1878
1879 for (unsigned i=0; i<num_results; i++) {
1880
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001881 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001882 if (i == 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001883 scanResults = helper.newObjectArray(
1884 num_results, "android/net/wifi/ScanResult", scanResult);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001885 if (scanResults == 0) {
1886 ALOGD("cant allocate array");
1887 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001888 ALOGD("allocated array %u", helper.getArrayLength(scanResults));
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001889 }
1890 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001891 helper.setObjectArrayElement(scanResults, i, scanResult);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001892 }
1893
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07001894 ALOGD("Scan result with ie length %d, i %u, <%s> rssi=%d %02x:%02x:%02x:%02x:%02x:%02x",
xinhe6d0cd102015-05-05 11:10:08 -07001895 results->ie_length, i, results[i].ssid, results[i].rssi, results[i].bssid[0],
1896 results[i].bssid[1],results[i].bssid[2], results[i].bssid[3], results[i].bssid[4],
1897 results[i].bssid[5]);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001898
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001899 /*elements = helper.newByteArray(results->ie_length);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001900 if (elements == NULL) {
1901 ALOGE("Error in allocating array");
1902 return;
1903 }*/
1904
1905 //ALOGD("onPnoNetworkFound: Setting byte array");
1906
1907 //bytes = (jbyte *)&(results->ie_data[0]);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001908 //helper.setByteArrayRegion(elements, 0, results->ie_length, bytes);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001909
1910 //ALOGD("onPnoNetworkFound: Returning result");
1911 }
1912
1913
1914 ALOGD("calling report");
1915
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001916 helper.reportEvent(mCls, "onPnoNetworkFound", "(I[Landroid/net/wifi/ScanResult;)V", id,
1917 scanResults.get());
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001918 ALOGD("free ref");
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001919}
1920
1921static jboolean android_net_wifi_setPnoListNative(
1922 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {
1923
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001924 JNIHelper helper(env);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001925 wifi_epno_handler handler;
1926 handler.on_network_found = &onPnoNetworkFound;
1927
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001928 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001929 ALOGD("configure ePno list request [%d] = %p", id, handle);
1930
1931 if (list == NULL) {
1932 // stop pno
1933 int result = hal_fn.wifi_set_epno_list(id, handle, 0, NULL, handler);
1934 ALOGE(" setPnoListNative: STOP result = %d", result);
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07001935 return result >= 0;
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001936 }
1937
1938 wifi_epno_network net_list[MAX_PNO_SSID];
1939 memset(&net_list, 0, sizeof(net_list));
1940
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001941 size_t len = helper.getArrayLength((jobjectArray)list);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001942 if (len > (size_t)MAX_PNO_SSID) {
1943 return false;
1944 }
1945
1946 for (unsigned int i = 0; i < len; i++) {
1947
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001948 JNIObject<jobject> pno_net = helper.getObjectArrayElement((jobjectArray)list, i);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001949 if (pno_net == NULL) {
1950 ALOGD("setPnoListNative: could not get element %d", i);
1951 continue;
1952 }
1953
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001954 JNIObject<jstring> sssid = helper.getStringField(pno_net, "SSID");
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001955 if (sssid == NULL) {
1956 ALOGE("Error setPnoListNative: getting ssid field");
1957 return false;
1958 }
1959
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001960 ScopedUtfChars chars(env, (jstring)sssid.get());
1961 const char *ssid = chars.c_str();
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001962 if (ssid == NULL) {
1963 ALOGE("Error setPnoListNative: getting ssid");
1964 return false;
1965 }
1966 int ssid_len = strnlen((const char*)ssid, 33);
1967 if (ssid_len > 32) {
1968 ALOGE("Error setPnoListNative: long ssid %u", strnlen((const char*)ssid, 256));
1969 return false;
1970 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001971
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001972 if (ssid_len > 1 && ssid[0] == '"' && ssid[ssid_len-1])
1973 {
1974 // strip leading and trailing '"'
1975 ssid++;
1976 ssid_len-=2;
1977 }
1978 if (ssid_len == 0) {
1979 ALOGE("Error setPnoListNative: zero length ssid, skip it");
1980 continue;
1981 }
1982 memcpy(net_list[i].ssid, ssid, ssid_len);
1983
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001984 int rssit = helper.getIntField(pno_net, "rssi_threshold");
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001985 net_list[i].rssi_threshold = (byte)rssit;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001986 int a = helper.getIntField(pno_net, "auth");
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001987 net_list[i].auth_bit_field = a;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001988 int f = helper.getIntField(pno_net, "flags");
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001989 net_list[i].flags = f;
xinhe03ba4a52015-04-28 14:40:44 -07001990 ALOGE(" setPnoListNative: idx %u rssi %d/%d auth %x/%x flags %x/%x [%s]", i,
Vinit Deshpandee5bf4b82015-05-13 18:38:10 -07001991 (signed)net_list[i].rssi_threshold, net_list[i].rssi_threshold,
xinhe03ba4a52015-04-28 14:40:44 -07001992 net_list[i].auth_bit_field, a, net_list[i].flags, f, net_list[i].ssid);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001993 }
1994
1995 int result = hal_fn.wifi_set_epno_list(id, handle, len, net_list, handler);
1996 ALOGE(" setPnoListNative: result %d", result);
1997
1998 return result >= 0;
1999}
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07002000
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002001static jboolean android_net_wifi_setLazyRoam(
2002 JNIEnv *env, jclass cls, jint iface, jint id, jboolean enabled, jobject roam_param) {
2003
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002004 JNIHelper helper(env);
Vinit Deshpandef49a59b2015-05-27 11:24:47 -07002005 wifi_error status = WIFI_SUCCESS;
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002006 wifi_roam_params params;
2007 memset(&params, 0, sizeof(params));
2008
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002009 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002010 ALOGD("configure lazy roam request [%d] = %p", id, handle);
2011
2012 if (roam_param != NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002013 params.A_band_boost_threshold = helper.getIntField(roam_param, "A_band_boost_threshold");
2014 params.A_band_penalty_threshold = helper.getIntField(roam_param, "A_band_penalty_threshold");
2015 params.A_band_boost_factor = helper.getIntField(roam_param, "A_band_boost_factor");
2016 params.A_band_penalty_factor = helper.getIntField(roam_param, "A_band_penalty_factor");
2017 params.A_band_max_boost = helper.getIntField(roam_param, "A_band_max_boost");
2018 params.lazy_roam_hysteresis = helper.getIntField(roam_param, "lazy_roam_hysteresis");
2019 params.alert_roam_rssi_trigger = helper.getIntField(roam_param, "alert_roam_rssi_trigger");
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002020 status = hal_fn.wifi_set_gscan_roam_params(id, handle, &params);
2021 }
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07002022 ALOGE("android_net_wifi_setLazyRoam configured params status=%d\n", status);
2023
2024 if (status >= 0) {
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002025 int doEnable = enabled ? 1 : 0;
2026 status = hal_fn.wifi_enable_lazy_roam(id, handle, doEnable);
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07002027 ALOGE("android_net_wifi_setLazyRoam enabled roam status=%d\n", status);
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002028 }
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07002029 return status >= 0;
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002030}
2031
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002032static jboolean android_net_wifi_setBssidBlacklist(
2033 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {
2034
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002035 JNIHelper helper(env);
2036 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002037 ALOGD("configure BSSID black list request [%d] = %p", id, handle);
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002038
2039 wifi_bssid_params params;
2040 memset(&params, 0, sizeof(params));
2041
2042 if (list != NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002043 size_t len = helper.getArrayLength((jobjectArray)list);
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002044 if (len > (size_t)MAX_BLACKLIST_BSSID) {
2045 return false;
2046 }
2047 for (unsigned int i = 0; i < len; i++) {
2048
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002049 JNIObject<jobject> jbssid = helper.getObjectArrayElement(list, i);
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002050 if (jbssid == NULL) {
2051 ALOGD("configure BSSID blacklist: could not get element %d", i);
2052 continue;
2053 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002054
2055 ScopedUtfChars chars(env, (jstring)jbssid.get());
2056 const char *bssid = chars.c_str();
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002057 if (bssid == NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002058 ALOGE("Error getting bssid");
2059 return false;
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002060 }
2061
2062 mac_addr addr;
2063 parseMacAddress(bssid, addr);
2064 memcpy(params.bssids[i], addr, sizeof(mac_addr));
2065
2066 char bssidOut[32];
2067 sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1],
2068 addr[2], addr[3], addr[4], addr[5]);
2069
2070 ALOGD("BSSID blacklist: added bssid %s", bssidOut);
2071
2072 params.num_bssid++;
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002073 }
2074 }
2075
2076 ALOGD("Added %d bssids", params.num_bssid);
2077 return hal_fn.wifi_set_bssid_blacklist(id, handle, params) == WIFI_SUCCESS;
2078}
2079
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002080static jboolean android_net_wifi_setSsidWhitelist(
2081 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {
2082
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002083 JNIHelper helper(env);
2084 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002085 ALOGD("configure SSID white list request [%d] = %p", id, handle);
2086 wifi_ssid *ssids = NULL;
2087 int num_ssids = 0;
2088 if (list != NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002089 size_t len = helper.getArrayLength((jobjectArray)list);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002090 if (len > 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002091 ssids = (wifi_ssid *)malloc(len * sizeof (wifi_ssid));
2092 if (!ssids) return false;
2093 memset(ssids, 0, len * sizeof (wifi_ssid));
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002094 for (unsigned int i = 0; i < len; i++) {
2095
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002096 JNIObject<jobject> jssid = helper.getObjectArrayElement(list, i);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002097 if (jssid == NULL) {
2098 ALOGD("configure SSID whitelist: could not get element %d", i);
2099 free(ssids);
2100 return false;
2101 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002102
2103 ScopedUtfChars chars(env, (jstring)jssid.get());
2104 const char *utf = chars.c_str();
2105 if (utf == NULL) {
2106 ALOGE("Error getting sssid");
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002107 free(ssids);
2108 return false;
2109 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002110
2111 int slen = strnlen(utf, 33);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002112 if (slen <= 0 || slen > 32) {
2113 ALOGE("Error wrong ssid length %d", slen);
2114 free(ssids);
2115 return false;
2116 }
2117
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002118 memcpy(ssids[i].ssid, utf, slen);
Pierre Vandwallebe2981a2015-05-20 18:20:45 -07002119 num_ssids++;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002120 ALOGD("SSID white list: added ssid %s", utf);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002121 }
2122 }
2123 }
2124
2125 ALOGD("android_net_wifi_setSsidWhitelist Added %d sssids", num_ssids);
2126 return hal_fn.wifi_set_ssid_white_list(id, handle, num_ssids, ssids) == WIFI_SUCCESS;
2127}
2128
Vinit Deshpande155b9d02014-01-08 23:46:46 +00002129// ----------------------------------------------------------------------------
2130
2131/*
2132 * JNI registration.
2133 */
2134static JNINativeMethod gWifiMethods[] = {
2135 /* name, signature, funcPtr */
2136
2137 { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
2138 { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded },
2139 { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
2140 { "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant },
2141 { "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant },
2142 { "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant },
2143 { "closeSupplicantConnectionNative", "()V",
2144 (void *)android_net_wifi_closeSupplicantConnection },
2145 { "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForEvent },
2146 { "doBooleanCommandNative", "(Ljava/lang/String;)Z", (void*)android_net_wifi_doBooleanCommand },
2147 { "doIntCommandNative", "(Ljava/lang/String;)I", (void*)android_net_wifi_doIntCommand },
2148 { "doStringCommandNative", "(Ljava/lang/String;)Ljava/lang/String;",
2149 (void*) android_net_wifi_doStringCommand },
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -08002150 { "startHalNative", "()Z", (void*) android_net_wifi_startHal },
2151 { "stopHalNative", "()V", (void*) android_net_wifi_stopHal },
2152 { "waitForHalEventNative", "()V", (void*) android_net_wifi_waitForHalEvents },
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07002153 { "getInterfacesNative", "()I", (void*) android_net_wifi_getInterfaces},
2154 { "getInterfaceNameNative", "(I)Ljava/lang/String;", (void*) android_net_wifi_getInterfaceName},
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002155 { "getScanCapabilitiesNative", "(ILcom/android/server/wifi/WifiNative$ScanCapabilities;)Z",
2156 (void *) android_net_wifi_getScanCapabilities},
2157 { "startScanNative", "(IILcom/android/server/wifi/WifiNative$ScanSettings;)Z",
2158 (void*) android_net_wifi_startScan},
2159 { "stopScanNative", "(II)Z", (void*) android_net_wifi_stopScan},
Vinit Deshpandec591ab32014-10-31 11:15:26 -07002160 { "getScanResultsNative", "(IZ)[Landroid/net/wifi/WifiScanner$ScanData;",
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002161 (void *) android_net_wifi_getScanResults},
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002162 { "setHotlistNative", "(IILandroid/net/wifi/WifiScanner$HotlistSettings;)Z",
2163 (void*) android_net_wifi_setHotlist},
2164 { "resetHotlistNative", "(II)Z", (void*) android_net_wifi_resetHotlist},
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002165 { "trackSignificantWifiChangeNative", "(IILandroid/net/wifi/WifiScanner$WifiChangeSettings;)Z",
2166 (void*) android_net_wifi_trackSignificantWifiChange},
2167 { "untrackSignificantWifiChangeNative", "(II)Z",
vandwalleaabe7a92014-05-09 18:11:02 -07002168 (void*) android_net_wifi_untrackSignificantWifiChange},
2169 { "getWifiLinkLayerStatsNative", "(I)Landroid/net/wifi/WifiLinkLayerStats;",
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07002170 (void*) android_net_wifi_getLinkLayerStats},
Pierre Vandwalled745a522015-06-11 17:48:58 -07002171 { "setWifiLinkLayerStatsNative", "(II)V",
2172 (void*) android_net_wifi_setLinkLayerStats},
Vinit Deshpandec35361d2014-08-07 16:24:10 -07002173 { "getSupportedFeatureSetNative", "(I)I",
Vinit Deshpande14365732014-06-30 15:23:23 -07002174 (void*) android_net_wifi_getSupportedFeatures},
2175 { "requestRangeNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z",
2176 (void*) android_net_wifi_requestRange},
2177 { "cancelRangeRequestNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z",
Vinit Deshpande042c54b2014-08-21 13:52:21 -07002178 (void*) android_net_wifi_cancelRange},
Vinit Deshpande90b902d2014-10-13 13:21:47 -07002179 { "setScanningMacOuiNative", "(I[B)Z", (void*) android_net_wifi_setScanningMacOui},
2180 { "getChannelsForBandNative", "(II)[I", (void*) android_net_wifi_getValidChannels},
xinheb830d762015-02-11 17:14:17 -08002181 { "setDfsFlagNative", "(IZ)Z", (void*) android_net_wifi_setDfsFlag},
xinhe12cf3882015-03-12 18:38:54 -07002182 { "toggleInterfaceNative", "(I)Z", (void*) android_net_wifi_toggle_interface},
2183 { "getRttCapabilitiesNative", "(I)Landroid/net/wifi/RttManager$RttCapabilities;",
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07002184 (void*) android_net_wifi_get_rtt_capabilities},
xinhe939177f2015-03-23 14:43:03 -07002185 {"setCountryCodeHalNative", "(ILjava/lang/String;)Z",
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07002186 (void*) android_net_wifi_set_Country_Code_Hal},
2187 { "setPnoListNative", "(II[Lcom/android/server/wifi/WifiNative$WifiPnoNetwork;)Z",
xinhed57f6302015-04-15 13:23:43 -07002188 (void*) android_net_wifi_setPnoListNative},
2189 {"enableDisableTdlsNative", "(IZLjava/lang/String;)Z",
2190 (void*) android_net_wifi_enable_disable_tdls},
2191 {"getTdlsStatusNative", "(ILjava/lang/String;)Lcom/android/server/wifi/WifiNative$TdlsStatus;",
2192 (void*) android_net_wifi_get_tdls_status},
2193 {"getTdlsCapabilitiesNative", "(I)Lcom/android/server/wifi/WifiNative$TdlsCapabilities;",
xinhe03ba4a52015-04-28 14:40:44 -07002194 (void*) android_net_wifi_get_tdls_capabilities},
2195 {"getSupportedLoggerFeatureSetNative","(I)I",
2196 (void*) android_net_wifi_get_supported_logger_feature},
2197 {"getDriverVersionNative", "(I)Ljava/lang/String;",
2198 (void*) android_net_wifi_get_driver_version},
2199 {"getFirmwareVersionNative", "(I)Ljava/lang/String;",
2200 (void*) android_net_wifi_get_firmware_version},
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07002201 {"getRingBufferStatusNative", "(I)[Lcom/android/server/wifi/WifiNative$RingBufferStatus;",
xinhe03ba4a52015-04-28 14:40:44 -07002202 (void*) android_net_wifi_get_ring_buffer_status},
2203 {"startLoggingRingBufferNative", "(IIIIILjava/lang/String;)Z",
2204 (void*) android_net_wifi_start_logging_ring_buffer},
2205 {"getRingBufferDataNative", "(ILjava/lang/String;)Z",
2206 (void*) android_net_wifi_get_ring_buffer_data},
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002207 {"getFwMemoryDumpNative","(I)Z", (void*) android_net_wifi_get_fw_memory_dump},
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002208 { "setLazyRoamNative", "(IIZLcom/android/server/wifi/WifiNative$WifiLazyRoamParams;)Z",
2209 (void*) android_net_wifi_setLazyRoam},
2210 { "setBssidBlacklistNative", "(II[Ljava/lang/String;)Z",
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002211 (void*)android_net_wifi_setBssidBlacklist},
2212 { "setSsidWhitelistNative", "(II[Ljava/lang/String;)Z",
xinheee0a0132015-08-04 14:27:27 -07002213 (void*)android_net_wifi_setSsidWhitelist},
xinheb7978932015-06-25 17:57:21 -07002214 {"setLoggingEventHandlerNative", "(II)Z", (void *) android_net_wifi_set_log_handler},
xinheee0a0132015-08-04 14:27:27 -07002215 {"resetLogHandlerNative", "(II)Z", (void *) android_net_wifi_reset_log_handler},
2216 {"isGetChannelsForBandSupportedNative", "()Z",
2217 (void*)android_net_wifi_is_get_channels_for_band_supported}
Vinit Deshpande155b9d02014-01-08 23:46:46 +00002218};
2219
2220int register_android_net_wifi_WifiNative(JNIEnv* env) {
2221 return AndroidRuntime::registerNativeMethods(env,
2222 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods));
2223}
2224
2225
2226/* User to register native functions */
2227extern "C"
2228jint Java_com_android_server_wifi_WifiNative_registerNatives(JNIEnv* env, jclass clazz) {
2229 return AndroidRuntime::registerNativeMethods(env,
2230 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods));
2231}
2232
2233}; // namespace android