android_net_wifi_Wifi.cpp revision 1f095869536472c178046bb63c59947508eac4a6
1/* 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" 20#include <ScopedUtfChars.h> 21#include <utils/misc.h> 22#include <android_runtime/AndroidRuntime.h> 23#include <utils/Log.h> 24#include <utils/String16.h> 25 26#include "wifi.h" 27 28#define WIFI_PKG_NAME "android/net/wifi/WifiNative" 29#define BUF_SIZE 256 30 31//TODO: This file can be refactored to push a lot of the functionality to java 32//with just a few JNI calls - doBoolean/doInt/doString 33 34namespace android { 35 36static jint DBG = false; 37 38static int doCommand(const char *cmd, char *replybuf, int replybuflen) 39{ 40 size_t reply_len = replybuflen - 1; 41 42 if (::wifi_command(cmd, replybuf, &reply_len) != 0) 43 return -1; 44 else { 45 // Strip off trailing newline 46 if (reply_len > 0 && replybuf[reply_len-1] == '\n') 47 replybuf[reply_len-1] = '\0'; 48 else 49 replybuf[reply_len] = '\0'; 50 return 0; 51 } 52} 53 54static jint doIntCommand(const char* fmt, ...) 55{ 56 char buf[BUF_SIZE]; 57 va_list args; 58 va_start(args, fmt); 59 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args); 60 va_end(args); 61 if (byteCount < 0 || byteCount >= BUF_SIZE) { 62 return -1; 63 } 64 char reply[BUF_SIZE]; 65 if (doCommand(buf, reply, sizeof(reply)) != 0) { 66 return -1; 67 } 68 return static_cast<jint>(atoi(reply)); 69} 70 71static jboolean doBooleanCommand(const char* expect, const char* fmt, ...) 72{ 73 char buf[BUF_SIZE]; 74 va_list args; 75 va_start(args, fmt); 76 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args); 77 va_end(args); 78 if (byteCount < 0 || byteCount >= BUF_SIZE) { 79 return JNI_FALSE; 80 } 81 char reply[BUF_SIZE]; 82 if (doCommand(buf, reply, sizeof(reply)) != 0) { 83 return JNI_FALSE; 84 } 85 return (strcmp(reply, expect) == 0); 86} 87 88// Send a command to the supplicant, and return the reply as a String 89static jstring doStringCommand(JNIEnv* env, const char* fmt, ...) { 90 char buf[BUF_SIZE]; 91 va_list args; 92 va_start(args, fmt); 93 int byteCount = vsnprintf(buf, sizeof(buf), fmt, args); 94 va_end(args); 95 if (byteCount < 0 || byteCount >= BUF_SIZE) { 96 return NULL; 97 } 98 char reply[4096]; 99 if (doCommand(buf, reply, sizeof(reply)) != 0) { 100 return NULL; 101 } 102 // TODO: why not just NewStringUTF? 103 String16 str((char *)reply); 104 return env->NewString((const jchar *)str.string(), str.size()); 105} 106 107static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject) 108{ 109 return (jboolean)(::is_wifi_driver_loaded() == 1); 110} 111 112static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject) 113{ 114 return (jboolean)(::wifi_load_driver() == 0); 115} 116 117static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject) 118{ 119 return (jboolean)(::wifi_unload_driver() == 0); 120} 121 122static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject) 123{ 124 return (jboolean)(::wifi_start_supplicant() == 0); 125} 126 127static jboolean android_net_wifi_startP2pSupplicant(JNIEnv* env, jobject) 128{ 129 return (jboolean)(::wifi_start_p2p_supplicant() == 0); 130} 131 132static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject) 133{ 134 return (jboolean)(::wifi_stop_supplicant() == 0); 135} 136 137static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject) 138{ 139 return (jboolean)(::wifi_connect_to_supplicant() == 0); 140} 141 142static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject) 143{ 144 ::wifi_close_supplicant_connection(); 145} 146 147static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject) 148{ 149 char buf[BUF_SIZE]; 150 151 int nread = ::wifi_wait_for_event(buf, sizeof buf); 152 if (nread > 0) { 153 return env->NewStringUTF(buf); 154 } else { 155 return NULL; 156 } 157} 158 159static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) 160{ 161 ScopedUtfChars command(env, javaCommand); 162 if (command.c_str() == NULL) { 163 return JNI_FALSE; 164 } 165 if (DBG) LOGD("doBoolean: %s", command.c_str()); 166 return doBooleanCommand("OK", "%s", command.c_str()); 167} 168 169static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) 170{ 171 ScopedUtfChars command(env, javaCommand); 172 if (command.c_str() == NULL) { 173 return -1; 174 } 175 if (DBG) LOGD("doInt: %s", command.c_str()); 176 return doIntCommand("%s", command.c_str()); 177} 178 179static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) 180{ 181 ScopedUtfChars command(env, javaCommand); 182 if (command.c_str() == NULL) { 183 return NULL; 184 } 185 if (DBG) LOGD("doString: %s", command.c_str()); 186 return doStringCommand(env, "%s", command.c_str()); 187} 188 189 190 191// ---------------------------------------------------------------------------- 192 193/* 194 * JNI registration. 195 */ 196static JNINativeMethod gWifiMethods[] = { 197 /* name, signature, funcPtr */ 198 199 { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver }, 200 { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded}, 201 { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver }, 202 { "startSupplicant", "()Z", (void *)android_net_wifi_startSupplicant }, 203 { "startP2pSupplicant", "()Z", (void *)android_net_wifi_startP2pSupplicant }, 204 { "killSupplicant", "()Z", (void *)android_net_wifi_killSupplicant }, 205 { "connectToSupplicant", "()Z", (void *)android_net_wifi_connectToSupplicant }, 206 { "closeSupplicantConnection", "()V", (void *)android_net_wifi_closeSupplicantConnection }, 207 { "waitForEvent", "()Ljava/lang/String;", (void*) android_net_wifi_waitForEvent }, 208 { "doBooleanCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_doBooleanCommand}, 209 { "doIntCommand", "(Ljava/lang/String;)I", (void*) android_net_wifi_doIntCommand}, 210 { "doStringCommand", "(Ljava/lang/String;)Ljava/lang/String;", (void*) android_net_wifi_doStringCommand}, 211}; 212 213int register_android_net_wifi_WifiManager(JNIEnv* env) 214{ 215 return AndroidRuntime::registerNativeMethods(env, 216 WIFI_PKG_NAME, gWifiMethods, NELEM(gWifiMethods)); 217} 218 219}; // namespace android 220