blob: 2ac3ca8d8da4285c0eaa0b07eb9280601cee7c21 [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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
31namespace android {
32
Irfan Sheriff618455f2011-11-18 14:33:09 -080033static jint DBG = false;
Mike Lockwooda5ec95c2009-07-08 17:11:17 -040034
Irfan Sheriff44b330d2011-12-28 13:00:28 -080035static int doCommand(const char *ifname, const char *cmd, char *replybuf, int replybuflen)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036{
37 size_t reply_len = replybuflen - 1;
38
Irfan Sheriff44b330d2011-12-28 13:00:28 -080039 if (::wifi_command(ifname, cmd, replybuf, &reply_len) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 return -1;
41 else {
42 // Strip off trailing newline
43 if (reply_len > 0 && replybuf[reply_len-1] == '\n')
44 replybuf[reply_len-1] = '\0';
45 else
46 replybuf[reply_len] = '\0';
47 return 0;
48 }
49}
50
Irfan Sheriff44b330d2011-12-28 13:00:28 -080051static jint doIntCommand(const char *ifname, const char* fmt, ...)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052{
Elliott Hughesf17b9712011-04-12 16:12:09 -070053 char buf[BUF_SIZE];
54 va_list args;
55 va_start(args, fmt);
56 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
57 va_end(args);
58 if (byteCount < 0 || byteCount >= BUF_SIZE) {
59 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 }
Elliott Hughesf17b9712011-04-12 16:12:09 -070061 char reply[BUF_SIZE];
Irfan Sheriff44b330d2011-12-28 13:00:28 -080062 if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
Elliott Hughesf17b9712011-04-12 16:12:09 -070063 return -1;
64 }
65 return static_cast<jint>(atoi(reply));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066}
67
Irfan Sheriff44b330d2011-12-28 13:00:28 -080068static jboolean doBooleanCommand(const char *ifname, const char* expect, const char* fmt, ...)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069{
Elliott Hughesf17b9712011-04-12 16:12:09 -070070 char buf[BUF_SIZE];
71 va_list args;
72 va_start(args, fmt);
73 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
74 va_end(args);
75 if (byteCount < 0 || byteCount >= BUF_SIZE) {
76 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 }
Elliott Hughesf17b9712011-04-12 16:12:09 -070078 char reply[BUF_SIZE];
Irfan Sheriff44b330d2011-12-28 13:00:28 -080079 if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
Elliott Hughesf17b9712011-04-12 16:12:09 -070080 return JNI_FALSE;
81 }
82 return (strcmp(reply, expect) == 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083}
84
85// Send a command to the supplicant, and return the reply as a String
Irfan Sheriff44b330d2011-12-28 13:00:28 -080086static jstring doStringCommand(JNIEnv* env, const char *ifname, const char* fmt, ...) {
Elliott Hughesf17b9712011-04-12 16:12:09 -070087 char buf[BUF_SIZE];
88 va_list args;
89 va_start(args, fmt);
90 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
91 va_end(args);
92 if (byteCount < 0 || byteCount >= BUF_SIZE) {
93 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 }
Elliott Hughesf17b9712011-04-12 16:12:09 -070095 char reply[4096];
Irfan Sheriff44b330d2011-12-28 13:00:28 -080096 if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
Elliott Hughesf17b9712011-04-12 16:12:09 -070097 return NULL;
98 }
99 // TODO: why not just NewStringUTF?
100 String16 str((char *)reply);
101 return env->NewString((const jchar *)str.string(), str.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102}
103
Elliott Hughesf17b9712011-04-12 16:12:09 -0700104static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject)
Irfan Sheriffa2a1b912010-06-07 09:03:04 -0700105{
106 return (jboolean)(::is_wifi_driver_loaded() == 1);
107}
108
Elliott Hughesf17b9712011-04-12 16:12:09 -0700109static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110{
111 return (jboolean)(::wifi_load_driver() == 0);
112}
113
Elliott Hughesf17b9712011-04-12 16:12:09 -0700114static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115{
116 return (jboolean)(::wifi_unload_driver() == 0);
117}
118
Elliott Hughesf17b9712011-04-12 16:12:09 -0700119static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120{
121 return (jboolean)(::wifi_start_supplicant() == 0);
122}
123
Irfan Sherifff42c39b2011-08-26 14:45:23 -0700124static jboolean android_net_wifi_startP2pSupplicant(JNIEnv* env, jobject)
125{
126 return (jboolean)(::wifi_start_p2p_supplicant() == 0);
127}
128
Elliott Hughesf17b9712011-04-12 16:12:09 -0700129static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130{
131 return (jboolean)(::wifi_stop_supplicant() == 0);
132}
133
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800134static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject, jstring jIface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135{
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800136 ScopedUtfChars ifname(env, jIface);
137 return (jboolean)(::wifi_connect_to_supplicant(ifname.c_str()) == 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138}
139
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800140static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject, jstring jIface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141{
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800142 ScopedUtfChars ifname(env, jIface);
143 ::wifi_close_supplicant_connection(ifname.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144}
145
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800146static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject, jstring jIface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147{
Irfan Sherifff235c5a2010-10-21 16:44:48 -0700148 char buf[BUF_SIZE];
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800149 ScopedUtfChars ifname(env, jIface);
150 int nread = ::wifi_wait_for_event(ifname.c_str(), buf, sizeof buf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 if (nread > 0) {
152 return env->NewStringUTF(buf);
153 } else {
Elliott Hughesf17b9712011-04-12 16:12:09 -0700154 return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 }
156}
157
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800158static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring jIface,
159 jstring jCommand)
repo sync55bc5f32011-06-24 14:23:07 -0700160{
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800161 ScopedUtfChars ifname(env, jIface);
162 ScopedUtfChars command(env, jCommand);
163
repo sync55bc5f32011-06-24 14:23:07 -0700164 if (command.c_str() == NULL) {
165 return JNI_FALSE;
166 }
Steve Block5baa3a62011-12-20 16:23:08 +0000167 if (DBG) ALOGD("doBoolean: %s", command.c_str());
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800168 return doBooleanCommand(ifname.c_str(), "OK", "%s", command.c_str());
repo sync55bc5f32011-06-24 14:23:07 -0700169}
170
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800171static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring jIface,
172 jstring jCommand)
repo sync55bc5f32011-06-24 14:23:07 -0700173{
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800174 ScopedUtfChars ifname(env, jIface);
175 ScopedUtfChars command(env, jCommand);
176
repo sync55bc5f32011-06-24 14:23:07 -0700177 if (command.c_str() == NULL) {
178 return -1;
179 }
Steve Block5baa3a62011-12-20 16:23:08 +0000180 if (DBG) ALOGD("doInt: %s", command.c_str());
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800181 return doIntCommand(ifname.c_str(), "%s", command.c_str());
repo sync55bc5f32011-06-24 14:23:07 -0700182}
183
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800184static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring jIface,
185 jstring jCommand)
repo sync55bc5f32011-06-24 14:23:07 -0700186{
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800187 ScopedUtfChars ifname(env, jIface);
188
189 ScopedUtfChars command(env, jCommand);
repo sync55bc5f32011-06-24 14:23:07 -0700190 if (command.c_str() == NULL) {
191 return NULL;
192 }
Steve Block5baa3a62011-12-20 16:23:08 +0000193 if (DBG) ALOGD("doString: %s", command.c_str());
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800194 return doStringCommand(env, ifname.c_str(), "%s", command.c_str());
repo sync55bc5f32011-06-24 14:23:07 -0700195}
196
197
198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199// ----------------------------------------------------------------------------
200
201/*
202 * JNI registration.
203 */
204static JNINativeMethod gWifiMethods[] = {
205 /* name, signature, funcPtr */
206
207 { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800208 { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
210 { "startSupplicant", "()Z", (void *)android_net_wifi_startSupplicant },
Irfan Sherifff42c39b2011-08-26 14:45:23 -0700211 { "startP2pSupplicant", "()Z", (void *)android_net_wifi_startP2pSupplicant },
Irfan Sheriff96071a72010-12-14 11:29:23 -0800212 { "killSupplicant", "()Z", (void *)android_net_wifi_killSupplicant },
Irfan Sheriff44b330d2011-12-28 13:00:28 -0800213 { "connectToSupplicant", "(Ljava/lang/String;)Z",
214 (void *)android_net_wifi_connectToSupplicant },
215 { "closeSupplicantConnection", "(Ljava/lang/String;)V",
216 (void *)android_net_wifi_closeSupplicantConnection },
217 { "waitForEvent", "(Ljava/lang/String;)Ljava/lang/String;",
218 (void*) android_net_wifi_waitForEvent },
219 { "doBooleanCommand", "(Ljava/lang/String;Ljava/lang/String;)Z",
220 (void*) android_net_wifi_doBooleanCommand },
221 { "doIntCommand", "(Ljava/lang/String;Ljava/lang/String;)I",
222 (void*) android_net_wifi_doIntCommand },
223 { "doStringCommand", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
224 (void*) android_net_wifi_doStringCommand },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225};
226
227int register_android_net_wifi_WifiManager(JNIEnv* env)
228{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 return AndroidRuntime::registerNativeMethods(env,
230 WIFI_PKG_NAME, gWifiMethods, NELEM(gWifiMethods));
231}
232
233}; // namespace android