blob: 9537ac478656388ef2cfa927f2d741e103e62ad0 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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"
Elliott Hughesf17b9712011-04-12 16:12:09 -070020#include <ScopedUtfChars.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021#include <utils/misc.h>
22#include <android_runtime/AndroidRuntime.h>
23#include <utils/Log.h>
Zheng BaoZhong038e3152009-10-10 08:07:44 -040024#include <utils/String16.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025
26#include "wifi.h"
27
28#define WIFI_PKG_NAME "android/net/wifi/WifiNative"
Irfan Sherifff235c5a2010-10-21 16:44:48 -070029#define BUF_SIZE 256
Irfan Sheriff21ba8152012-04-04 16:22:21 -070030#define EVENT_BUF_SIZE 2048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
32namespace android {
33
Irfan Sheriff618455f2011-11-18 14:33:09 -080034static jint DBG = false;
Mike Lockwooda5ec95c2009-07-08 17:11:17 -040035
Irfan Sheriff44b330d2011-12-28 13:00:28 -080036static int doCommand(const char *ifname, const char *cmd, char *replybuf, int replybuflen)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037{
38 size_t reply_len = replybuflen - 1;
39
Irfan Sheriff44b330d2011-12-28 13:00:28 -080040 if (::wifi_command(ifname, cmd, replybuf, &reply_len) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041 return -1;
42 else {
43 // Strip off trailing newline
44 if (reply_len > 0 && replybuf[reply_len-1] == '\n')
45 replybuf[reply_len-1] = '\0';
46 else
47 replybuf[reply_len] = '\0';
48 return 0;
49 }
50}
51
Irfan Sheriff44b330d2011-12-28 13:00:28 -080052static jint doIntCommand(const char *ifname, const char* fmt, ...)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053{
Elliott Hughesf17b9712011-04-12 16:12:09 -070054 char buf[BUF_SIZE];
55 va_list args;
56 va_start(args, fmt);
57 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
58 va_end(args);
59 if (byteCount < 0 || byteCount >= BUF_SIZE) {
60 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 }
Elliott Hughesf17b9712011-04-12 16:12:09 -070062 char reply[BUF_SIZE];
Irfan Sheriff44b330d2011-12-28 13:00:28 -080063 if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
Elliott Hughesf17b9712011-04-12 16:12:09 -070064 return -1;
65 }
66 return static_cast<jint>(atoi(reply));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067}
68
Irfan Sheriff44b330d2011-12-28 13:00:28 -080069static jboolean doBooleanCommand(const char *ifname, const char* expect, const char* fmt, ...)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070{
Elliott Hughesf17b9712011-04-12 16:12:09 -070071 char buf[BUF_SIZE];
72 va_list args;
73 va_start(args, fmt);
74 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
75 va_end(args);
76 if (byteCount < 0 || byteCount >= BUF_SIZE) {
77 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 }
Elliott Hughesf17b9712011-04-12 16:12:09 -070079 char reply[BUF_SIZE];
Irfan Sheriff44b330d2011-12-28 13:00:28 -080080 if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
Elliott Hughesf17b9712011-04-12 16:12:09 -070081 return JNI_FALSE;
82 }
83 return (strcmp(reply, expect) == 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084}
85
86// Send a command to the supplicant, and return the reply as a String
Irfan Sheriff44b330d2011-12-28 13:00:28 -080087static jstring doStringCommand(JNIEnv* env, const char *ifname, const char* fmt, ...) {
Elliott Hughesf17b9712011-04-12 16:12:09 -070088 char buf[BUF_SIZE];
89 va_list args;
90 va_start(args, fmt);
91 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
92 va_end(args);
93 if (byteCount < 0 || byteCount >= BUF_SIZE) {
94 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 }
Elliott Hughesf17b9712011-04-12 16:12:09 -070096 char reply[4096];
Irfan Sheriff44b330d2011-12-28 13:00:28 -080097 if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
Elliott Hughesf17b9712011-04-12 16:12:09 -070098 return NULL;
99 }
100 // TODO: why not just NewStringUTF?
101 String16 str((char *)reply);
102 return env->NewString((const jchar *)str.string(), str.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103}
104
Elliott Hughesf17b9712011-04-12 16:12:09 -0700105static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject)
Irfan Sheriffa2a1b912010-06-07 09:03:04 -0700106{
107 return (jboolean)(::is_wifi_driver_loaded() == 1);
108}
109
Elliott Hughesf17b9712011-04-12 16:12:09 -0700110static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111{
112 return (jboolean)(::wifi_load_driver() == 0);
113}
114
Elliott Hughesf17b9712011-04-12 16:12:09 -0700115static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116{
117 return (jboolean)(::wifi_unload_driver() == 0);
118}
119
Irfan Sheriff7d6d9c02012-01-10 15:50:45 -0800120static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121{
Irfan Sheriff7d6d9c02012-01-10 15:50:45 -0800122 return (jboolean)(::wifi_start_supplicant(p2pSupported) == 0);
Irfan Sherifff42c39b2011-08-26 14:45:23 -0700123}
124
Irfan Sheriff511d5342012-11-03 23:20:38 -0700125static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126{
Irfan Sheriff511d5342012-11-03 23:20:38 -0700127 return (jboolean)(::wifi_stop_supplicant(p2pSupported) == 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128}
129
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800130static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject, jstring jIface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131{
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800132 ScopedUtfChars ifname(env, jIface);
133 return (jboolean)(::wifi_connect_to_supplicant(ifname.c_str()) == 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134}
135
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800136static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject, jstring jIface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137{
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800138 ScopedUtfChars ifname(env, jIface);
139 ::wifi_close_supplicant_connection(ifname.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140}
141
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800142static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject, jstring jIface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143{
Irfan Sheriff21ba8152012-04-04 16:22:21 -0700144 char buf[EVENT_BUF_SIZE];
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800145 ScopedUtfChars ifname(env, jIface);
146 int nread = ::wifi_wait_for_event(ifname.c_str(), buf, sizeof buf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 if (nread > 0) {
148 return env->NewStringUTF(buf);
149 } else {
Elliott Hughesf17b9712011-04-12 16:12:09 -0700150 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 }
152}
153
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800154static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring jIface,
155 jstring jCommand)
repo sync55bc5f32011-06-24 14:23:07 -0700156{
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800157 ScopedUtfChars ifname(env, jIface);
158 ScopedUtfChars command(env, jCommand);
159
repo sync55bc5f32011-06-24 14:23:07 -0700160 if (command.c_str() == NULL) {
161 return JNI_FALSE;
162 }
Steve Block5baa3a62011-12-20 16:23:08 +0000163 if (DBG) ALOGD("doBoolean: %s", command.c_str());
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800164 return doBooleanCommand(ifname.c_str(), "OK", "%s", command.c_str());
repo sync55bc5f32011-06-24 14:23:07 -0700165}
166
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800167static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring jIface,
168 jstring jCommand)
repo sync55bc5f32011-06-24 14:23:07 -0700169{
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800170 ScopedUtfChars ifname(env, jIface);
171 ScopedUtfChars command(env, jCommand);
172
repo sync55bc5f32011-06-24 14:23:07 -0700173 if (command.c_str() == NULL) {
174 return -1;
175 }
Steve Block5baa3a62011-12-20 16:23:08 +0000176 if (DBG) ALOGD("doInt: %s", command.c_str());
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800177 return doIntCommand(ifname.c_str(), "%s", command.c_str());
repo sync55bc5f32011-06-24 14:23:07 -0700178}
179
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800180static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring jIface,
181 jstring jCommand)
repo sync55bc5f32011-06-24 14:23:07 -0700182{
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800183 ScopedUtfChars ifname(env, jIface);
184
185 ScopedUtfChars command(env, jCommand);
repo sync55bc5f32011-06-24 14:23:07 -0700186 if (command.c_str() == NULL) {
187 return NULL;
188 }
Steve Block5baa3a62011-12-20 16:23:08 +0000189 if (DBG) ALOGD("doString: %s", command.c_str());
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800190 return doStringCommand(env, ifname.c_str(), "%s", command.c_str());
repo sync55bc5f32011-06-24 14:23:07 -0700191}
192
193
194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195// ----------------------------------------------------------------------------
196
197/*
198 * JNI registration.
199 */
200static JNINativeMethod gWifiMethods[] = {
201 /* name, signature, funcPtr */
202
203 { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800204 { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
Irfan Sheriff7d6d9c02012-01-10 15:50:45 -0800206 { "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant },
Irfan Sheriff511d5342012-11-03 23:20:38 -0700207 { "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant },
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800208 { "connectToSupplicant", "(Ljava/lang/String;)Z",
209 (void *)android_net_wifi_connectToSupplicant },
210 { "closeSupplicantConnection", "(Ljava/lang/String;)V",
211 (void *)android_net_wifi_closeSupplicantConnection },
212 { "waitForEvent", "(Ljava/lang/String;)Ljava/lang/String;",
213 (void*) android_net_wifi_waitForEvent },
214 { "doBooleanCommand", "(Ljava/lang/String;Ljava/lang/String;)Z",
215 (void*) android_net_wifi_doBooleanCommand },
216 { "doIntCommand", "(Ljava/lang/String;Ljava/lang/String;)I",
217 (void*) android_net_wifi_doIntCommand },
218 { "doStringCommand", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
219 (void*) android_net_wifi_doStringCommand },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220};
221
222int register_android_net_wifi_WifiManager(JNIEnv* env)
223{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 return AndroidRuntime::registerNativeMethods(env,
225 WIFI_PKG_NAME, gWifiMethods, NELEM(gWifiMethods));
226}
227
228}; // namespace android