| /* |
| * Copyright 2008, The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_TAG "wifi" |
| |
| #include "jni.h" |
| #include <ScopedUtfChars.h> |
| #include <utils/misc.h> |
| #include <android_runtime/AndroidRuntime.h> |
| #include <utils/Log.h> |
| #include <utils/String16.h> |
| |
| #include "wifi.h" |
| |
| #define REPLY_BUF_SIZE 4096 // wpa_supplicant's maximum size. |
| #define EVENT_BUF_SIZE 2048 |
| |
| namespace android { |
| |
| static jint DBG = false; |
| |
| static bool doCommand(JNIEnv* env, jstring javaCommand, |
| char* reply, size_t reply_len) { |
| ScopedUtfChars command(env, javaCommand); |
| if (command.c_str() == NULL) { |
| return false; // ScopedUtfChars already threw on error. |
| } |
| |
| if (DBG) { |
| ALOGD("doCommand: %s", command.c_str()); |
| } |
| |
| --reply_len; // Ensure we have room to add NUL termination. |
| if (::wifi_command(command.c_str(), reply, &reply_len) != 0) { |
| return false; |
| } |
| |
| // Strip off trailing newline. |
| if (reply_len > 0 && reply[reply_len-1] == '\n') { |
| reply[reply_len-1] = '\0'; |
| } else { |
| reply[reply_len] = '\0'; |
| } |
| return true; |
| } |
| |
| static jint doIntCommand(JNIEnv* env, jstring javaCommand) { |
| char reply[REPLY_BUF_SIZE]; |
| if (!doCommand(env, javaCommand, reply, sizeof(reply))) { |
| return -1; |
| } |
| return static_cast<jint>(atoi(reply)); |
| } |
| |
| static jboolean doBooleanCommand(JNIEnv* env, jstring javaCommand) { |
| char reply[REPLY_BUF_SIZE]; |
| if (!doCommand(env, javaCommand, reply, sizeof(reply))) { |
| return JNI_FALSE; |
| } |
| return (strcmp(reply, "OK") == 0); |
| } |
| |
| // Send a command to the supplicant, and return the reply as a String. |
| static jstring doStringCommand(JNIEnv* env, jstring javaCommand) { |
| char reply[REPLY_BUF_SIZE]; |
| if (!doCommand(env, javaCommand, reply, sizeof(reply))) { |
| return NULL; |
| } |
| return env->NewStringUTF(reply); |
| } |
| |
| static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject) |
| { |
| return (::is_wifi_driver_loaded() == 1); |
| } |
| |
| static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject) |
| { |
| return (::wifi_load_driver() == 0); |
| } |
| |
| static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject) |
| { |
| return (::wifi_unload_driver() == 0); |
| } |
| |
| static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) |
| { |
| return (::wifi_start_supplicant(p2pSupported) == 0); |
| } |
| |
| static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) |
| { |
| return (::wifi_stop_supplicant(p2pSupported) == 0); |
| } |
| |
| static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject) |
| { |
| return (::wifi_connect_to_supplicant() == 0); |
| } |
| |
| static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject) |
| { |
| ::wifi_close_supplicant_connection(); |
| } |
| |
| static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject) |
| { |
| char buf[EVENT_BUF_SIZE]; |
| int nread = ::wifi_wait_for_event(buf, sizeof buf); |
| if (nread > 0) { |
| return env->NewStringUTF(buf); |
| } else { |
| return NULL; |
| } |
| } |
| |
| static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) { |
| return doBooleanCommand(env, javaCommand); |
| } |
| |
| static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) { |
| return doIntCommand(env, javaCommand); |
| } |
| |
| static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) { |
| return doStringCommand(env,javaCommand); |
| } |
| |
| |
| |
| // ---------------------------------------------------------------------------- |
| |
| /* |
| * JNI registration. |
| */ |
| static JNINativeMethod gWifiMethods[] = { |
| /* name, signature, funcPtr */ |
| |
| { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver }, |
| { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded }, |
| { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver }, |
| { "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant }, |
| { "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant }, |
| { "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant }, |
| { "closeSupplicantConnectionNative", "()V", |
| (void *)android_net_wifi_closeSupplicantConnection }, |
| { "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForEvent }, |
| { "doBooleanCommandNative", "(Ljava/lang/String;)Z", (void*)android_net_wifi_doBooleanCommand }, |
| { "doIntCommandNative", "(Ljava/lang/String;)I", (void*)android_net_wifi_doIntCommand }, |
| { "doStringCommandNative", "(Ljava/lang/String;)Ljava/lang/String;", |
| (void*) android_net_wifi_doStringCommand }, |
| }; |
| |
| int register_android_net_wifi_WifiNative(JNIEnv* env) { |
| return AndroidRuntime::registerNativeMethods(env, |
| "android/net/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods)); |
| } |
| |
| }; // namespace android |