blob: 1ad0b0b8211dbc906d9c974161774e2ac29f70d5 [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 Deshpandebbbafda2015-10-02 13:39:59 -070035#define REPLY_BUF_SIZE 4096 + 1 // wpa_supplicant's maximum size + 1 for nul
Vinit Deshpande155b9d02014-01-08 23:46:46 +000036#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;
Ningyuan Wang659a90e2017-05-15 14:24:41 -070046constexpr int SAFE_NET_LOG_ID = 0x534e4554;
Vinit Deshpande155b9d02014-01-08 23:46:46 +000047
xinheec61e772015-03-30 18:39:12 -070048//Please put all HAL function call here and call from the function table instead of directly call
49static wifi_hal_fn hal_fn;
50int init_wifi_hal_func_table(wifi_hal_fn *hal_fn) {
51 if (hal_fn == NULL) {
52 return -1;
53 }
54 hal_fn->wifi_initialize = wifi_initialize_stub;
55 hal_fn->wifi_cleanup = wifi_cleanup_stub;
56 hal_fn->wifi_event_loop = wifi_event_loop_stub;
57 hal_fn->wifi_get_error_info = wifi_get_error_info_stub;
58 hal_fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set_stub;
59 hal_fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix_stub;
60 hal_fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui_stub;
61 hal_fn->wifi_get_supported_channels = wifi_get_supported_channels_stub;
62 hal_fn->wifi_is_epr_supported = wifi_is_epr_supported_stub;
63 hal_fn->wifi_get_ifaces = wifi_get_ifaces_stub;
64 hal_fn->wifi_get_iface_name = wifi_get_iface_name_stub;
65 hal_fn->wifi_reset_iface_event_handler = wifi_reset_iface_event_handler_stub;
66 hal_fn->wifi_start_gscan = wifi_start_gscan_stub;
67 hal_fn->wifi_stop_gscan = wifi_stop_gscan_stub;
xin He6f7fe1c2015-04-02 21:10:12 +000068 hal_fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results_stub;
xinheec61e772015-03-30 18:39:12 -070069 hal_fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist_stub;
70 hal_fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist_stub;
71 hal_fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler_stub;
72 hal_fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler_stub;
73 hal_fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities_stub;
74 hal_fn->wifi_set_link_stats = wifi_set_link_stats_stub;
75 hal_fn->wifi_get_link_stats = wifi_get_link_stats_stub;
76 hal_fn->wifi_clear_link_stats = wifi_clear_link_stats_stub;
77 hal_fn->wifi_get_valid_channels = wifi_get_valid_channels_stub;
78 hal_fn->wifi_rtt_range_request = wifi_rtt_range_request_stub;
79 hal_fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel_stub;
80 hal_fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities_stub;
xinheec61e772015-03-30 18:39:12 -070081 hal_fn->wifi_start_logging = wifi_start_logging_stub;
82 hal_fn->wifi_set_epno_list = wifi_set_epno_list_stub;
83 hal_fn->wifi_set_country_code = wifi_set_country_code_stub;
xinhed57f6302015-04-15 13:23:43 -070084 hal_fn->wifi_enable_tdls = wifi_enable_tdls_stub;
85 hal_fn->wifi_disable_tdls = wifi_disable_tdls_stub;
86 hal_fn->wifi_get_tdls_status = wifi_get_tdls_status_stub;
87 hal_fn->wifi_get_tdls_capabilities = wifi_get_tdls_capabilities_stub;
Vinit Deshpande6f59b022015-05-05 11:39:47 -070088 hal_fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag_stub;
xinhe21602b32015-04-24 09:32:13 -070089 hal_fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump_stub;
90 hal_fn->wifi_set_log_handler = wifi_set_log_handler_stub;
JerryLee32cbc7a2015-06-17 19:19:30 -070091 hal_fn->wifi_reset_log_handler = wifi_reset_log_handler_stub;
xinhe21602b32015-04-24 09:32:13 -070092 hal_fn->wifi_set_alert_handler = wifi_set_alert_handler_stub;
Jerry Lee370ad502015-07-13 13:42:21 -070093 hal_fn->wifi_reset_alert_handler = wifi_reset_alert_handler_stub;
xinhe21602b32015-04-24 09:32:13 -070094 hal_fn->wifi_get_firmware_version = wifi_get_firmware_version_stub;
95 hal_fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status_stub;
96 hal_fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set_stub;
97 hal_fn->wifi_get_ring_data = wifi_get_ring_data_stub;
98 hal_fn->wifi_get_driver_version = wifi_get_driver_version_stub;
Vinit Deshpandee5bf4b82015-05-13 18:38:10 -070099 hal_fn->wifi_set_ssid_white_list = wifi_set_ssid_white_list_stub;
100 hal_fn->wifi_set_gscan_roam_params = wifi_set_gscan_roam_params_stub;
101 hal_fn->wifi_set_bssid_preference = wifi_set_bssid_preference_stub;
102 hal_fn->wifi_enable_lazy_roam = wifi_enable_lazy_roam_stub;
103 hal_fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist_stub;
Ecco Park2723d992015-06-18 17:08:23 -0700104 hal_fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet_stub;
105 hal_fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet_stub;
xinheec61e772015-03-30 18:39:12 -0700106 return 0;
107}
108
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530109extern struct accessPointObjectItem *g_pItemList;
110extern struct accessPointObjectItem *g_pLastNode;
111extern pthread_mutex_t *g_pItemListMutex;
112extern String8 *g_pCurrentSSID;
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000113static bool doCommand(JNIEnv* env, jstring javaCommand,
114 char* reply, size_t reply_len) {
115 ScopedUtfChars command(env, javaCommand);
116 if (command.c_str() == NULL) {
117 return false; // ScopedUtfChars already threw on error.
118 }
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530119 if(strstr(command.c_str(), "SET_NETWORK")) {
120 if(!setNetworkVariable((char *)command.c_str())) {
121 return false;
122 }
123 }
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000124 if (DBG) {
125 ALOGD("doCommand: %s", command.c_str());
126 }
127
128 --reply_len; // Ensure we have room to add NUL termination.
129 if (::wifi_command(command.c_str(), reply, &reply_len) != 0) {
130 return false;
131 }
132
133 // Strip off trailing newline.
134 if (reply_len > 0 && reply[reply_len-1] == '\n') {
135 reply[reply_len-1] = '\0';
136 } else {
137 reply[reply_len] = '\0';
138 }
139 return true;
140}
141
142static jint doIntCommand(JNIEnv* env, jstring javaCommand) {
143 char reply[REPLY_BUF_SIZE];
144 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
145 return -1;
146 }
147 return static_cast<jint>(atoi(reply));
148}
149
150static jboolean doBooleanCommand(JNIEnv* env, jstring javaCommand) {
151 char reply[REPLY_BUF_SIZE];
152 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
153 return JNI_FALSE;
154 }
Vinit Deshpandebbbafda2015-10-02 13:39:59 -0700155 jboolean result = (strcmp(reply, "OK") == 0);
156 if (!result) {
157 ScopedUtfChars command(env, javaCommand);
158 ALOGI("command '%s' returned '%s", command.c_str(), reply);
159 }
160 return result;
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000161}
162
163// Send a command to the supplicant, and return the reply as a String.
164static jstring doStringCommand(JNIEnv* env, jstring javaCommand) {
165 char reply[REPLY_BUF_SIZE];
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530166 ScopedUtfChars command(env, javaCommand);
167 if (command.c_str() == NULL) {
168 return NULL;
169 }
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000170 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
171 return NULL;
172 }
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530173 if (DBG) ALOGD("cmd = %s, reply: %s", command.c_str(), reply);
174 String16 str;
175 if (strstr(command.c_str(),"BSS RANGE=")) {
176 parseScanResults(str,reply);
177 } else if (strstr(command.c_str(),"GET_NETWORK") &&
178 strstr(command.c_str(),"ssid") && !strstr(command.c_str(),"bssid")
179 && !strstr(command.c_str(),"scan_ssid")){
180 constructSsid(str, reply);
181 } else {
182 str += String16((char *)reply);
183 }
184 return env->NewString((const jchar *)str.string(), str.size());
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000185}
186
187static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject)
188{
189 return (::is_wifi_driver_loaded() == 1);
190}
191
192static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
193{
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530194 g_pItemListMutex = new pthread_mutex_t;
195 if (NULL == g_pItemListMutex) {
196 ALOGE("Failed to allocate memory for g_pItemListMutex!");
197 return JNI_FALSE;
198 }
199 pthread_mutex_init(g_pItemListMutex, NULL);
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000200 return (::wifi_load_driver() == 0);
201}
202
203static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
204{
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530205 if (g_pItemListMutex != NULL) {
206 pthread_mutex_lock(g_pItemListMutex);
207 struct accessPointObjectItem *pCurrentNode = g_pItemList;
208 struct accessPointObjectItem *pNextNode = NULL;
209 while (pCurrentNode) {
210 pNextNode = pCurrentNode->pNext;
211 if (NULL != pCurrentNode->ssid) {
212 delete pCurrentNode->ssid;
213 pCurrentNode->ssid = NULL;
214 }
215 if (NULL != pCurrentNode->ssid_utf8) {
216 delete pCurrentNode->ssid_utf8;
217 pCurrentNode->ssid_utf8 = NULL;
218 }
219 delete pCurrentNode;
220 pCurrentNode = pNextNode;
221 }
222 g_pItemList = NULL;
223 g_pLastNode = NULL;
224 pthread_mutex_unlock(g_pItemListMutex);
225 pthread_mutex_destroy(g_pItemListMutex);
226 delete g_pItemListMutex;
227 g_pItemListMutex = NULL;
228 }
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000229 return (::wifi_unload_driver() == 0);
230}
231
232static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
233{
234 return (::wifi_start_supplicant(p2pSupported) == 0);
235}
236
237static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
238{
239 return (::wifi_stop_supplicant(p2pSupported) == 0);
240}
241
242static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject)
243{
244 return (::wifi_connect_to_supplicant() == 0);
245}
246
247static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject)
248{
249 ::wifi_close_supplicant_connection();
250}
251
252static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject)
253{
254 char buf[EVENT_BUF_SIZE];
255 int nread = ::wifi_wait_for_event(buf, sizeof buf);
256 if (nread > 0) {
Sravanthi Palakonda1a0319f2015-07-27 16:38:09 +0530257 if (strstr(buf, " SSID=") || strstr(buf, " SSID ")){
258 constructEventSsid(buf);
259 }
Vinit Deshpande155b9d02014-01-08 23:46:46 +0000260 return env->NewStringUTF(buf);
261 } else {
262 return NULL;
263 }
264}
265
266static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) {
267 return doBooleanCommand(env, javaCommand);
268}
269
270static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) {
271 return doIntCommand(env, javaCommand);
272}
273
274static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) {
275 return doStringCommand(env,javaCommand);
276}
277
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700278/* wifi_hal <==> WifiNative bridge */
279
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700280static jclass mCls; /* saved WifiNative object */
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700281static JavaVM *mVM; /* saved JVM pointer */
282
vandwalleaabe7a92014-05-09 18:11:02 -0700283static const char *WifiHandleVarName = "sWifiHalHandle";
284static const char *WifiIfaceHandleVarName = "sWifiIfaceHandles";
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700285static jmethodID OnScanResultsMethodID;
286
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700287static wifi_handle getWifiHandle(JNIHelper &helper, jclass cls) {
288 return (wifi_handle) helper.getStaticLongField(cls, WifiHandleVarName);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700289}
290
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700291static wifi_interface_handle getIfaceHandle(JNIHelper &helper, jclass cls, jint index) {
292 return (wifi_interface_handle) helper.getStaticLongArrayField(cls, WifiIfaceHandleVarName, index);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700293}
294
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700295jboolean setSSIDField(JNIHelper helper, jobject scanResult, const char *rawSsid) {
xinhe5cfd8d82015-07-28 16:34:37 -0700296
297 int len = strlen(rawSsid);
298
299 if (len > 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700300 JNIObject<jbyteArray> ssidBytes = helper.newByteArray(len);
301 helper.setByteArrayRegion(ssidBytes, 0, len, (jbyte *) rawSsid);
302 jboolean ret = helper.callStaticMethod(mCls,
303 "setSsid", "([BLandroid/net/wifi/ScanResult;)Z", ssidBytes.get(), scanResult);
xinhe5cfd8d82015-07-28 16:34:37 -0700304 return ret;
305 } else {
306 //empty SSID or SSID start with \0
307 return true;
308 }
309}
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700310static JNIObject<jobject> createScanResult(JNIHelper &helper, wifi_scan_result *result) {
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700311
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700312 // ALOGD("creating scan result");
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700313
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700314 JNIObject<jobject> scanResult = helper.createObject("android/net/wifi/ScanResult");
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700315 if (scanResult == NULL) {
316 ALOGE("Error in creating scan result");
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700317 return JNIObject<jobject>(helper, NULL);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700318 }
319
Vinit Deshpandee73629f2015-04-23 15:06:46 -0700320 ALOGV("setting SSID to %s", result->ssid);
xinhe5cfd8d82015-07-28 16:34:37 -0700321
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700322 if (!setSSIDField(helper, scanResult, result->ssid)) {
xinhe5cfd8d82015-07-28 16:34:37 -0700323 ALOGE("Error on set SSID");
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700324 return JNIObject<jobject>(helper, NULL);
xinhe5cfd8d82015-07-28 16:34:37 -0700325 }
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700326
327 char bssid[32];
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700328 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->bssid[0], result->bssid[1],
329 result->bssid[2], result->bssid[3], result->bssid[4], result->bssid[5]);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700330
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700331 helper.setStringField(scanResult, "BSSID", bssid);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700332
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700333 helper.setIntField(scanResult, "level", result->rssi);
334 helper.setIntField(scanResult, "frequency", result->channel);
335 helper.setLongField(scanResult, "timestamp", result->ts);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700336
337 return scanResult;
338}
339
xinhebe3b27a2015-01-30 17:56:24 -0800340int set_iface_flags(const char *ifname, int dev_up) {
341 struct ifreq ifr;
342 int ret;
xinhebe3b27a2015-01-30 17:56:24 -0800343 int sock = socket(PF_INET, SOCK_DGRAM, 0);
344 if (sock < 0) {
345 ALOGD("Bad socket: %d\n", sock);
346 return -errno;
347 }
348
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700349 //ALOGD("setting interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
xinhebe3b27a2015-01-30 17:56:24 -0800350
351 memset(&ifr, 0, sizeof(ifr));
352 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
353
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700354 //ALOGD("reading old value\n");
xinhebe3b27a2015-01-30 17:56:24 -0800355
356 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
357 ret = errno ? -errno : -999;
Vinit Deshpandebb6942c2015-04-10 18:10:29 -0700358 ALOGE("Could not read interface %s flags: %d\n", ifname, errno);
xinhebe3b27a2015-01-30 17:56:24 -0800359 close(sock);
360 return ret;
361 } else {
Pierre Vandwalledd490cf2015-03-20 18:43:31 -0700362 //ALOGD("writing new value\n");
xinhebe3b27a2015-01-30 17:56:24 -0800363 }
364
365 if (dev_up) {
366 if (ifr.ifr_flags & IFF_UP) {
Vinit Deshpandebb6942c2015-04-10 18:10:29 -0700367 // ALOGD("interface %s is already up\n", ifname);
xinhebe3b27a2015-01-30 17:56:24 -0800368 close(sock);
369 return 0;
370 }
371 ifr.ifr_flags |= IFF_UP;
372 } else {
373 if (!(ifr.ifr_flags & IFF_UP)) {
Vinit Deshpandebb6942c2015-04-10 18:10:29 -0700374 // ALOGD("interface %s is already down\n", ifname);
xinhebe3b27a2015-01-30 17:56:24 -0800375 close(sock);
376 return 0;
377 }
378 ifr.ifr_flags &= ~IFF_UP;
379 }
380
381 if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
Vinit Deshpande64143012015-06-25 12:41:57 -0700382 ALOGE("Could not set interface %s flags: %d\n", ifname, errno);
383 ret = errno ? -errno : -999;
xinhebe3b27a2015-01-30 17:56:24 -0800384 close(sock);
385 return ret;
386 } else {
387 ALOGD("set interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
388 }
389 close(sock);
390 return 0;
391}
392
xinheb830d762015-02-11 17:14:17 -0800393static jboolean android_net_wifi_toggle_interface(JNIEnv* env, jclass cls, int toggle) {
394 return(set_iface_flags("wlan0", toggle) == 0);
395}
396
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700397static jboolean android_net_wifi_startHal(JNIEnv* env, jclass cls) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700398 JNIHelper helper(env);
399 wifi_handle halHandle = getWifiHandle(helper, cls);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800400 if (halHandle == NULL) {
xinheec61e772015-03-30 18:39:12 -0700401
402 if(init_wifi_hal_func_table(&hal_fn) != 0 ) {
403 ALOGD("Can not initialize the basic function pointer table");
404 return false;
405 }
406
407 wifi_error res = init_wifi_vendor_hal_func_table(&hal_fn);
408 if (res != WIFI_SUCCESS) {
409 ALOGD("Can not initialize the vendor function pointer table");
410 return false;
411 }
412
xinhebe3b27a2015-01-30 17:56:24 -0800413 int ret = set_iface_flags("wlan0", 1);
414 if(ret != 0) {
415 return false;
416 }
xinheec61e772015-03-30 18:39:12 -0700417
418 res = hal_fn.wifi_initialize(&halHandle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700419 if (res == WIFI_SUCCESS) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700420 helper.setStaticLongField(cls, WifiHandleVarName, (jlong)halHandle);
vandwalleaabe7a92014-05-09 18:11:02 -0700421 ALOGD("Did set static halHandle = %p", halHandle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700422 }
423 env->GetJavaVM(&mVM);
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700424 mCls = (jclass) env->NewGlobalRef(cls);
425 ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800426 return res == WIFI_SUCCESS;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700427 } else {
xinhe82628222015-02-04 16:39:45 -0800428 return (set_iface_flags("wlan0", 1) == 0);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800429 }
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800430}
431
432void android_net_wifi_hal_cleaned_up_handler(wifi_handle handle) {
433 ALOGD("In wifi cleaned up handler");
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700434
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700435 JNIHelper helper(mVM);
436 helper.setStaticLongField(mCls, WifiHandleVarName, 0);
437
438 helper.deleteGlobalRef(mCls);
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700439 mCls = NULL;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700440 mVM = NULL;
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800441}
442
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700443static void android_net_wifi_stopHal(JNIEnv* env, jclass cls) {
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800444 ALOGD("In wifi stop Hal");
xinheb830d762015-02-11 17:14:17 -0800445
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700446 JNIHelper helper(env);
447 wifi_handle halHandle = getWifiHandle(helper, cls);
Vinit Deshpandef49a59b2015-05-27 11:24:47 -0700448 if (halHandle == NULL)
449 return;
450
451 ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls);
xinheec61e772015-03-30 18:39:12 -0700452 hal_fn.wifi_cleanup(halHandle, android_net_wifi_hal_cleaned_up_handler);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800453}
454
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700455static void android_net_wifi_waitForHalEvents(JNIEnv* env, jclass cls) {
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700456
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700457 ALOGD("waitForHalEvents called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700458
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700459 JNIHelper helper(env);
460 wifi_handle halHandle = getWifiHandle(helper, cls);
xinheec61e772015-03-30 18:39:12 -0700461 hal_fn.wifi_event_loop(halHandle);
Vinit Deshpandef49a59b2015-05-27 11:24:47 -0700462 set_iface_flags("wlan0", 0);
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -0800463}
464
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700465static int android_net_wifi_getInterfaces(JNIEnv *env, jclass cls) {
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700466 int n = 0;
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700467
468 JNIHelper helper(env);
469
470 wifi_handle halHandle = getWifiHandle(helper, cls);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700471 wifi_interface_handle *ifaceHandles = NULL;
xinheec61e772015-03-30 18:39:12 -0700472 int result = hal_fn.wifi_get_ifaces(halHandle, &n, &ifaceHandles);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700473 if (result < 0) {
474 return result;
475 }
476
Vinit Deshpande07ce33c2014-08-14 12:04:35 -0700477 if (n < 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700478 THROW(helper,"android_net_wifi_getInterfaces no interfaces");
vandwalleaabe7a92014-05-09 18:11:02 -0700479 return 0;
480 }
481
482 if (ifaceHandles == NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700483 THROW(helper,"android_net_wifi_getInterfaces null interface array");
vandwalleaabe7a92014-05-09 18:11:02 -0700484 return 0;
485 }
486
Vinit Deshpande07ce33c2014-08-14 12:04:35 -0700487 if (n > 8) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700488 THROW(helper,"Too many interfaces");
Vinit Deshpande07ce33c2014-08-14 12:04:35 -0700489 return 0;
490 }
491
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700492 jlongArray array = (env)->NewLongArray(n);
493 if (array == NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700494 THROW(helper,"Error in accessing array");
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700495 return 0;
496 }
497
498 jlong elems[8];
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700499 for (int i = 0; i < n; i++) {
500 elems[i] = reinterpret_cast<jlong>(ifaceHandles[i]);
501 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700502
503 helper.setLongArrayRegion(array, 0, n, elems);
504 helper.setStaticLongArrayField(cls, WifiIfaceHandleVarName, array);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700505
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700506 return (result < 0) ? result : n;
507}
508
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700509static jstring android_net_wifi_getInterfaceName(JNIEnv *env, jclass cls, jint i) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700510
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700511 char buf[EVENT_BUF_SIZE];
512
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700513 JNIHelper helper(env);
514
515 jlong value = helper.getStaticLongArrayField(cls, WifiIfaceHandleVarName, i);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700516 wifi_interface_handle handle = (wifi_interface_handle) value;
xinheec61e772015-03-30 18:39:12 -0700517 int result = hal_fn.wifi_get_iface_name(handle, buf, sizeof(buf));
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700518 if (result < 0) {
519 return NULL;
520 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700521 JNIObject<jstring> name = helper.newStringUTF(buf);
522 return name.detach();
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700523 }
524}
525
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700526
Vinit Deshapnde766cb4b2014-05-07 18:00:44 -0700527static void onScanResultsAvailable(wifi_request_id id, unsigned num_results) {
528
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700529 JNIHelper helper(mVM);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700530
Vinit Deshpandec5cdba42015-06-03 15:51:55 -0700531 // ALOGD("onScanResultsAvailable called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshapnde766cb4b2014-05-07 18:00:44 -0700532
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700533 helper.reportEvent(mCls, "onScanResultsAvailable", "(I)V", id);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700534}
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700535
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700536static void onScanEvent(wifi_scan_event event, unsigned status) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700537
538 JNIHelper helper(mVM);
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700539
Vinit Deshpandec5cdba42015-06-03 15:51:55 -0700540 // ALOGD("onScanStatus called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700541
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700542 helper.reportEvent(mCls, "onScanStatus", "(I)V", event);
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700543}
544
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700545static void onFullScanResult(wifi_request_id id, wifi_scan_result *result) {
546
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700547 JNIHelper helper(mVM);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700548
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700549 //ALOGD("onFullScanResult called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700550
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700551 JNIObject<jobject> scanResult = createScanResult(helper, result);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700552
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700553 //ALOGD("Creating a byte array of length %d", result->ie_length);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700554
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700555 JNIObject<jbyteArray> elements = helper.newByteArray(result->ie_length);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700556 if (elements == NULL) {
557 ALOGE("Error in allocating array");
558 return;
559 }
560
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700561 // ALOGD("Setting byte array");
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700562
563 jbyte *bytes = (jbyte *)&(result->ie_data[0]);
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700564 helper.setByteArrayRegion(elements, 0, result->ie_length, bytes);
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700565
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700566 // ALOGD("Returning result");
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700567
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700568 helper.reportEvent(mCls, "onFullScanResult", "(ILandroid/net/wifi/ScanResult;[B)V", id,
569 scanResult.get(), elements.get());
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700570}
571
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700572static jboolean android_net_wifi_startScan(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700573 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700574
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700575 JNIHelper helper(env);
576 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700577 // ALOGD("starting scan on interface[%d] = %p", iface, handle);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700578
579 wifi_scan_cmd_params params;
580 memset(&params, 0, sizeof(params));
vandwalleaabe7a92014-05-09 18:11:02 -0700581
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700582 params.base_period = helper.getIntField(settings, "base_period_ms");
583 params.max_ap_per_scan = helper.getIntField(settings, "max_ap_per_scan");
584 params.report_threshold_percent = helper.getIntField(settings, "report_threshold_percent");
585 params.report_threshold_num_scans = helper.getIntField(settings, "report_threshold_num_scans");
vandwalleaabe7a92014-05-09 18:11:02 -0700586
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700587 ALOGD("Initialized common fields %d, %d, %d, %d", params.base_period, params.max_ap_per_scan,
588 params.report_threshold_percent, params.report_threshold_num_scans);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700589
590 const char *bucket_array_type = "[Lcom/android/server/wifi/WifiNative$BucketSettings;";
591 const char *channel_array_type = "[Lcom/android/server/wifi/WifiNative$ChannelSettings;";
vandwalleaabe7a92014-05-09 18:11:02 -0700592
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700593 params.num_buckets = helper.getIntField(settings, "num_buckets");
vandwalleaabe7a92014-05-09 18:11:02 -0700594
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700595 // ALOGD("Initialized num_buckets to %d", params.num_buckets);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700596
597 for (int i = 0; i < params.num_buckets; i++) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700598 JNIObject<jobject> bucket = helper.getObjectArrayField(
599 settings, "buckets", bucket_array_type, i);
vandwalleaabe7a92014-05-09 18:11:02 -0700600
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700601 params.buckets[i].bucket = helper.getIntField(bucket, "bucket");
602 params.buckets[i].band = (wifi_band) helper.getIntField(bucket, "band");
603 params.buckets[i].period = helper.getIntField(bucket, "period_ms");
vandwalleaabe7a92014-05-09 18:11:02 -0700604
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700605 int report_events = helper.getIntField(bucket, "report_events");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700606 params.buckets[i].report_events = report_events;
vandwalleaabe7a92014-05-09 18:11:02 -0700607
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700608 ALOGD("bucket[%d] = %d:%d:%d:%d", i, params.buckets[i].bucket,
609 params.buckets[i].band, params.buckets[i].period, report_events);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700610
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700611 params.buckets[i].num_channels = helper.getIntField(bucket, "num_channels");
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700612 // ALOGD("Initialized num_channels to %d", params.buckets[i].num_channels);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700613
614 for (int j = 0; j < params.buckets[i].num_channels; j++) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700615 JNIObject<jobject> channel = helper.getObjectArrayField(
616 bucket, "channels", channel_array_type, j);
vandwalleaabe7a92014-05-09 18:11:02 -0700617
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700618 params.buckets[i].channels[j].channel = helper.getIntField(channel, "frequency");
619 params.buckets[i].channels[j].dwellTimeMs = helper.getIntField(channel, "dwell_time_ms");
vandwalleaabe7a92014-05-09 18:11:02 -0700620
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700621 bool passive = helper.getBoolField(channel, "passive");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700622 params.buckets[i].channels[j].passive = (passive ? 1 : 0);
623
Vinit Deshpandebb6942c2015-04-10 18:10:29 -0700624 // ALOGD("Initialized channel %d", params.buckets[i].channels[j].channel);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700625 }
626 }
627
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700628 // ALOGD("Initialized all fields");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700629
630 wifi_scan_result_handler handler;
631 memset(&handler, 0, sizeof(handler));
632 handler.on_scan_results_available = &onScanResultsAvailable;
Vinit Deshapndef1daf932014-05-13 15:44:05 -0700633 handler.on_full_scan_result = &onFullScanResult;
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -0700634 handler.on_scan_event = &onScanEvent;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700635
xinheec61e772015-03-30 18:39:12 -0700636 return hal_fn.wifi_start_gscan(id, handle, params, handler) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700637}
638
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700639static jboolean android_net_wifi_stopScan(JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700640
641 JNIHelper helper(env);
642 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpanded7cbebf2015-05-11 14:07:13 -0700643 // ALOGD("stopping scan on interface[%d] = %p", iface, handle);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700644
xinheec61e772015-03-30 18:39:12 -0700645 return hal_fn.wifi_stop_gscan(id, handle) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700646}
647
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700648static int compare_scan_result_timestamp(const void *v1, const void *v2) {
649 const wifi_scan_result *result1 = static_cast<const wifi_scan_result *>(v1);
650 const wifi_scan_result *result2 = static_cast<const wifi_scan_result *>(v2);
651 return result1->ts - result2->ts;
652}
653
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700654static jobject android_net_wifi_getScanResults(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700655 JNIEnv *env, jclass cls, jint iface, jboolean flush) {
Navtej Singh Mannc8b61ce2015-04-16 18:54:10 -0700656
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700657 JNIHelper helper(env);
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700658 wifi_cached_scan_results scan_data[64];
659 int num_scan_data = 64;
Navtej Singh Mannc8b61ce2015-04-16 18:54:10 -0700660
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700661 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700662 // ALOGD("getting scan results on interface[%d] = %p", iface, handle);
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700663
Navtej Singh Mannc8b61ce2015-04-16 18:54:10 -0700664 byte b = flush ? 0xFF : 0;
xinheec61e772015-03-30 18:39:12 -0700665 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 -0700666 if (result == WIFI_SUCCESS) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700667 JNIObject<jobjectArray> scanData = helper.createObjectArray(
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700668 "android/net/wifi/WifiScanner$ScanData", num_scan_data);
669 if (scanData == NULL) {
670 ALOGE("Error in allocating array of scanData");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700671 return NULL;
672 }
673
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700674 for (int i = 0; i < num_scan_data; i++) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700675
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700676 JNIObject<jobject> data = helper.createObject("android/net/wifi/WifiScanner$ScanData");
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700677 if (data == NULL) {
678 ALOGE("Error in allocating scanData");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700679 return NULL;
680 }
681
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700682 helper.setIntField(data, "mId", scan_data[i].scan_id);
683 helper.setIntField(data, "mFlags", scan_data[i].flags);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700684
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700685 /* sort all scan results by timestamp */
686 qsort(scan_data[i].results, scan_data[i].num_results,
687 sizeof(wifi_scan_result), compare_scan_result_timestamp);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700688
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700689 JNIObject<jobjectArray> scanResults = helper.createObjectArray(
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700690 "android/net/wifi/ScanResult", scan_data[i].num_results);
691 if (scanResults == NULL) {
692 ALOGE("Error in allocating scanResult array");
693 return NULL;
694 }
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700695
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700696 wifi_scan_result *results = scan_data[i].results;
697 for (int j = 0; j < scan_data[i].num_results; j++) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700698
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700699 JNIObject<jobject> scanResult = createScanResult(helper, &results[j]);
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700700 if (scanResult == NULL) {
701 ALOGE("Error in creating scan result");
702 return NULL;
703 }
704
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700705 helper.setObjectArrayElement(scanResults, j, scanResult);
Vinit Deshpandec591ab32014-10-31 11:15:26 -0700706 }
707
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700708 helper.setObjectField(data, "mResults", "[Landroid/net/wifi/ScanResult;", scanResults);
709 helper.setObjectArrayElement(scanData, i, data);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700710 }
711
Vinit Deshpandec5cdba42015-06-03 15:51:55 -0700712 // ALOGD("retrieved %d scan data from interface[%d] = %p", num_scan_data, iface, handle);
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700713 return scanData.detach();
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700714 } else {
715 return NULL;
716 }
717}
718
719
720static jboolean android_net_wifi_getScanCapabilities(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700721 JNIEnv *env, jclass cls, jint iface, jobject capabilities) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700722
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700723 JNIHelper helper(env);
724 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -0700725 // ALOGD("getting scan capabilities on interface[%d] = %p", iface, handle);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700726
727 wifi_gscan_capabilities c;
728 memset(&c, 0, sizeof(c));
xinheec61e772015-03-30 18:39:12 -0700729 int result = hal_fn.wifi_get_gscan_capabilities(handle, &c);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700730 if (result != WIFI_SUCCESS) {
731 ALOGD("failed to get capabilities : %d", result);
732 return JNI_FALSE;
733 }
734
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700735 helper.setIntField(capabilities, "max_scan_cache_size", c.max_scan_cache_size);
736 helper.setIntField(capabilities, "max_scan_buckets", c.max_scan_buckets);
737 helper.setIntField(capabilities, "max_ap_cache_per_scan", c.max_ap_cache_per_scan);
738 helper.setIntField(capabilities, "max_rssi_sample_size", c.max_rssi_sample_size);
739 helper.setIntField(capabilities, "max_scan_reporting_threshold", c.max_scan_reporting_threshold);
740 helper.setIntField(capabilities, "max_hotlist_bssids", c.max_hotlist_bssids);
741 helper.setIntField(capabilities, "max_significant_wifi_change_aps",
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700742 c.max_significant_wifi_change_aps);
743
744 return JNI_TRUE;
745}
746
747
748static byte parseHexChar(char ch) {
749 if (isdigit(ch))
750 return ch - '0';
751 else if ('A' <= ch && ch <= 'F')
752 return ch - 'A' + 10;
753 else if ('a' <= ch && ch <= 'f')
754 return ch - 'a' + 10;
755 else {
756 ALOGE("invalid character in bssid %c", ch);
757 return 0;
758 }
759}
760
761static byte parseHexByte(const char * &str) {
Paul Stewarta35267d2016-05-31 17:31:03 -0700762 if (str[0] == '\0') {
763 ALOGE("Passed an empty string");
764 return 0;
765 }
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700766 byte b = parseHexChar(str[0]);
Paul Stewarta35267d2016-05-31 17:31:03 -0700767 if (str[1] == '\0' || str[1] == ':') {
768 str ++;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700769 } else {
770 b = b << 4 | parseHexChar(str[1]);
Paul Stewarta35267d2016-05-31 17:31:03 -0700771 str += 2;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700772 }
Paul Stewarta35267d2016-05-31 17:31:03 -0700773
774 // Skip trailing delimiter if not at the end of the string.
775 if (str[0] != '\0') {
776 str++;
777 }
778 return b;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700779}
780
781static void parseMacAddress(const char *str, mac_addr addr) {
782 addr[0] = parseHexByte(str);
783 addr[1] = parseHexByte(str);
784 addr[2] = parseHexByte(str);
785 addr[3] = parseHexByte(str);
786 addr[4] = parseHexByte(str);
787 addr[5] = parseHexByte(str);
788}
789
Vinit Deshpande14365732014-06-30 15:23:23 -0700790static bool parseMacAddress(JNIEnv *env, jobject obj, mac_addr addr) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700791 JNIHelper helper(env);
792 JNIObject<jstring> macAddrString = helper.getStringField(obj, "bssid");
Vinit Deshpande14365732014-06-30 15:23:23 -0700793 if (macAddrString == NULL) {
794 ALOGE("Error getting bssid field");
795 return false;
796 }
797
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700798 ScopedUtfChars chars(env, macAddrString);
799 const char *bssid = chars.c_str();
Vinit Deshpande14365732014-06-30 15:23:23 -0700800 if (bssid == NULL) {
801 ALOGE("Error getting bssid");
802 return false;
803 }
804
805 parseMacAddress(bssid, addr);
806 return true;
807}
808
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700809static void onHotlistApFound(wifi_request_id id,
810 unsigned num_results, wifi_scan_result *results) {
811
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700812 JNIHelper helper(mVM);
813 ALOGD("onHotlistApFound called, vm = %p, obj = %p, num_results = %d", mVM, mCls, num_results);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700814
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700815 JNIObject<jobjectArray> scanResults = helper.newObjectArray(num_results,
816 "android/net/wifi/ScanResult", NULL);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700817 if (scanResults == NULL) {
818 ALOGE("Error in allocating array");
819 return;
820 }
821
822 for (unsigned i = 0; i < num_results; i++) {
823
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700824 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700825 if (scanResult == NULL) {
826 ALOGE("Error in creating scan result");
827 return;
828 }
829
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700830 helper.setObjectArrayElement(scanResults, i, scanResult);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700831
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700832 ALOGD("Found AP %32s", results[i].ssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700833 }
834
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700835 helper.reportEvent(mCls, "onHotlistApFound", "(I[Landroid/net/wifi/ScanResult;)V",
836 id, scanResults.get());
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700837}
838
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700839static void onHotlistApLost(wifi_request_id id,
840 unsigned num_results, wifi_scan_result *results) {
841
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700842 JNIHelper helper(mVM);
843 ALOGD("onHotlistApLost called, vm = %p, obj = %p, num_results = %d", mVM, mCls, num_results);
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700844
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700845 JNIObject<jobjectArray> scanResults = helper.newObjectArray(num_results,
846 "android/net/wifi/ScanResult", NULL);
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700847 if (scanResults == NULL) {
848 ALOGE("Error in allocating array");
849 return;
850 }
851
852 for (unsigned i = 0; i < num_results; i++) {
853
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700854 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]);
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700855 if (scanResult == NULL) {
856 ALOGE("Error in creating scan result");
857 return;
858 }
859
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700860 helper.setObjectArrayElement(scanResults, i, scanResult);
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700861
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700862 ALOGD("Lost AP %32s", results[i].ssid);
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700863 }
864
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700865 helper.reportEvent(mCls, "onHotlistApLost", "(I[Landroid/net/wifi/ScanResult;)V",
866 id, scanResults.get());
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700867}
868
869
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700870static jboolean android_net_wifi_setHotlist(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700871 JNIEnv *env, jclass cls, jint iface, jint id, jobject ap) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700872
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700873 JNIHelper helper(env);
874 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700875 ALOGD("setting hotlist on interface[%d] = %p", iface, handle);
876
877 wifi_bssid_hotlist_params params;
878 memset(&params, 0, sizeof(params));
879
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700880 params.lost_ap_sample_size = helper.getIntField(ap, "apLostThreshold");
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700881
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700882 JNIObject<jobjectArray> array = helper.getArrayField(
883 ap, "bssidInfos", "[Landroid/net/wifi/WifiScanner$BssidInfo;");
884 params.num_bssid = helper.getArrayLength(array);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700885
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700886 if (params.num_bssid == 0) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700887 ALOGE("Error in accesing array");
888 return false;
889 }
890
Ningyuan Wang41c9e492016-10-11 11:42:12 -0700891 if (params.num_bssid >
Ningyuan Wangdc254cf2016-10-06 13:29:45 -0700892 static_cast<int>(sizeof(params.ap) / sizeof(params.ap[0]))) {
893 ALOGE("setHotlist array length is too long");
Ningyuan Wang659a90e2017-05-15 14:24:41 -0700894 android_errorWriteLog(SAFE_NET_LOG_ID, "31856351");
Ningyuan Wangdc254cf2016-10-06 13:29:45 -0700895 return false;
896 }
897
Pierre Vandwallec03c1462015-03-18 19:16:30 -0700898 for (int i = 0; i < params.num_bssid; i++) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700899 JNIObject<jobject> objAp = helper.getObjectArrayElement(array, i);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700900
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700901 JNIObject<jstring> macAddrString = helper.getStringField(objAp, "bssid");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700902 if (macAddrString == NULL) {
903 ALOGE("Error getting bssid field");
904 return false;
905 }
906
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700907 ScopedUtfChars chars(env, macAddrString);
908 const char *bssid = chars.c_str();
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700909 if (bssid == NULL) {
910 ALOGE("Error getting bssid");
911 return false;
912 }
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700913 parseMacAddress(bssid, params.ap[i].bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700914
915 mac_addr addr;
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700916 memcpy(addr, params.ap[i].bssid, sizeof(mac_addr));
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700917
918 char bssidOut[32];
919 sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1],
920 addr[2], addr[3], addr[4], addr[5]);
921
922 ALOGD("Added bssid %s", bssidOut);
923
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700924 params.ap[i].low = helper.getIntField(objAp, "low");
925 params.ap[i].high = helper.getIntField(objAp, "high");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700926 }
927
928 wifi_hotlist_ap_found_handler handler;
929 memset(&handler, 0, sizeof(handler));
930
931 handler.on_hotlist_ap_found = &onHotlistApFound;
Vinit Deshpandee9fa5dc2014-08-11 21:51:25 -0700932 handler.on_hotlist_ap_lost = &onHotlistApLost;
xinheec61e772015-03-30 18:39:12 -0700933 return hal_fn.wifi_set_bssid_hotlist(id, handle, params, handler) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700934}
935
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700936static jboolean android_net_wifi_resetHotlist(JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700937
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700938 JNIHelper helper(env);
939 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700940 ALOGD("resetting hotlist on interface[%d] = %p", iface, handle);
941
xinheec61e772015-03-30 18:39:12 -0700942 return hal_fn.wifi_reset_bssid_hotlist(id, handle) == WIFI_SUCCESS;
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700943}
944
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700945void onSignificantWifiChange(wifi_request_id id,
946 unsigned num_results, wifi_significant_change_result **results) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700947
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700948 JNIHelper helper(mVM);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700949
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700950 ALOGD("onSignificantWifiChange called, vm = %p, obj = %p", mVM, mCls);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700951
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700952 JNIObject<jobjectArray> scanResults = helper.newObjectArray(
953 num_results, "android/net/wifi/ScanResult", NULL);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700954 if (scanResults == NULL) {
955 ALOGE("Error in allocating array");
956 return;
957 }
958
959 for (unsigned i = 0; i < num_results; i++) {
960
Greg Hackmannd31a40e2015-02-22 21:39:38 -0800961 wifi_significant_change_result &result = *(results[i]);
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700962
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700963 JNIObject<jobject> scanResult = helper.createObject("android/net/wifi/ScanResult");
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700964 if (scanResult == NULL) {
965 ALOGE("Error in creating scan result");
966 return;
967 }
968
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700969 // helper.setStringField(scanResult, "SSID", results[i].ssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700970
971 char bssid[32];
Vinit Deshpandea59fae62014-05-23 15:59:35 -0700972 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result.bssid[0], result.bssid[1],
973 result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700974
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700975 helper.setStringField(scanResult, "BSSID", bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700976
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700977 helper.setIntField(scanResult, "level", result.rssi[0]);
978 helper.setIntField(scanResult, "frequency", result.channel);
979 // helper.setLongField(scanResult, "timestamp", result.ts);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700980
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700981 helper.setObjectArrayElement(scanResults, i, scanResult);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700982 }
983
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700984 helper.reportEvent(mCls, "onSignificantWifiChange", "(I[Landroid/net/wifi/ScanResult;)V",
985 id, scanResults.get());
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700986
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700987}
988
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700989static jboolean android_net_wifi_trackSignificantWifiChange(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -0700990 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) {
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700991
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700992 JNIHelper helper(env);
993 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700994 ALOGD("tracking significant wifi change on interface[%d] = %p", iface, handle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700995
Vinit Deshapndee4e37502014-05-05 11:32:21 -0700996 wifi_significant_change_params params;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -0700997 memset(&params, 0, sizeof(params));
998
Vinit Deshpande7d519b62015-08-04 16:43:09 -0700999 params.rssi_sample_size = helper.getIntField(settings, "rssiSampleSize");
1000 params.lost_ap_sample_size = helper.getIntField(settings, "lostApSampleSize");
1001 params.min_breaching = helper.getIntField(settings, "minApsBreachingThreshold");
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001002
Vinit Deshpandeb7cc3092014-07-30 18:07:03 -07001003 const char *bssid_info_array_type = "[Landroid/net/wifi/WifiScanner$BssidInfo;";
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001004 JNIObject<jobjectArray> bssids = helper.getArrayField(
1005 settings, "bssidInfos", bssid_info_array_type);
1006 params.num_bssid = helper.getArrayLength(bssids);
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001007
Pierre Vandwallec03c1462015-03-18 19:16:30 -07001008 if (params.num_bssid == 0) {
vandwalleaabe7a92014-05-09 18:11:02 -07001009 ALOGE("Error in accessing array");
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001010 return false;
1011 }
Ningyuan Wang659a90e2017-05-15 14:24:41 -07001012 if (params.num_bssid >
1013 static_cast<int>(sizeof(params.ap) / sizeof(params.ap[0]))) {
1014 ALOGE("trackSignificantWifiChange array length is too long");
1015 android_errorWriteLog(SAFE_NET_LOG_ID, "37775935");
1016 return false;
1017 }
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001018 ALOGD("Initialized common fields %d, %d, %d, %d", params.rssi_sample_size,
Pierre Vandwallec03c1462015-03-18 19:16:30 -07001019 params.lost_ap_sample_size, params.min_breaching, params.num_bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001020
Pierre Vandwallec03c1462015-03-18 19:16:30 -07001021 for (int i = 0; i < params.num_bssid; i++) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001022 JNIObject<jobject> objAp = helper.getObjectArrayElement(bssids, i);
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001023
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001024 JNIObject<jstring> macAddrString = helper.getStringField(objAp, "bssid");
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001025 if (macAddrString == NULL) {
1026 ALOGE("Error getting bssid field");
1027 return false;
1028 }
1029
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001030 ScopedUtfChars chars(env, macAddrString.get());
1031 const char *bssid = chars.c_str();
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001032 if (bssid == NULL) {
1033 ALOGE("Error getting bssid");
1034 return false;
1035 }
1036
1037 mac_addr addr;
1038 parseMacAddress(bssid, addr);
Vinit Deshpandea59fae62014-05-23 15:59:35 -07001039 memcpy(params.ap[i].bssid, addr, sizeof(mac_addr));
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001040
1041 char bssidOut[32];
Vinit Deshpande4dbfefd2014-08-10 18:19:13 -07001042 sprintf(bssidOut, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1],
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001043 addr[2], addr[3], addr[4], addr[5]);
1044
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001045 params.ap[i].low = helper.getIntField(objAp, "low");
1046 params.ap[i].high = helper.getIntField(objAp, "high");
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001047
Vinit Deshpandea59fae62014-05-23 15:59:35 -07001048 ALOGD("Added bssid %s, [%04d, %04d]", bssidOut, params.ap[i].low, params.ap[i].high);
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001049 }
1050
Pierre Vandwallec03c1462015-03-18 19:16:30 -07001051 ALOGD("Added %d bssids", params.num_bssid);
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001052
1053 wifi_significant_change_handler handler;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001054 memset(&handler, 0, sizeof(handler));
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001055
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001056 handler.on_significant_change = &onSignificantWifiChange;
xinheec61e772015-03-30 18:39:12 -07001057 return hal_fn.wifi_set_significant_change_handler(id, handle, params, handler) == WIFI_SUCCESS;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001058}
1059
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001060static jboolean android_net_wifi_untrackSignificantWifiChange(
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -07001061 JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001062
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001063 JNIHelper helper(env);
1064 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001065 ALOGD("resetting significant wifi change on interface[%d] = %p", iface, handle);
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001066
xinheec61e772015-03-30 18:39:12 -07001067 return hal_fn.wifi_reset_significant_change_handler(id, handle) == WIFI_SUCCESS;
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07001068}
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -08001069
vandwalleaabe7a92014-05-09 18:11:02 -07001070wifi_iface_stat link_stat;
vandwalle200e8ee2014-07-18 18:44:32 -07001071wifi_radio_stat radio_stat; // L release has support for only one radio
vandwalleaabe7a92014-05-09 18:11:02 -07001072
1073void onLinkStatsResults(wifi_request_id id, wifi_iface_stat *iface_stat,
vandwalle200e8ee2014-07-18 18:44:32 -07001074 int num_radios, wifi_radio_stat *radio_stats)
vandwalleaabe7a92014-05-09 18:11:02 -07001075{
vandwalle200e8ee2014-07-18 18:44:32 -07001076 if (iface_stat != 0) {
1077 memcpy(&link_stat, iface_stat, sizeof(wifi_iface_stat));
1078 } else {
1079 memset(&link_stat, 0, sizeof(wifi_iface_stat));
1080 }
vandwalle200e8ee2014-07-18 18:44:32 -07001081
1082 if (num_radios > 0 && radio_stats != 0) {
1083 memcpy(&radio_stat, radio_stats, sizeof(wifi_radio_stat));
1084 } else {
1085 memset(&radio_stat, 0, sizeof(wifi_radio_stat));
1086 }
vandwalleaabe7a92014-05-09 18:11:02 -07001087}
1088
Pierre Vandwalled745a522015-06-11 17:48:58 -07001089static void android_net_wifi_setLinkLayerStats (JNIEnv *env, jclass cls, jint iface, int enable) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001090 JNIHelper helper(env);
1091 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Pierre Vandwalled745a522015-06-11 17:48:58 -07001092
1093 wifi_link_layer_params params;
1094 params.aggressive_statistics_gathering = enable;
1095 params.mpdu_size_threshold = 128;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001096
1097 ALOGD("android_net_wifi_setLinkLayerStats: %u\n", enable);
Pierre Vandwalled745a522015-06-11 17:48:58 -07001098
1099 hal_fn.wifi_set_link_stats(handle, params);
1100}
1101
Vinit Deshpandeb0b1d592014-05-29 16:37:24 -07001102static jobject android_net_wifi_getLinkLayerStats (JNIEnv *env, jclass cls, jint iface) {
vandwalleaabe7a92014-05-09 18:11:02 -07001103
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001104 JNIHelper helper(env);
vandwalleaabe7a92014-05-09 18:11:02 -07001105 wifi_stats_result_handler handler;
1106 memset(&handler, 0, sizeof(handler));
1107 handler.on_link_stats_results = &onLinkStatsResults;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001108 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinheec61e772015-03-30 18:39:12 -07001109 int result = hal_fn.wifi_get_link_stats(0, handle, handler);
vandwalleaabe7a92014-05-09 18:11:02 -07001110 if (result < 0) {
vandwalle200e8ee2014-07-18 18:44:32 -07001111 ALOGE("android_net_wifi_getLinkLayerStats: failed to get link statistics\n");
vandwalleaabe7a92014-05-09 18:11:02 -07001112 return NULL;
1113 }
1114
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001115 JNIObject<jobject> wifiLinkLayerStats = helper.createObject(
1116 "android/net/wifi/WifiLinkLayerStats");
vandwalleaabe7a92014-05-09 18:11:02 -07001117 if (wifiLinkLayerStats == NULL) {
1118 ALOGE("Error in allocating wifiLinkLayerStats");
1119 return NULL;
1120 }
1121
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001122 helper.setIntField(wifiLinkLayerStats, "beacon_rx", link_stat.beacon_rx);
1123 helper.setIntField(wifiLinkLayerStats, "rssi_mgmt", link_stat.rssi_mgmt);
1124 helper.setLongField(wifiLinkLayerStats, "rxmpdu_be", link_stat.ac[WIFI_AC_BE].rx_mpdu);
1125 helper.setLongField(wifiLinkLayerStats, "rxmpdu_bk", link_stat.ac[WIFI_AC_BK].rx_mpdu);
1126 helper.setLongField(wifiLinkLayerStats, "rxmpdu_vi", link_stat.ac[WIFI_AC_VI].rx_mpdu);
1127 helper.setLongField(wifiLinkLayerStats, "rxmpdu_vo", link_stat.ac[WIFI_AC_VO].rx_mpdu);
1128 helper.setLongField(wifiLinkLayerStats, "txmpdu_be", link_stat.ac[WIFI_AC_BE].tx_mpdu);
1129 helper.setLongField(wifiLinkLayerStats, "txmpdu_bk", link_stat.ac[WIFI_AC_BK].tx_mpdu);
1130 helper.setLongField(wifiLinkLayerStats, "txmpdu_vi", link_stat.ac[WIFI_AC_VI].tx_mpdu);
1131 helper.setLongField(wifiLinkLayerStats, "txmpdu_vo", link_stat.ac[WIFI_AC_VO].tx_mpdu);
1132 helper.setLongField(wifiLinkLayerStats, "lostmpdu_be", link_stat.ac[WIFI_AC_BE].mpdu_lost);
1133 helper.setLongField(wifiLinkLayerStats, "lostmpdu_bk", link_stat.ac[WIFI_AC_BK].mpdu_lost);
1134 helper.setLongField(wifiLinkLayerStats, "lostmpdu_vi", link_stat.ac[WIFI_AC_VI].mpdu_lost);
1135 helper.setLongField(wifiLinkLayerStats, "lostmpdu_vo", link_stat.ac[WIFI_AC_VO].mpdu_lost);
1136 helper.setLongField(wifiLinkLayerStats, "retries_be", link_stat.ac[WIFI_AC_BE].retries);
1137 helper.setLongField(wifiLinkLayerStats, "retries_bk", link_stat.ac[WIFI_AC_BK].retries);
1138 helper.setLongField(wifiLinkLayerStats, "retries_vi", link_stat.ac[WIFI_AC_VI].retries);
1139 helper.setLongField(wifiLinkLayerStats, "retries_vo", link_stat.ac[WIFI_AC_VO].retries);
vandwalleaabe7a92014-05-09 18:11:02 -07001140
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001141 helper.setIntField(wifiLinkLayerStats, "on_time", radio_stat.on_time);
1142 helper.setIntField(wifiLinkLayerStats, "tx_time", radio_stat.tx_time);
1143 helper.setIntField(wifiLinkLayerStats, "rx_time", radio_stat.rx_time);
1144 helper.setIntField(wifiLinkLayerStats, "on_time_scan", radio_stat.on_time_scan);
vandwalle200e8ee2014-07-18 18:44:32 -07001145
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001146 return wifiLinkLayerStats.detach();
vandwalleaabe7a92014-05-09 18:11:02 -07001147}
Vinit Deshapndee4e37502014-05-05 11:32:21 -07001148
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001149static jint android_net_wifi_getSupportedFeatures(JNIEnv *env, jclass cls, jint iface) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001150
1151 JNIHelper helper(env);
1152 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001153 feature_set set = 0;
1154
1155 wifi_error result = WIFI_SUCCESS;
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001156 /*
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001157 set = WIFI_FEATURE_INFRA
1158 | WIFI_FEATURE_INFRA_5G
1159 | WIFI_FEATURE_HOTSPOT
1160 | WIFI_FEATURE_P2P
1161 | WIFI_FEATURE_SOFT_AP
1162 | WIFI_FEATURE_GSCAN
1163 | WIFI_FEATURE_PNO
1164 | WIFI_FEATURE_TDLS
1165 | WIFI_FEATURE_EPR;
Vinit Deshpandec35361d2014-08-07 16:24:10 -07001166 */
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001167
xinheec61e772015-03-30 18:39:12 -07001168 result = hal_fn.wifi_get_supported_feature_set(handle, &set);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001169 if (result == WIFI_SUCCESS) {
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -07001170 // ALOGD("wifi_get_supported_feature_set returned set = 0x%x", set);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001171 return set;
1172 } else {
Vinit Deshpandef3bc3c62015-04-23 15:06:46 -07001173 ALOGE("wifi_get_supported_feature_set returned error = 0x%x", result);
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07001174 return 0;
1175 }
1176}
1177
xinhe06a3eba2015-03-18 20:17:17 -07001178static void onRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* results[]) {
Vinit Deshpande14365732014-06-30 15:23:23 -07001179
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001180 JNIHelper helper(mVM);
Vinit Deshpande14365732014-06-30 15:23:23 -07001181
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001182 ALOGD("onRttResults called, vm = %p, obj = %p", mVM, mCls);
Vinit Deshpande14365732014-06-30 15:23:23 -07001183
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001184 JNIObject<jobjectArray> rttResults = helper.newObjectArray(
1185 num_results, "android/net/wifi/RttManager$RttResult", NULL);
Vinit Deshpande14365732014-06-30 15:23:23 -07001186 if (rttResults == NULL) {
1187 ALOGE("Error in allocating array");
1188 return;
1189 }
1190
1191 for (unsigned i = 0; i < num_results; i++) {
1192
xinhe06a3eba2015-03-18 20:17:17 -07001193 wifi_rtt_result *result = results[i];
Vinit Deshpande14365732014-06-30 15:23:23 -07001194
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001195 JNIObject<jobject> rttResult = helper.createObject("android/net/wifi/RttManager$RttResult");
Vinit Deshpande14365732014-06-30 15:23:23 -07001196 if (rttResult == NULL) {
1197 ALOGE("Error in creating rtt result");
1198 return;
1199 }
1200
Vinit Deshpande14365732014-06-30 15:23:23 -07001201 char bssid[32];
xinhe06a3eba2015-03-18 20:17:17 -07001202 sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->addr[0], result->addr[1],
1203 result->addr[2], result->addr[3], result->addr[4], result->addr[5]);
Vinit Deshpande14365732014-06-30 15:23:23 -07001204
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001205 helper.setStringField(rttResult, "bssid", bssid);
1206 helper.setIntField( rttResult, "burstNumber", result->burst_num);
1207 helper.setIntField( rttResult, "measurementFrameNumber", result->measurement_number);
1208 helper.setIntField( rttResult, "successMeasurementFrameNumber", result->success_number);
1209 helper.setIntField(rttResult, "frameNumberPerBurstPeer", result->number_per_burst_peer);
1210 helper.setIntField( rttResult, "status", result->status);
1211 helper.setIntField( rttResult, "measurementType", result->type);
1212 helper.setIntField(rttResult, "retryAfterDuration", result->retry_after_duration);
1213 helper.setLongField(rttResult, "ts", result->ts);
1214 helper.setIntField( rttResult, "rssi", result->rssi);
1215 helper.setIntField( rttResult, "rssiSpread", result->rssi_spread);
1216 helper.setIntField( rttResult, "txRate", result->tx_rate.bitrate);
1217 helper.setIntField( rttResult, "rxRate", result->rx_rate.bitrate);
1218 helper.setLongField(rttResult, "rtt", result->rtt);
1219 helper.setLongField(rttResult, "rttStandardDeviation", result->rtt_sd);
1220 helper.setIntField( rttResult, "distance", result->distance);
1221 helper.setIntField( rttResult, "distanceStandardDeviation", result->distance_sd);
1222 helper.setIntField( rttResult, "distanceSpread", result->distance_spread);
1223 helper.setIntField( rttResult, "burstDuration", result->burst_duration);
1224 helper.setIntField( rttResult, "negotiatedBurstNum", result->negotiated_burst_num);
xinhe12cf3882015-03-12 18:38:54 -07001225
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001226 JNIObject<jobject> LCI = helper.createObject(
1227 "android/net/wifi/RttManager$WifiInformationElement");
1228 if (result->LCI != NULL && result->LCI->len > 0) {
1229 ALOGD("Add LCI in result");
1230 helper.setByteField(LCI, "id", result->LCI->id);
1231 JNIObject<jbyteArray> elements = helper.newByteArray(result->LCI->len);
1232 jbyte *bytes = (jbyte *)&(result->LCI->data[0]);
1233 helper.setByteArrayRegion(elements, 0, result->LCI->len, bytes);
1234 helper.setObjectField(LCI, "data", "[B", elements);
1235 } else {
1236 ALOGD("No LCI in result");
1237 helper.setByteField(LCI, "id", (byte)(0xff));
1238 }
1239 helper.setObjectField(rttResult, "LCI",
1240 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCI);
Vinit Deshpande14365732014-06-30 15:23:23 -07001241
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001242 JNIObject<jobject> LCR = helper.createObject(
1243 "android/net/wifi/RttManager$WifiInformationElement");
1244 if (result->LCR != NULL && result->LCR->len > 0) {
1245 ALOGD("Add LCR in result");
1246 helper.setByteField(LCR, "id", result->LCR->id);
1247 JNIObject<jbyteArray> elements = helper.newByteArray(result->LCI->len);
1248 jbyte *bytes = (jbyte *)&(result->LCR->data[0]);
1249 helper.setByteArrayRegion(elements, 0, result->LCI->len, bytes);
1250 helper.setObjectField(LCR, "data", "[B", elements);
1251 } else {
1252 ALOGD("No LCR in result");
1253 helper.setByteField(LCR, "id", (byte)(0xff));
1254 }
1255 helper.setObjectField(rttResult, "LCR",
1256 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCR);
1257
1258 helper.setObjectArrayElement(rttResults, i, rttResult);
Vinit Deshpande14365732014-06-30 15:23:23 -07001259 }
1260
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001261 helper.reportEvent(mCls, "onRttResults", "(I[Landroid/net/wifi/RttManager$RttResult;)V",
1262 id, rttResults.get());
Vinit Deshpande14365732014-06-30 15:23:23 -07001263}
1264
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001265const int MaxRttConfigs = 16;
1266
Vinit Deshpande14365732014-06-30 15:23:23 -07001267static jboolean android_net_wifi_requestRange(
1268 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) {
1269
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001270 JNIHelper helper(env);
1271
1272 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande14365732014-06-30 15:23:23 -07001273 ALOGD("sending rtt request [%d] = %p", id, handle);
1274
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001275 wifi_rtt_config configs[MaxRttConfigs];
1276 memset(&configs, 0, sizeof(configs));
Vinit Deshpande14365732014-06-30 15:23:23 -07001277
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001278 int len = helper.getArrayLength((jobjectArray)params);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001279 if (len > MaxRttConfigs) {
1280 return false;
1281 }
1282
1283 for (int i = 0; i < len; i++) {
1284
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001285 JNIObject<jobject> param = helper.getObjectArrayElement((jobjectArray)params, i);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001286 if (param == NULL) {
1287 ALOGD("could not get element %d", i);
1288 continue;
1289 }
1290
1291 wifi_rtt_config &config = configs[i];
1292
1293 parseMacAddress(env, param, config.addr);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001294 config.type = (wifi_rtt_type)helper.getIntField(param, "requestType");
1295 config.peer = (rtt_peer_type)helper.getIntField(param, "deviceType");
1296 config.channel.center_freq = helper.getIntField(param, "frequency");
1297 config.channel.width = (wifi_channel_width) helper.getIntField(param, "channelWidth");
1298 config.channel.center_freq0 = helper.getIntField(param, "centerFreq0");
1299 config.channel.center_freq1 = helper.getIntField(param, "centerFreq1");
xinhe12cf3882015-03-12 18:38:54 -07001300
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001301 config.num_burst = helper.getIntField(param, "numberBurst");
1302 config.burst_period = (unsigned) helper.getIntField(param, "interval");
1303 config.num_frames_per_burst = (unsigned) helper.getIntField(param, "numSamplesPerBurst");
1304 config.num_retries_per_rtt_frame = (unsigned) helper.getIntField(param,
xinhe12cf3882015-03-12 18:38:54 -07001305 "numRetriesPerMeasurementFrame");
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001306 config.num_retries_per_ftmr = (unsigned) helper.getIntField(param, "numRetriesPerFTMR");
1307 config.LCI_request = helper.getBoolField(param, "LCIRequest") ? 1 : 0;
1308 config.LCR_request = helper.getBoolField(param, "LCRRequest") ? 1 : 0;
1309 config.burst_duration = (unsigned) helper.getIntField(param, "burstTimeout");
1310 config.preamble = (wifi_rtt_preamble) helper.getIntField(param, "preamble");
1311 config.bw = (wifi_rtt_bw) helper.getIntField(param, "bandwidth");
xinhe12cf3882015-03-12 18:38:54 -07001312
1313 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 -07001314 config.type,config.peer, config.channel.width, config.channel.center_freq);
xinhe12cf3882015-03-12 18:38:54 -07001315 ALOGD("center_freq0 is %d, center_freq1 is %d, num_burst is %d,interval is %d",
1316 config.channel.center_freq0, config.channel.center_freq1, config.num_burst,
xinhec96feb82015-04-01 18:52:59 -07001317 config.burst_period);
xinhe12cf3882015-03-12 18:38:54 -07001318 ALOGD("frames_per_burst is %d, retries of measurement frame is %d, retries_per_ftmr is %d",
xinhec96feb82015-04-01 18:52:59 -07001319 config.num_frames_per_burst, config.num_retries_per_rtt_frame,
xinhe12cf3882015-03-12 18:38:54 -07001320 config.num_retries_per_ftmr);
1321 ALOGD("LCI_requestis %d, LCR_request is %d, burst_timeout is %d, preamble is %d, bw is %d",
xinhec96feb82015-04-01 18:52:59 -07001322 config.LCI_request, config.LCR_request, config.burst_duration, config.preamble,
xinhe12cf3882015-03-12 18:38:54 -07001323 config.bw);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001324 }
Vinit Deshpande14365732014-06-30 15:23:23 -07001325
1326 wifi_rtt_event_handler handler;
1327 handler.on_rtt_results = &onRttResults;
1328
xinheec61e772015-03-30 18:39:12 -07001329 return hal_fn.wifi_rtt_range_request(id, handle, len, configs, handler) == WIFI_SUCCESS;
Vinit Deshpande14365732014-06-30 15:23:23 -07001330}
1331
1332static jboolean android_net_wifi_cancelRange(
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001333 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) {
Vinit Deshpande14365732014-06-30 15:23:23 -07001334
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001335 JNIHelper helper(env);
1336 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande14365732014-06-30 15:23:23 -07001337 ALOGD("cancelling rtt request [%d] = %p", id, handle);
1338
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001339 mac_addr addrs[MaxRttConfigs];
1340 memset(&addrs, 0, sizeof(addrs));
Vinit Deshpande14365732014-06-30 15:23:23 -07001341
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001342 int len = helper.getArrayLength((jobjectArray)params);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001343 if (len > MaxRttConfigs) {
1344 return false;
1345 }
Vinit Deshpande14365732014-06-30 15:23:23 -07001346
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001347 for (int i = 0; i < len; i++) {
1348
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001349 JNIObject<jobject> param = helper.getObjectArrayElement(params, i);
Vinit Deshpande02a1f982014-07-25 17:44:39 -07001350 if (param == NULL) {
1351 ALOGD("could not get element %d", i);
1352 continue;
1353 }
1354
1355 parseMacAddress(env, param, addrs[i]);
1356 }
1357
xinheec61e772015-03-30 18:39:12 -07001358 return hal_fn.wifi_rtt_range_cancel(id, handle, len, addrs) == WIFI_SUCCESS;
Vinit Deshpande14365732014-06-30 15:23:23 -07001359}
1360
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001361static jboolean android_net_wifi_setScanningMacOui(JNIEnv *env, jclass cls,
1362 jint iface, jbyteArray param) {
1363
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001364 JNIHelper helper(env);
1365 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001366 ALOGD("setting scan oui %p", handle);
1367
1368 static const unsigned oui_len = 3; /* OUI is upper 3 bytes of mac_address */
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001369 int len = helper.getArrayLength(param);
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001370 if (len != oui_len) {
1371 ALOGE("invalid oui length %d", len);
1372 return false;
1373 }
1374
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001375 ScopedBytesRO paramBytes(env, param);
1376 const jbyte* bytes = paramBytes.get();
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001377 if (bytes == NULL) {
1378 ALOGE("failed to get array");
1379 return false;
1380 }
1381
xinheec61e772015-03-30 18:39:12 -07001382 return hal_fn.wifi_set_scanning_mac_oui(handle, (byte *)bytes) == WIFI_SUCCESS;
Vinit Deshpande042c54b2014-08-21 13:52:21 -07001383}
1384
xinheee0a0132015-08-04 14:27:27 -07001385static jboolean android_net_wifi_is_get_channels_for_band_supported(JNIEnv *env, jclass cls){
1386 return (hal_fn.wifi_get_valid_channels == wifi_get_valid_channels_stub);
1387}
1388
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001389static jintArray android_net_wifi_getValidChannels(JNIEnv *env, jclass cls,
1390 jint iface, jint band) {
1391
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001392 JNIHelper helper(env);
1393 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001394 ALOGD("getting valid channels %p", handle);
1395
1396 static const int MaxChannels = 64;
1397 wifi_channel channels[64];
1398 int num_channels = 0;
xinheec61e772015-03-30 18:39:12 -07001399 wifi_error result = hal_fn.wifi_get_valid_channels(handle, band, MaxChannels,
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001400 channels, &num_channels);
1401
1402 if (result == WIFI_SUCCESS) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001403 JNIObject<jintArray> channelArray = helper.newIntArray(num_channels);
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001404 if (channelArray == NULL) {
1405 ALOGE("failed to allocate channel list");
1406 return NULL;
1407 }
1408
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001409 helper.setIntArrayRegion(channelArray, 0, num_channels, channels);
1410 return channelArray.detach();
Vinit Deshpandeefa77c12014-09-05 20:44:49 -07001411 } else {
1412 ALOGE("failed to get channel list : %d", result);
1413 return NULL;
1414 }
1415}
1416
Vinit Deshpande90b902d2014-10-13 13:21:47 -07001417static jboolean android_net_wifi_setDfsFlag(JNIEnv *env, jclass cls, jint iface, jboolean dfs) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001418
1419 JNIHelper helper(env);
1420 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande90b902d2014-10-13 13:21:47 -07001421 ALOGD("setting dfs flag to %s, %p", dfs ? "true" : "false", handle);
1422
1423 u32 nodfs = dfs ? 0 : 1;
xinheec61e772015-03-30 18:39:12 -07001424 wifi_error result = hal_fn.wifi_set_nodfs_flag(handle, nodfs);
Vinit Deshpande90b902d2014-10-13 13:21:47 -07001425 return result == WIFI_SUCCESS;
1426}
1427
xinhe12cf3882015-03-12 18:38:54 -07001428static jobject android_net_wifi_get_rtt_capabilities(JNIEnv *env, jclass cls, jint iface) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001429
1430 JNIHelper helper(env);
xinhe12cf3882015-03-12 18:38:54 -07001431 wifi_rtt_capabilities rtt_capabilities;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001432 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinheec61e772015-03-30 18:39:12 -07001433 wifi_error ret = hal_fn.wifi_get_rtt_capabilities(handle, &rtt_capabilities);
xinhe12cf3882015-03-12 18:38:54 -07001434
1435 if(WIFI_SUCCESS == ret) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001436 JNIObject<jobject> capabilities = helper.createObject(
1437 "android/net/wifi/RttManager$RttCapabilities");
1438 helper.setBooleanField(capabilities, "oneSidedRttSupported",
xinhe12cf3882015-03-12 18:38:54 -07001439 rtt_capabilities.rtt_one_sided_supported == 1);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001440 helper.setBooleanField(capabilities, "twoSided11McRttSupported",
xinhe12cf3882015-03-12 18:38:54 -07001441 rtt_capabilities.rtt_ftm_supported == 1);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001442 helper.setBooleanField(capabilities, "lciSupported",
xinhe12cf3882015-03-12 18:38:54 -07001443 rtt_capabilities.lci_support);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001444 helper.setBooleanField(capabilities, "lcrSupported",
xinhe12cf3882015-03-12 18:38:54 -07001445 rtt_capabilities.lcr_support);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001446 helper.setIntField(capabilities, "preambleSupported",
xinhe12cf3882015-03-12 18:38:54 -07001447 rtt_capabilities.preamble_support);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001448 helper.setIntField(capabilities, "bwSupported",
xinhe12cf3882015-03-12 18:38:54 -07001449 rtt_capabilities.bw_support);
1450 ALOGD("One side RTT is: %s", rtt_capabilities.rtt_one_sided_supported ==1 ? "support" :
1451 "not support");
1452 ALOGD("Two side RTT is: %s", rtt_capabilities.rtt_ftm_supported == 1 ? "support" :
1453 "not support");
1454 ALOGD("LCR is: %s", rtt_capabilities.lcr_support == 1 ? "support" : "not support");
1455
1456 ALOGD("LCI is: %s", rtt_capabilities.lci_support == 1 ? "support" : "not support");
1457
1458 ALOGD("Support Preamble is : %d support BW is %d", rtt_capabilities.preamble_support,
1459 rtt_capabilities.bw_support);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001460 return capabilities.detach();
xinhe12cf3882015-03-12 18:38:54 -07001461 } else {
1462 return NULL;
1463 }
1464}
1465
xinhe939177f2015-03-23 14:43:03 -07001466static jboolean android_net_wifi_set_Country_Code_Hal(JNIEnv *env,jclass cls, jint iface,
1467 jstring country_code) {
1468
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001469 JNIHelper helper(env);
1470 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
1471
1472 ScopedUtfChars chars(env, country_code);
1473 const char *country = chars.c_str();
xinhe939177f2015-03-23 14:43:03 -07001474
1475 ALOGD("set country code: %s", country);
xinhe44787b52015-04-02 09:41:57 -07001476 wifi_error res = hal_fn.wifi_set_country_code(handle, country);
xinhe939177f2015-03-23 14:43:03 -07001477 return res == WIFI_SUCCESS;
1478}
xinhed57f6302015-04-15 13:23:43 -07001479
1480static jboolean android_net_wifi_enable_disable_tdls(JNIEnv *env,jclass cls, jint iface,
1481 jboolean enable, jstring addr) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001482
1483 JNIHelper helper(env);
1484 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhed57f6302015-04-15 13:23:43 -07001485
1486 mac_addr address;
1487 parseMacAddress(env, addr, address);
1488 wifi_tdls_handler tdls_handler;
1489 //tdls_handler.on_tdls_state_changed = &on_tdls_state_changed;
1490
1491 if(enable) {
1492 return (hal_fn.wifi_enable_tdls(handle, address, NULL, tdls_handler) == WIFI_SUCCESS);
1493 } else {
1494 return (hal_fn.wifi_disable_tdls(handle, address) == WIFI_SUCCESS);
1495 }
1496}
1497
1498static void on_tdls_state_changed(mac_addr addr, wifi_tdls_status status) {
xinhed57f6302015-04-15 13:23:43 -07001499
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001500 JNIHelper helper(mVM);
1501
1502 ALOGD("on_tdls_state_changed is called: vm = %p, obj = %p", mVM, mCls);
xinhed57f6302015-04-15 13:23:43 -07001503
1504 char mac[32];
1505 sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4],
1506 addr[5]);
1507
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001508 JNIObject<jstring> mac_address = helper.newStringUTF(mac);
1509 helper.reportEvent(mCls, "onTdlsStatus", "(Ljava/lang/StringII;)V",
1510 mac_address.get(), status.state, status.reason);
xinhed57f6302015-04-15 13:23:43 -07001511
1512}
1513
1514static jobject android_net_wifi_get_tdls_status(JNIEnv *env,jclass cls, jint iface,jstring addr) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001515
1516 JNIHelper helper(env);
1517 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhed57f6302015-04-15 13:23:43 -07001518
1519 mac_addr address;
1520 parseMacAddress(env, addr, address);
1521
1522 wifi_tdls_status status;
1523
1524 wifi_error ret;
1525 ret = hal_fn.wifi_get_tdls_status(handle, address, &status );
1526
1527 if (ret != WIFI_SUCCESS) {
1528 return NULL;
1529 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001530 JNIObject<jobject> tdls_status = helper.createObject(
1531 "com/android/server/wifi/WifiNative$TdlsStatus");
1532 helper.setIntField(tdls_status, "channel", status.channel);
1533 helper.setIntField(tdls_status, "global_operating_class", status.global_operating_class);
1534 helper.setIntField(tdls_status, "state", status.state);
1535 helper.setIntField(tdls_status, "reason", status.reason);
1536 return tdls_status.detach();
xinhed57f6302015-04-15 13:23:43 -07001537 }
1538}
1539
1540static jobject android_net_wifi_get_tdls_capabilities(JNIEnv *env, jclass cls, jint iface) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001541
1542 JNIHelper helper(env);
xinhed57f6302015-04-15 13:23:43 -07001543 wifi_tdls_capabilities tdls_capabilities;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001544 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhed57f6302015-04-15 13:23:43 -07001545 wifi_error ret = hal_fn.wifi_get_tdls_capabilities(handle, &tdls_capabilities);
1546
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001547 if (WIFI_SUCCESS == ret) {
1548 JNIObject<jobject> capabilities = helper.createObject(
xinhed57f6302015-04-15 13:23:43 -07001549 "com/android/server/wifi/WifiNative$TdlsCapabilities");
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001550 helper.setIntField(capabilities, "maxConcurrentTdlsSessionNumber",
xinhed57f6302015-04-15 13:23:43 -07001551 tdls_capabilities.max_concurrent_tdls_session_num);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001552 helper.setBooleanField(capabilities, "isGlobalTdlsSupported",
xinhed57f6302015-04-15 13:23:43 -07001553 tdls_capabilities.is_global_tdls_supported == 1);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001554 helper.setBooleanField(capabilities, "isPerMacTdlsSupported",
xinhed57f6302015-04-15 13:23:43 -07001555 tdls_capabilities.is_per_mac_tdls_supported == 1);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001556 helper.setBooleanField(capabilities, "isOffChannelTdlsSupported",
xinhed57f6302015-04-15 13:23:43 -07001557 tdls_capabilities.is_off_channel_tdls_supported);
1558
1559 ALOGD("TDLS Max Concurrent Tdls Session Number is: %d",
1560 tdls_capabilities.max_concurrent_tdls_session_num);
1561 ALOGD("Global Tdls is: %s", tdls_capabilities.is_global_tdls_supported == 1 ? "support" :
1562 "not support");
1563 ALOGD("Per Mac Tdls is: %s", tdls_capabilities.is_per_mac_tdls_supported == 1 ? "support" :
1564 "not support");
1565 ALOGD("Off Channel Tdls is: %s", tdls_capabilities.is_off_channel_tdls_supported == 1 ?
1566 "support" : "not support");
1567
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001568 return capabilities.detach();
xinhed57f6302015-04-15 13:23:43 -07001569 } else {
1570 return NULL;
1571 }
1572}
1573
Vinit Deshpande155b9d02014-01-08 23:46:46 +00001574// ----------------------------------------------------------------------------
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001575// Debug framework
1576// ----------------------------------------------------------------------------
xinhe03ba4a52015-04-28 14:40:44 -07001577static jint android_net_wifi_get_supported_logger_feature(JNIEnv *env, jclass cls, jint iface){
1578 //Not implemented yet
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001579 JNIHelper helper(env);
1580 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001581 return -1;
1582}
1583
1584static jobject android_net_wifi_get_driver_version(JNIEnv *env, jclass cls, jint iface) {
1585 //Need to be fixed. The memory should be allocated from lower layer
1586 //char *buffer = NULL;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001587 JNIHelper helper(env);
xinhe03ba4a52015-04-28 14:40:44 -07001588 int buffer_length = 256;
xinhe6d0cd102015-05-05 11:10:08 -07001589 char *buffer = (char *)malloc(buffer_length);
1590 if (!buffer) return NULL;
1591 memset(buffer, 0, buffer_length);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001592 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001593
1594 ALOGD("android_net_wifi_get_driver_version = %p", handle);
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001595
1596 if (handle == 0) {
xinhe03ba4a52015-04-28 14:40:44 -07001597 return NULL;
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001598 }
xinhe03ba4a52015-04-28 14:40:44 -07001599
xinhe6d0cd102015-05-05 11:10:08 -07001600 wifi_error result = hal_fn.wifi_get_driver_version(handle, buffer, buffer_length);
xinhe03ba4a52015-04-28 14:40:44 -07001601
1602 if (result == WIFI_SUCCESS) {
1603 ALOGD("buffer is %p, length is %d", buffer, buffer_length);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001604 JNIObject<jstring> driver_version = helper.newStringUTF(buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001605 free(buffer);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001606 return driver_version.detach();
xinhe03ba4a52015-04-28 14:40:44 -07001607 } else {
1608 ALOGD("Fail to get driver version");
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001609 free(buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001610 return NULL;
1611 }
1612}
1613
1614static jobject android_net_wifi_get_firmware_version(JNIEnv *env, jclass cls, jint iface) {
1615
1616 //char *buffer = NULL;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001617 JNIHelper helper(env);
xinhe03ba4a52015-04-28 14:40:44 -07001618 int buffer_length = 256;
1619 char *buffer = (char *)malloc(buffer_length);
xinhe6d0cd102015-05-05 11:10:08 -07001620 if (!buffer) return NULL;
1621 memset(buffer, 0, buffer_length);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001622 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001623
1624 ALOGD("android_net_wifi_get_firmware_version = %p", handle);
1625
1626 if (handle == 0) {
1627 return NULL;
1628 }
1629
xinhe6d0cd102015-05-05 11:10:08 -07001630 wifi_error result = hal_fn.wifi_get_firmware_version(handle, buffer, buffer_length);
xinhe03ba4a52015-04-28 14:40:44 -07001631
1632 if (result == WIFI_SUCCESS) {
1633 ALOGD("buffer is %p, length is %d", buffer, buffer_length);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001634 JNIObject<jstring> firmware_version = helper.newStringUTF(buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001635 free(buffer);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001636 return firmware_version.detach();
xinhe03ba4a52015-04-28 14:40:44 -07001637 } else {
1638 ALOGD("Fail to get Firmware version");
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001639 free(buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001640 return NULL;
1641 }
1642}
1643
1644static jobject android_net_wifi_get_ring_buffer_status (JNIEnv *env, jclass cls, jint iface) {
1645
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001646 JNIHelper helper(env);
1647 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001648
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001649 ALOGD("android_net_wifi_get_ring_buffer_status = %p", handle);
xinhe03ba4a52015-04-28 14:40:44 -07001650
1651 if (handle == 0) {
1652 return NULL;
1653 }
1654
1655 //wifi_ring_buffer_status *status = NULL;
1656 u32 num_rings = 10;
1657 wifi_ring_buffer_status *status =
1658 (wifi_ring_buffer_status *)malloc(sizeof(wifi_ring_buffer_status) * num_rings);
xinhe6d0cd102015-05-05 11:10:08 -07001659 if (!status) return NULL;
1660 memset(status, 0, sizeof(wifi_ring_buffer_status) * num_rings);
1661 wifi_error result = hal_fn.wifi_get_ring_buffers_status(handle, &num_rings, status);
xinhe03ba4a52015-04-28 14:40:44 -07001662 if (result == WIFI_SUCCESS) {
1663 ALOGD("status is %p, number is %d", status, num_rings);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001664
1665 JNIObject<jobjectArray> ringBuffersStatus = helper.newObjectArray(
1666 num_rings, "com/android/server/wifi/WifiNative$RingBufferStatus", NULL);
1667
xinhe03ba4a52015-04-28 14:40:44 -07001668 wifi_ring_buffer_status *tmp = status;
1669
1670 for(u32 i = 0; i < num_rings; i++, tmp++) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001671
1672 JNIObject<jobject> ringStatus = helper.createObject(
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001673 "com/android/server/wifi/WifiNative$RingBufferStatus");
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001674
xinhe03ba4a52015-04-28 14:40:44 -07001675 if (ringStatus == NULL) {
1676 ALOGE("Error in creating ringBufferStatus");
1677 free(status);
1678 return NULL;
1679 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001680
xinhe03ba4a52015-04-28 14:40:44 -07001681 char name[32];
1682 for(int j = 0; j < 32; j++) {
1683 name[j] = tmp->name[j];
1684 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001685
1686 helper.setStringField(ringStatus, "name", name);
1687 helper.setIntField(ringStatus, "flag", tmp->flags);
1688 helper.setIntField(ringStatus, "ringBufferId", tmp->ring_id);
1689 helper.setIntField(ringStatus, "ringBufferByteSize", tmp->ring_buffer_byte_size);
1690 helper.setIntField(ringStatus, "verboseLevel", tmp->verbose_level);
1691 helper.setIntField(ringStatus, "writtenBytes", tmp->written_bytes);
1692 helper.setIntField(ringStatus, "readBytes", tmp->read_bytes);
1693 helper.setIntField(ringStatus, "writtenRecords", tmp->written_records);
1694
1695 helper.setObjectArrayElement(ringBuffersStatus, i, ringStatus);
xinhe03ba4a52015-04-28 14:40:44 -07001696 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001697
xinhe03ba4a52015-04-28 14:40:44 -07001698 free(status);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001699 return ringBuffersStatus.detach();
xinhe03ba4a52015-04-28 14:40:44 -07001700 } else {
xinhe6d0cd102015-05-05 11:10:08 -07001701 free(status);
xinhe03ba4a52015-04-28 14:40:44 -07001702 return NULL;
1703 }
1704}
1705
1706static void on_ring_buffer_data(char *ring_name, char *buffer, int buffer_size,
1707 wifi_ring_buffer_status *status) {
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001708
Jerry Lee6111ff72015-05-11 15:10:03 -07001709 if (!ring_name || !buffer || !status ||
1710 (unsigned int)buffer_size <= sizeof(wifi_ring_buffer_entry)) {
xinhe03ba4a52015-04-28 14:40:44 -07001711 ALOGE("Error input for on_ring_buffer_data!");
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001712 return;
xinhe03ba4a52015-04-28 14:40:44 -07001713 }
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001714
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001715
1716 JNIHelper helper(mVM);
Vinit Deshpande64143012015-06-25 12:41:57 -07001717 /* ALOGD("on_ring_buffer_data called, vm = %p, obj = %p, env = %p buffer size = %d", mVM,
1718 mCls, env, buffer_size); */
xinhe03ba4a52015-04-28 14:40:44 -07001719
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001720 JNIObject<jobject> ringStatus = helper.createObject(
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07001721 "com/android/server/wifi/WifiNative$RingBufferStatus");
xinhe03ba4a52015-04-28 14:40:44 -07001722 if (status == NULL) {
1723 ALOGE("Error in creating ringBufferStatus");
1724 return;
1725 }
1726
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001727 helper.setStringField(ringStatus, "name", ring_name);
1728 helper.setIntField(ringStatus, "flag", status->flags);
1729 helper.setIntField(ringStatus, "ringBufferId", status->ring_id);
1730 helper.setIntField(ringStatus, "ringBufferByteSize", status->ring_buffer_byte_size);
1731 helper.setIntField(ringStatus, "verboseLevel", status->verbose_level);
1732 helper.setIntField(ringStatus, "writtenBytes", status->written_bytes);
1733 helper.setIntField(ringStatus, "readBytes", status->read_bytes);
1734 helper.setIntField(ringStatus, "writtenRecords", status->written_records);
xinhe03ba4a52015-04-28 14:40:44 -07001735
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001736 JNIObject<jbyteArray> bytes = helper.newByteArray(buffer_size);
1737 helper.setByteArrayRegion(bytes, 0, buffer_size, (jbyte*)buffer);
xinhe03ba4a52015-04-28 14:40:44 -07001738
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001739 helper.reportEvent(mCls,"onRingBufferData",
1740 "(Lcom/android/server/wifi/WifiNative$RingBufferStatus;[B)V",
1741 ringStatus.get(), bytes.get());
xinhe03ba4a52015-04-28 14:40:44 -07001742}
1743
1744static void on_alert_data(wifi_request_id id, char *buffer, int buffer_size, int err_code){
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001745
1746 JNIHelper helper(mVM);
1747 ALOGD("on_alert_data called, vm = %p, obj = %p, buffer_size = %d, error code = %d"
1748 , mVM, mCls, buffer_size, err_code);
xinhe03ba4a52015-04-28 14:40:44 -07001749
1750 if (buffer_size > 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001751 JNIObject<jbyteArray> records = helper.newByteArray(buffer_size);
xinhe03ba4a52015-04-28 14:40:44 -07001752 jbyte *bytes = (jbyte *) buffer;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001753 helper.setByteArrayRegion(records, 0,buffer_size, bytes);
1754 helper.reportEvent(mCls,"onWifiAlert","([BI)V", records.get(), err_code);
xinhe03ba4a52015-04-28 14:40:44 -07001755 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001756 helper.reportEvent(mCls,"onWifiAlert","([BI)V", NULL, err_code);
xinhe03ba4a52015-04-28 14:40:44 -07001757 }
1758}
1759
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07001760
xinhe03ba4a52015-04-28 14:40:44 -07001761static jboolean android_net_wifi_start_logging_ring_buffer(JNIEnv *env, jclass cls, jint iface,
1762 jint verbose_level,jint flags, jint max_interval,jint min_data_size, jstring ring_name) {
1763
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001764 JNIHelper helper(env);
1765 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinhe03ba4a52015-04-28 14:40:44 -07001766
1767 ALOGD("android_net_wifi_start_logging_ring_buffer = %p", handle);
1768
1769 if (handle == 0) {
1770 return false;
1771 }
1772
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001773 ScopedUtfChars chars(env, ring_name);
1774 const char* ring_name_const_char = chars.c_str();
1775 int ret = hal_fn.wifi_start_logging(handle, verbose_level,
1776 flags, max_interval, min_data_size, const_cast<char *>(ring_name_const_char));
xinhe03ba4a52015-04-28 14:40:44 -07001777
1778 if (ret != WIFI_SUCCESS) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001779 ALOGE("Fail to start logging for ring %s", ring_name_const_char);
xinhe03ba4a52015-04-28 14:40:44 -07001780 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001781 ALOGD("start logging for ring %s", ring_name_const_char);
xinhe03ba4a52015-04-28 14:40:44 -07001782 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001783
xinhe03ba4a52015-04-28 14:40:44 -07001784 return ret == WIFI_SUCCESS;
1785}
1786
1787static jboolean android_net_wifi_get_ring_buffer_data(JNIEnv *env, jclass cls, jint iface,
1788 jstring ring_name) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001789
1790 JNIHelper helper(env);
1791 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande64143012015-06-25 12:41:57 -07001792 // ALOGD("android_net_wifi_get_ring_buffer_data = %p", handle);
xinhe03ba4a52015-04-28 14:40:44 -07001793
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001794 ScopedUtfChars chars(env, ring_name);
1795 const char* ring_name_const_char = chars.c_str();
1796 int result = hal_fn.wifi_get_ring_data(handle, const_cast<char *>(ring_name_const_char));
xinhe03ba4a52015-04-28 14:40:44 -07001797 return result == WIFI_SUCCESS;
1798}
1799
1800
1801void on_firmware_memory_dump(char *buffer, int buffer_size) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001802
1803 JNIHelper helper(mVM);
Vinit Deshpande64143012015-06-25 12:41:57 -07001804 /* ALOGD("on_firmware_memory_dump called, vm = %p, obj = %p, env = %p buffer_size = %d"
1805 , mVM, mCls, env, buffer_size); */
xinhe03ba4a52015-04-28 14:40:44 -07001806
1807 if (buffer_size > 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001808 JNIObject<jbyteArray> dump = helper.newByteArray(buffer_size);
xinhe03ba4a52015-04-28 14:40:44 -07001809 jbyte *bytes = (jbyte *) (buffer);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001810 helper.setByteArrayRegion(dump, 0, buffer_size, bytes);
1811 helper.reportEvent(mCls,"onWifiFwMemoryAvailable","([B)V", dump.get());
xinhe03ba4a52015-04-28 14:40:44 -07001812 }
xinhe03ba4a52015-04-28 14:40:44 -07001813}
1814
1815static jboolean android_net_wifi_get_fw_memory_dump(JNIEnv *env, jclass cls, jint iface){
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001816
1817 JNIHelper helper(env);
1818 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Vinit Deshpande64143012015-06-25 12:41:57 -07001819 // ALOGD("android_net_wifi_get_fw_memory_dump = %p", handle);
xinhe03ba4a52015-04-28 14:40:44 -07001820
1821 if (handle == NULL) {
1822 ALOGE("Can not get wifi_interface_handle");
1823 return false;
1824 }
1825
1826 wifi_firmware_memory_dump_handler fw_dump_handle;
1827 fw_dump_handle.on_firmware_memory_dump = on_firmware_memory_dump;
1828 int result = hal_fn.wifi_get_firmware_memory_dump(handle, fw_dump_handle);
1829 return result == WIFI_SUCCESS;
1830
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07001831}
1832
xinheb7978932015-06-25 17:57:21 -07001833static jboolean android_net_wifi_set_log_handler(JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001834
1835 JNIHelper helper(env);
1836 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
xinheb7978932015-06-25 17:57:21 -07001837 ALOGD("android_net_wifi_set_log_handler = %p", handle);
1838
1839 //initialize the handler on first time
1840 wifi_ring_buffer_data_handler handler;
1841 handler.on_ring_buffer_data = &on_ring_buffer_data;
1842 int result = hal_fn.wifi_set_log_handler(id, handle, handler);
1843 if (result != WIFI_SUCCESS) {
1844 ALOGE("Fail to set logging handler");
1845 return false;
1846 }
1847
1848 //set alter handler This will start alert too
1849 wifi_alert_handler alert_handler;
1850 alert_handler.on_alert = &on_alert_data;
1851 result = hal_fn.wifi_set_alert_handler(id, handle, alert_handler);
1852 if (result != WIFI_SUCCESS) {
1853 ALOGE(" Fail to set alert handler");
1854 return false;
1855 }
1856
1857 return true;
1858}
1859
1860static jboolean android_net_wifi_reset_log_handler(JNIEnv *env, jclass cls, jint iface, jint id) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001861
1862 JNIHelper helper(env);
1863 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Jerry Lee370ad502015-07-13 13:42:21 -07001864
1865 //reset alter handler
1866 ALOGD("android_net_wifi_reset_alert_handler = %p", handle);
1867 int result = hal_fn.wifi_reset_alert_handler(id, handle);
1868 if (result != WIFI_SUCCESS) {
1869 ALOGE(" Fail to reset alert handler");
1870 return false;
1871 }
1872
1873 //reset log handler
xinheb7978932015-06-25 17:57:21 -07001874 ALOGD("android_net_wifi_reset_log_handler = %p", handle);
Jerry Lee370ad502015-07-13 13:42:21 -07001875 result = hal_fn.wifi_reset_log_handler(id, handle);
1876 if (result != WIFI_SUCCESS) {
1877 ALOGE("Fail to reset logging handler");
1878 return false;
1879 }
1880
1881 return true;
xinheb7978932015-06-25 17:57:21 -07001882}
Jerry Lee370ad502015-07-13 13:42:21 -07001883
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001884// ----------------------------------------------------------------------------
1885// ePno framework
1886// ----------------------------------------------------------------------------
1887
1888
1889static void onPnoNetworkFound(wifi_request_id id,
1890 unsigned num_results, wifi_scan_result *results) {
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001891
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001892 JNIHelper helper(mVM);
1893
1894 ALOGD("onPnoNetworkFound called, vm = %p, obj = %p, num_results %u", mVM, mCls, num_results);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001895
1896 if (results == 0 || num_results == 0) {
1897 ALOGE("onPnoNetworkFound: Error no results");
1898 return;
1899 }
1900
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001901 jbyte *bytes;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001902 JNIObject<jobjectArray> scanResults(helper, NULL);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001903 //jbyteArray elements;
1904
1905 for (unsigned i=0; i<num_results; i++) {
1906
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001907 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001908 if (i == 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001909 scanResults = helper.newObjectArray(
1910 num_results, "android/net/wifi/ScanResult", scanResult);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001911 if (scanResults == 0) {
1912 ALOGD("cant allocate array");
1913 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001914 ALOGD("allocated array %u", helper.getArrayLength(scanResults));
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001915 }
1916 } else {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001917 helper.setObjectArrayElement(scanResults, i, scanResult);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001918 }
1919
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07001920 ALOGD("Scan result with ie length %d, i %u, <%s> rssi=%d %02x:%02x:%02x:%02x:%02x:%02x",
xinhe6d0cd102015-05-05 11:10:08 -07001921 results->ie_length, i, results[i].ssid, results[i].rssi, results[i].bssid[0],
1922 results[i].bssid[1],results[i].bssid[2], results[i].bssid[3], results[i].bssid[4],
1923 results[i].bssid[5]);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001924
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001925 /*elements = helper.newByteArray(results->ie_length);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001926 if (elements == NULL) {
1927 ALOGE("Error in allocating array");
1928 return;
1929 }*/
1930
1931 //ALOGD("onPnoNetworkFound: Setting byte array");
1932
1933 //bytes = (jbyte *)&(results->ie_data[0]);
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001934 //helper.setByteArrayRegion(elements, 0, results->ie_length, bytes);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001935
1936 //ALOGD("onPnoNetworkFound: Returning result");
1937 }
1938
1939
1940 ALOGD("calling report");
1941
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001942 helper.reportEvent(mCls, "onPnoNetworkFound", "(I[Landroid/net/wifi/ScanResult;)V", id,
1943 scanResults.get());
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001944 ALOGD("free ref");
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001945}
1946
1947static jboolean android_net_wifi_setPnoListNative(
1948 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {
1949
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001950 JNIHelper helper(env);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001951 wifi_epno_handler handler;
1952 handler.on_network_found = &onPnoNetworkFound;
1953
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001954 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001955 ALOGD("configure ePno list request [%d] = %p", id, handle);
1956
1957 if (list == NULL) {
1958 // stop pno
1959 int result = hal_fn.wifi_set_epno_list(id, handle, 0, NULL, handler);
1960 ALOGE(" setPnoListNative: STOP result = %d", result);
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07001961 return result >= 0;
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001962 }
1963
1964 wifi_epno_network net_list[MAX_PNO_SSID];
1965 memset(&net_list, 0, sizeof(net_list));
1966
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001967 size_t len = helper.getArrayLength((jobjectArray)list);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001968 if (len > (size_t)MAX_PNO_SSID) {
1969 return false;
1970 }
1971
1972 for (unsigned int i = 0; i < len; i++) {
1973
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001974 JNIObject<jobject> pno_net = helper.getObjectArrayElement((jobjectArray)list, i);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001975 if (pno_net == NULL) {
1976 ALOGD("setPnoListNative: could not get element %d", i);
1977 continue;
1978 }
1979
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001980 JNIObject<jstring> sssid = helper.getStringField(pno_net, "SSID");
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001981 if (sssid == NULL) {
1982 ALOGE("Error setPnoListNative: getting ssid field");
1983 return false;
1984 }
1985
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001986 ScopedUtfChars chars(env, (jstring)sssid.get());
1987 const char *ssid = chars.c_str();
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001988 if (ssid == NULL) {
1989 ALOGE("Error setPnoListNative: getting ssid");
1990 return false;
1991 }
1992 int ssid_len = strnlen((const char*)ssid, 33);
1993 if (ssid_len > 32) {
1994 ALOGE("Error setPnoListNative: long ssid %u", strnlen((const char*)ssid, 256));
1995 return false;
1996 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07001997
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07001998 if (ssid_len > 1 && ssid[0] == '"' && ssid[ssid_len-1])
1999 {
2000 // strip leading and trailing '"'
2001 ssid++;
2002 ssid_len-=2;
2003 }
2004 if (ssid_len == 0) {
2005 ALOGE("Error setPnoListNative: zero length ssid, skip it");
2006 continue;
2007 }
2008 memcpy(net_list[i].ssid, ssid, ssid_len);
2009
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002010 int rssit = helper.getIntField(pno_net, "rssi_threshold");
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07002011 net_list[i].rssi_threshold = (byte)rssit;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002012 int a = helper.getIntField(pno_net, "auth");
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07002013 net_list[i].auth_bit_field = a;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002014 int f = helper.getIntField(pno_net, "flags");
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07002015 net_list[i].flags = f;
xinhe03ba4a52015-04-28 14:40:44 -07002016 ALOGE(" setPnoListNative: idx %u rssi %d/%d auth %x/%x flags %x/%x [%s]", i,
Vinit Deshpandee5bf4b82015-05-13 18:38:10 -07002017 (signed)net_list[i].rssi_threshold, net_list[i].rssi_threshold,
xinhe03ba4a52015-04-28 14:40:44 -07002018 net_list[i].auth_bit_field, a, net_list[i].flags, f, net_list[i].ssid);
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07002019 }
2020
2021 int result = hal_fn.wifi_set_epno_list(id, handle, len, net_list, handler);
2022 ALOGE(" setPnoListNative: result %d", result);
2023
2024 return result >= 0;
2025}
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07002026
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002027static jboolean android_net_wifi_setLazyRoam(
2028 JNIEnv *env, jclass cls, jint iface, jint id, jboolean enabled, jobject roam_param) {
2029
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002030 JNIHelper helper(env);
Vinit Deshpandef49a59b2015-05-27 11:24:47 -07002031 wifi_error status = WIFI_SUCCESS;
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002032 wifi_roam_params params;
2033 memset(&params, 0, sizeof(params));
2034
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002035 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002036 ALOGD("configure lazy roam request [%d] = %p", id, handle);
2037
2038 if (roam_param != NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002039 params.A_band_boost_threshold = helper.getIntField(roam_param, "A_band_boost_threshold");
2040 params.A_band_penalty_threshold = helper.getIntField(roam_param, "A_band_penalty_threshold");
2041 params.A_band_boost_factor = helper.getIntField(roam_param, "A_band_boost_factor");
2042 params.A_band_penalty_factor = helper.getIntField(roam_param, "A_band_penalty_factor");
2043 params.A_band_max_boost = helper.getIntField(roam_param, "A_band_max_boost");
2044 params.lazy_roam_hysteresis = helper.getIntField(roam_param, "lazy_roam_hysteresis");
2045 params.alert_roam_rssi_trigger = helper.getIntField(roam_param, "alert_roam_rssi_trigger");
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002046 status = hal_fn.wifi_set_gscan_roam_params(id, handle, &params);
2047 }
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07002048 ALOGE("android_net_wifi_setLazyRoam configured params status=%d\n", status);
2049
2050 if (status >= 0) {
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002051 int doEnable = enabled ? 1 : 0;
2052 status = hal_fn.wifi_enable_lazy_roam(id, handle, doEnable);
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07002053 ALOGE("android_net_wifi_setLazyRoam enabled roam status=%d\n", status);
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002054 }
Pierre Vandwalleb0b0cc22015-05-06 13:57:06 -07002055 return status >= 0;
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002056}
2057
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002058static jboolean android_net_wifi_setBssidBlacklist(
2059 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {
2060
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002061 JNIHelper helper(env);
2062 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002063 ALOGD("configure BSSID black list request [%d] = %p", id, handle);
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002064
2065 wifi_bssid_params params;
2066 memset(&params, 0, sizeof(params));
2067
2068 if (list != NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002069 size_t len = helper.getArrayLength((jobjectArray)list);
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002070 if (len > (size_t)MAX_BLACKLIST_BSSID) {
2071 return false;
2072 }
2073 for (unsigned int i = 0; i < len; i++) {
2074
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002075 JNIObject<jobject> jbssid = helper.getObjectArrayElement(list, i);
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002076 if (jbssid == NULL) {
2077 ALOGD("configure BSSID blacklist: could not get element %d", i);
2078 continue;
2079 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002080
2081 ScopedUtfChars chars(env, (jstring)jbssid.get());
2082 const char *bssid = chars.c_str();
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002083 if (bssid == NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002084 ALOGE("Error getting bssid");
2085 return false;
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002086 }
2087
2088 mac_addr addr;
2089 parseMacAddress(bssid, addr);
2090 memcpy(params.bssids[i], addr, sizeof(mac_addr));
2091
2092 char bssidOut[32];
2093 sprintf(bssidOut, "%0x:%0x:%0x:%0x:%0x:%0x", addr[0], addr[1],
2094 addr[2], addr[3], addr[4], addr[5]);
2095
2096 ALOGD("BSSID blacklist: added bssid %s", bssidOut);
2097
2098 params.num_bssid++;
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002099 }
2100 }
2101
2102 ALOGD("Added %d bssids", params.num_bssid);
2103 return hal_fn.wifi_set_bssid_blacklist(id, handle, params) == WIFI_SUCCESS;
2104}
2105
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002106static jboolean android_net_wifi_setSsidWhitelist(
2107 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {
2108
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002109 JNIHelper helper(env);
2110 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002111 ALOGD("configure SSID white list request [%d] = %p", id, handle);
2112 wifi_ssid *ssids = NULL;
2113 int num_ssids = 0;
2114 if (list != NULL) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002115 size_t len = helper.getArrayLength((jobjectArray)list);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002116 if (len > 0) {
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002117 ssids = (wifi_ssid *)malloc(len * sizeof (wifi_ssid));
2118 if (!ssids) return false;
2119 memset(ssids, 0, len * sizeof (wifi_ssid));
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002120 for (unsigned int i = 0; i < len; i++) {
2121
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002122 JNIObject<jobject> jssid = helper.getObjectArrayElement(list, i);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002123 if (jssid == NULL) {
2124 ALOGD("configure SSID whitelist: could not get element %d", i);
2125 free(ssids);
2126 return false;
2127 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002128
2129 ScopedUtfChars chars(env, (jstring)jssid.get());
2130 const char *utf = chars.c_str();
2131 if (utf == NULL) {
2132 ALOGE("Error getting sssid");
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002133 free(ssids);
2134 return false;
2135 }
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002136
2137 int slen = strnlen(utf, 33);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002138 if (slen <= 0 || slen > 32) {
2139 ALOGE("Error wrong ssid length %d", slen);
2140 free(ssids);
2141 return false;
2142 }
2143
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002144 memcpy(ssids[i].ssid, utf, slen);
Pierre Vandwallebe2981a2015-05-20 18:20:45 -07002145 num_ssids++;
Vinit Deshpande7d519b62015-08-04 16:43:09 -07002146 ALOGD("SSID white list: added ssid %s", utf);
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002147 }
2148 }
2149 }
2150
2151 ALOGD("android_net_wifi_setSsidWhitelist Added %d sssids", num_ssids);
2152 return hal_fn.wifi_set_ssid_white_list(id, handle, num_ssids, ssids) == WIFI_SUCCESS;
2153}
2154
Prerepa Viswanadhamc55e8812015-07-01 15:18:22 -07002155static jint android_net_wifi_start_sending_offloaded_packet(JNIEnv *env, jclass cls, jint iface,
2156 jint idx, jbyteArray srcMac, jbyteArray dstMac, jbyteArray pkt, jint period) {
Vinit Deshpandeda515a82015-08-05 22:41:14 -07002157 JNIHelper helper(env);
2158 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Prerepa Viswanadhamc55e8812015-07-01 15:18:22 -07002159 ALOGD("Start packet offload [%d] = %p", idx, handle);
2160 wifi_error ret;
2161 wifi_request_id id = idx;
Vinit Deshpandeda515a82015-08-05 22:41:14 -07002162
2163 ScopedBytesRO pktBytes(env, pkt), srcMacBytes(env, srcMac), dstMacBytes(env, dstMac);
2164
2165 byte * pkt_data = (byte*) pktBytes.get();
Prerepa Viswanadhamc55e8812015-07-01 15:18:22 -07002166 unsigned short pkt_len = env->GetArrayLength(pkt);
Vinit Deshpandeda515a82015-08-05 22:41:14 -07002167 byte* src_mac_addr = (byte*) srcMacBytes.get();
2168 byte* dst_mac_addr = (byte*) dstMacBytes.get();
Prerepa Viswanadhamc55e8812015-07-01 15:18:22 -07002169 int i;
2170 char macAddr[32];
2171 sprintf(macAddr, "%0x:%0x:%0x:%0x:%0x:%0x", src_mac_addr[0], src_mac_addr[1],
2172 src_mac_addr[2], src_mac_addr[3], src_mac_addr[4], src_mac_addr[5]);
2173 ALOGD("src_mac_addr %s", macAddr);
2174 sprintf(macAddr, "%0x:%0x:%0x:%0x:%0x:%0x", dst_mac_addr[0], dst_mac_addr[1],
2175 dst_mac_addr[2], dst_mac_addr[3], dst_mac_addr[4], dst_mac_addr[5]);
2176 ALOGD("dst_mac_addr %s", macAddr);
2177 ALOGD("pkt_len %d\n", pkt_len);
2178 ALOGD("Pkt data : ");
2179 for(i = 0; i < pkt_len; i++) {
2180 ALOGD(" %x ", pkt_data[i]);
2181 }
2182 ALOGD("\n");
2183 ret = hal_fn.wifi_start_sending_offloaded_packet(id, handle, pkt_data, pkt_len,
2184 src_mac_addr, dst_mac_addr, period);
2185 ALOGD("ret= %d\n", ret);
2186 return ret;
2187}
2188
2189static jint android_net_wifi_stop_sending_offloaded_packet(JNIEnv *env, jclass cls,
2190 jint iface, jint idx) {
2191 int ret;
Vinit Deshpandeda515a82015-08-05 22:41:14 -07002192 JNIHelper helper(env);
2193 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Prerepa Viswanadhamc55e8812015-07-01 15:18:22 -07002194 ALOGD("Stop packet offload [%d] = %p", idx, handle);
2195 ret = hal_fn.wifi_stop_sending_offloaded_packet(idx, handle);
2196 ALOGD("ret= %d\n", ret);
2197 return ret;
2198}
Prerepa Viswanadhamc2b197d2015-07-13 23:50:31 -07002199
2200static void onRssiThresholdbreached(wifi_request_id id, u8 *cur_bssid, s8 cur_rssi) {
2201
2202 ALOGD("RSSI threshold breached, cur RSSI - %d!!\n", cur_rssi);
2203 ALOGD("BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
2204 cur_bssid[0], cur_bssid[1], cur_bssid[2],
2205 cur_bssid[3], cur_bssid[4], cur_bssid[5]);
Vinit Deshpandeda515a82015-08-05 22:41:14 -07002206 JNIHelper helper(mVM);
Prerepa Viswanadhamc2b197d2015-07-13 23:50:31 -07002207 //ALOGD("onRssiThresholdbreached called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
Vinit Deshpandeda515a82015-08-05 22:41:14 -07002208 helper.reportEvent(mCls, "onRssiThresholdBreached", "(IB)V", id, cur_rssi);
Prerepa Viswanadhamc2b197d2015-07-13 23:50:31 -07002209}
2210
2211static jint android_net_wifi_start_rssi_monitoring_native(JNIEnv *env, jclass cls, jint iface,
2212 jint idx, jbyte maxRssi, jbyte minRssi) {
2213
Vinit Deshpandeda515a82015-08-05 22:41:14 -07002214 JNIHelper helper(env);
2215 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Prerepa Viswanadhamc2b197d2015-07-13 23:50:31 -07002216 ALOGD("Start Rssi monitoring = %p", handle);
2217 ALOGD("MinRssi %d MaxRssi %d", minRssi, maxRssi);
2218 wifi_error ret;
2219 wifi_request_id id = idx;
2220 wifi_rssi_event_handler eh;
2221 eh.on_rssi_threshold_breached = onRssiThresholdbreached;
2222 ret = hal_fn.wifi_start_rssi_monitoring(id, handle, maxRssi, minRssi, eh);
2223 return ret;
2224}
2225
2226static jint android_net_wifi_stop_rssi_monitoring_native(JNIEnv *env, jclass cls,
2227 jint iface, jint idx) {
Vinit Deshpandeda515a82015-08-05 22:41:14 -07002228 JNIHelper helper(env);
2229 wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
Prerepa Viswanadhamc2b197d2015-07-13 23:50:31 -07002230 ALOGD("Stop Rssi monitoring = %p", handle);
2231 wifi_error ret;
2232 wifi_request_id id = idx;
2233 ret = hal_fn.wifi_stop_rssi_monitoring(id, handle);
2234 return ret;
2235}
2236
Vinit Deshpande155b9d02014-01-08 23:46:46 +00002237// ----------------------------------------------------------------------------
2238
2239/*
2240 * JNI registration.
2241 */
2242static JNINativeMethod gWifiMethods[] = {
2243 /* name, signature, funcPtr */
2244
2245 { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
2246 { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded },
2247 { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
2248 { "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant },
2249 { "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant },
2250 { "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant },
2251 { "closeSupplicantConnectionNative", "()V",
2252 (void *)android_net_wifi_closeSupplicantConnection },
2253 { "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForEvent },
2254 { "doBooleanCommandNative", "(Ljava/lang/String;)Z", (void*)android_net_wifi_doBooleanCommand },
2255 { "doIntCommandNative", "(Ljava/lang/String;)I", (void*)android_net_wifi_doIntCommand },
2256 { "doStringCommandNative", "(Ljava/lang/String;)Ljava/lang/String;",
2257 (void*) android_net_wifi_doStringCommand },
Vinit Deshapnde7ef73dd2014-02-28 08:42:14 -08002258 { "startHalNative", "()Z", (void*) android_net_wifi_startHal },
2259 { "stopHalNative", "()V", (void*) android_net_wifi_stopHal },
2260 { "waitForHalEventNative", "()V", (void*) android_net_wifi_waitForHalEvents },
Vinit Deshapnde7f9a15d2014-05-07 16:29:44 -07002261 { "getInterfacesNative", "()I", (void*) android_net_wifi_getInterfaces},
2262 { "getInterfaceNameNative", "(I)Ljava/lang/String;", (void*) android_net_wifi_getInterfaceName},
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002263 { "getScanCapabilitiesNative", "(ILcom/android/server/wifi/WifiNative$ScanCapabilities;)Z",
2264 (void *) android_net_wifi_getScanCapabilities},
2265 { "startScanNative", "(IILcom/android/server/wifi/WifiNative$ScanSettings;)Z",
2266 (void*) android_net_wifi_startScan},
2267 { "stopScanNative", "(II)Z", (void*) android_net_wifi_stopScan},
Vinit Deshpandec591ab32014-10-31 11:15:26 -07002268 { "getScanResultsNative", "(IZ)[Landroid/net/wifi/WifiScanner$ScanData;",
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002269 (void *) android_net_wifi_getScanResults},
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002270 { "setHotlistNative", "(IILandroid/net/wifi/WifiScanner$HotlistSettings;)Z",
2271 (void*) android_net_wifi_setHotlist},
2272 { "resetHotlistNative", "(II)Z", (void*) android_net_wifi_resetHotlist},
Vinit Deshapndee4e37502014-05-05 11:32:21 -07002273 { "trackSignificantWifiChangeNative", "(IILandroid/net/wifi/WifiScanner$WifiChangeSettings;)Z",
2274 (void*) android_net_wifi_trackSignificantWifiChange},
2275 { "untrackSignificantWifiChangeNative", "(II)Z",
vandwalleaabe7a92014-05-09 18:11:02 -07002276 (void*) android_net_wifi_untrackSignificantWifiChange},
2277 { "getWifiLinkLayerStatsNative", "(I)Landroid/net/wifi/WifiLinkLayerStats;",
Vinit Deshpandea632d8a2014-07-01 14:12:13 -07002278 (void*) android_net_wifi_getLinkLayerStats},
Pierre Vandwalled745a522015-06-11 17:48:58 -07002279 { "setWifiLinkLayerStatsNative", "(II)V",
2280 (void*) android_net_wifi_setLinkLayerStats},
Vinit Deshpandec35361d2014-08-07 16:24:10 -07002281 { "getSupportedFeatureSetNative", "(I)I",
Vinit Deshpande14365732014-06-30 15:23:23 -07002282 (void*) android_net_wifi_getSupportedFeatures},
2283 { "requestRangeNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z",
2284 (void*) android_net_wifi_requestRange},
2285 { "cancelRangeRequestNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z",
Vinit Deshpande042c54b2014-08-21 13:52:21 -07002286 (void*) android_net_wifi_cancelRange},
Vinit Deshpande90b902d2014-10-13 13:21:47 -07002287 { "setScanningMacOuiNative", "(I[B)Z", (void*) android_net_wifi_setScanningMacOui},
2288 { "getChannelsForBandNative", "(II)[I", (void*) android_net_wifi_getValidChannels},
xinheb830d762015-02-11 17:14:17 -08002289 { "setDfsFlagNative", "(IZ)Z", (void*) android_net_wifi_setDfsFlag},
xinhe12cf3882015-03-12 18:38:54 -07002290 { "toggleInterfaceNative", "(I)Z", (void*) android_net_wifi_toggle_interface},
2291 { "getRttCapabilitiesNative", "(I)Landroid/net/wifi/RttManager$RttCapabilities;",
Pierre Vandwallea0d34d32015-03-18 17:19:01 -07002292 (void*) android_net_wifi_get_rtt_capabilities},
xinhe939177f2015-03-23 14:43:03 -07002293 {"setCountryCodeHalNative", "(ILjava/lang/String;)Z",
Pierre Vandwalledd490cf2015-03-20 18:43:31 -07002294 (void*) android_net_wifi_set_Country_Code_Hal},
2295 { "setPnoListNative", "(II[Lcom/android/server/wifi/WifiNative$WifiPnoNetwork;)Z",
xinhed57f6302015-04-15 13:23:43 -07002296 (void*) android_net_wifi_setPnoListNative},
2297 {"enableDisableTdlsNative", "(IZLjava/lang/String;)Z",
2298 (void*) android_net_wifi_enable_disable_tdls},
2299 {"getTdlsStatusNative", "(ILjava/lang/String;)Lcom/android/server/wifi/WifiNative$TdlsStatus;",
2300 (void*) android_net_wifi_get_tdls_status},
2301 {"getTdlsCapabilitiesNative", "(I)Lcom/android/server/wifi/WifiNative$TdlsCapabilities;",
xinhe03ba4a52015-04-28 14:40:44 -07002302 (void*) android_net_wifi_get_tdls_capabilities},
2303 {"getSupportedLoggerFeatureSetNative","(I)I",
2304 (void*) android_net_wifi_get_supported_logger_feature},
2305 {"getDriverVersionNative", "(I)Ljava/lang/String;",
2306 (void*) android_net_wifi_get_driver_version},
2307 {"getFirmwareVersionNative", "(I)Ljava/lang/String;",
2308 (void*) android_net_wifi_get_firmware_version},
Vinit Deshpande0bf150b2015-06-01 14:13:04 -07002309 {"getRingBufferStatusNative", "(I)[Lcom/android/server/wifi/WifiNative$RingBufferStatus;",
xinhe03ba4a52015-04-28 14:40:44 -07002310 (void*) android_net_wifi_get_ring_buffer_status},
2311 {"startLoggingRingBufferNative", "(IIIIILjava/lang/String;)Z",
2312 (void*) android_net_wifi_start_logging_ring_buffer},
2313 {"getRingBufferDataNative", "(ILjava/lang/String;)Z",
2314 (void*) android_net_wifi_get_ring_buffer_data},
Pierre Vandwalled4c25fd2015-04-17 13:50:41 -07002315 {"getFwMemoryDumpNative","(I)Z", (void*) android_net_wifi_get_fw_memory_dump},
Pierre Vandwalle9ccffbb2015-05-15 16:34:17 -07002316 { "setLazyRoamNative", "(IIZLcom/android/server/wifi/WifiNative$WifiLazyRoamParams;)Z",
2317 (void*) android_net_wifi_setLazyRoam},
2318 { "setBssidBlacklistNative", "(II[Ljava/lang/String;)Z",
Pierre Vandwalle5caa43b2015-05-15 17:42:46 -07002319 (void*)android_net_wifi_setBssidBlacklist},
2320 { "setSsidWhitelistNative", "(II[Ljava/lang/String;)Z",
xinheee0a0132015-08-04 14:27:27 -07002321 (void*)android_net_wifi_setSsidWhitelist},
xinheb7978932015-06-25 17:57:21 -07002322 {"setLoggingEventHandlerNative", "(II)Z", (void *) android_net_wifi_set_log_handler},
xinheee0a0132015-08-04 14:27:27 -07002323 {"resetLogHandlerNative", "(II)Z", (void *) android_net_wifi_reset_log_handler},
Prerepa Viswanadhamc55e8812015-07-01 15:18:22 -07002324 { "startSendingOffloadedPacketNative", "(II[B[B[BI)I",
2325 (void*)android_net_wifi_start_sending_offloaded_packet},
2326 { "stopSendingOffloadedPacketNative", "(II)I",
Prerepa Viswanadhamc2b197d2015-07-13 23:50:31 -07002327 (void*)android_net_wifi_stop_sending_offloaded_packet},
2328 {"startRssiMonitoringNative", "(IIBB)I",
2329 (void*)android_net_wifi_start_rssi_monitoring_native},
2330 {"stopRssiMonitoringNative", "(II)I",
xinhe9dc6bda2015-08-05 15:17:22 -07002331 (void*)android_net_wifi_stop_rssi_monitoring_native},
xinheee0a0132015-08-04 14:27:27 -07002332 {"isGetChannelsForBandSupportedNative", "()Z",
2333 (void*)android_net_wifi_is_get_channels_for_band_supported}
Vinit Deshpande155b9d02014-01-08 23:46:46 +00002334};
2335
2336int register_android_net_wifi_WifiNative(JNIEnv* env) {
2337 return AndroidRuntime::registerNativeMethods(env,
2338 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods));
2339}
2340
2341
2342/* User to register native functions */
2343extern "C"
2344jint Java_com_android_server_wifi_WifiNative_registerNatives(JNIEnv* env, jclass clazz) {
2345 return AndroidRuntime::registerNativeMethods(env,
2346 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods));
2347}
2348
2349}; // namespace android