Add multi-interface support to native calls

Add the initial support for supporting seperate socket
connections on the p2p interface.

This is the initial change making primary interface connections
work alongside native support for p2p socket connection

Change-Id: I7619715ca75b10afd29af852279fe713331f75e0
This commit is contained in:
Irfan Sheriff
2011-12-28 13:00:28 -08:00
parent 1f09586953
commit 44b330dfb0
3 changed files with 88 additions and 40 deletions

View File

@@ -28,18 +28,15 @@
#define WIFI_PKG_NAME "android/net/wifi/WifiNative"
#define BUF_SIZE 256
//TODO: This file can be refactored to push a lot of the functionality to java
//with just a few JNI calls - doBoolean/doInt/doString
namespace android {
static jint DBG = false;
static int doCommand(const char *cmd, char *replybuf, int replybuflen)
static int doCommand(const char *ifname, const char *cmd, char *replybuf, int replybuflen)
{
size_t reply_len = replybuflen - 1;
if (::wifi_command(cmd, replybuf, &reply_len) != 0)
if (::wifi_command(ifname, cmd, replybuf, &reply_len) != 0)
return -1;
else {
// Strip off trailing newline
@@ -51,7 +48,7 @@ static int doCommand(const char *cmd, char *replybuf, int replybuflen)
}
}
static jint doIntCommand(const char* fmt, ...)
static jint doIntCommand(const char *ifname, const char* fmt, ...)
{
char buf[BUF_SIZE];
va_list args;
@@ -62,13 +59,13 @@ static jint doIntCommand(const char* fmt, ...)
return -1;
}
char reply[BUF_SIZE];
if (doCommand(buf, reply, sizeof(reply)) != 0) {
if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
return -1;
}
return static_cast<jint>(atoi(reply));
}
static jboolean doBooleanCommand(const char* expect, const char* fmt, ...)
static jboolean doBooleanCommand(const char *ifname, const char* expect, const char* fmt, ...)
{
char buf[BUF_SIZE];
va_list args;
@@ -79,14 +76,14 @@ static jboolean doBooleanCommand(const char* expect, const char* fmt, ...)
return JNI_FALSE;
}
char reply[BUF_SIZE];
if (doCommand(buf, reply, sizeof(reply)) != 0) {
if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
return JNI_FALSE;
}
return (strcmp(reply, expect) == 0);
}
// Send a command to the supplicant, and return the reply as a String
static jstring doStringCommand(JNIEnv* env, const char* fmt, ...) {
static jstring doStringCommand(JNIEnv* env, const char *ifname, const char* fmt, ...) {
char buf[BUF_SIZE];
va_list args;
va_start(args, fmt);
@@ -96,7 +93,7 @@ static jstring doStringCommand(JNIEnv* env, const char* fmt, ...) {
return NULL;
}
char reply[4096];
if (doCommand(buf, reply, sizeof(reply)) != 0) {
if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
return NULL;
}
// TODO: why not just NewStringUTF?
@@ -134,21 +131,23 @@ static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject)
return (jboolean)(::wifi_stop_supplicant() == 0);
}
static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject)
static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject, jstring jIface)
{
return (jboolean)(::wifi_connect_to_supplicant() == 0);
ScopedUtfChars ifname(env, jIface);
return (jboolean)(::wifi_connect_to_supplicant(ifname.c_str()) == 0);
}
static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject)
static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject, jstring jIface)
{
::wifi_close_supplicant_connection();
ScopedUtfChars ifname(env, jIface);
::wifi_close_supplicant_connection(ifname.c_str());
}
static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject)
static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject, jstring jIface)
{
char buf[BUF_SIZE];
int nread = ::wifi_wait_for_event(buf, sizeof buf);
ScopedUtfChars ifname(env, jIface);
int nread = ::wifi_wait_for_event(ifname.c_str(), buf, sizeof buf);
if (nread > 0) {
return env->NewStringUTF(buf);
} else {
@@ -156,34 +155,43 @@ static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject)
}
}
static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand)
static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring jIface,
jstring jCommand)
{
ScopedUtfChars command(env, javaCommand);
ScopedUtfChars ifname(env, jIface);
ScopedUtfChars command(env, jCommand);
if (command.c_str() == NULL) {
return JNI_FALSE;
}
if (DBG) LOGD("doBoolean: %s", command.c_str());
return doBooleanCommand("OK", "%s", command.c_str());
return doBooleanCommand(ifname.c_str(), "OK", "%s", command.c_str());
}
static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand)
static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring jIface,
jstring jCommand)
{
ScopedUtfChars command(env, javaCommand);
ScopedUtfChars ifname(env, jIface);
ScopedUtfChars command(env, jCommand);
if (command.c_str() == NULL) {
return -1;
}
if (DBG) LOGD("doInt: %s", command.c_str());
return doIntCommand("%s", command.c_str());
return doIntCommand(ifname.c_str(), "%s", command.c_str());
}
static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand)
static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring jIface,
jstring jCommand)
{
ScopedUtfChars command(env, javaCommand);
ScopedUtfChars ifname(env, jIface);
ScopedUtfChars command(env, jCommand);
if (command.c_str() == NULL) {
return NULL;
}
if (DBG) LOGD("doString: %s", command.c_str());
return doStringCommand(env, "%s", command.c_str());
return doStringCommand(env, ifname.c_str(), "%s", command.c_str());
}
@@ -197,17 +205,23 @@ static JNINativeMethod gWifiMethods[] = {
/* name, signature, funcPtr */
{ "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
{ "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded},
{ "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded },
{ "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
{ "startSupplicant", "()Z", (void *)android_net_wifi_startSupplicant },
{ "startP2pSupplicant", "()Z", (void *)android_net_wifi_startP2pSupplicant },
{ "killSupplicant", "()Z", (void *)android_net_wifi_killSupplicant },
{ "connectToSupplicant", "()Z", (void *)android_net_wifi_connectToSupplicant },
{ "closeSupplicantConnection", "()V", (void *)android_net_wifi_closeSupplicantConnection },
{ "waitForEvent", "()Ljava/lang/String;", (void*) android_net_wifi_waitForEvent },
{ "doBooleanCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_doBooleanCommand},
{ "doIntCommand", "(Ljava/lang/String;)I", (void*) android_net_wifi_doIntCommand},
{ "doStringCommand", "(Ljava/lang/String;)Ljava/lang/String;", (void*) android_net_wifi_doStringCommand},
{ "connectToSupplicant", "(Ljava/lang/String;)Z",
(void *)android_net_wifi_connectToSupplicant },
{ "closeSupplicantConnection", "(Ljava/lang/String;)V",
(void *)android_net_wifi_closeSupplicantConnection },
{ "waitForEvent", "(Ljava/lang/String;)Ljava/lang/String;",
(void*) android_net_wifi_waitForEvent },
{ "doBooleanCommand", "(Ljava/lang/String;Ljava/lang/String;)Z",
(void*) android_net_wifi_doBooleanCommand },
{ "doIntCommand", "(Ljava/lang/String;Ljava/lang/String;)I",
(void*) android_net_wifi_doIntCommand },
{ "doStringCommand", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
(void*) android_net_wifi_doStringCommand },
};
int register_android_net_wifi_WifiManager(JNIEnv* env)

View File

@@ -19,6 +19,7 @@ package android.net.wifi;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pDevice;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;
@@ -42,6 +43,8 @@ public class WifiNative {
static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
static final int BLUETOOTH_COEXISTENCE_MODE_SENSE = 2;
static String sDefaultInterface;
public native static boolean loadDriver();
public native static boolean isDriverLoaded();
@@ -56,21 +59,49 @@ public class WifiNative {
or when the supplicant is hung */
public native static boolean killSupplicant();
public native static boolean connectToSupplicant();
public native static boolean connectToSupplicant(String iface);
public native static void closeSupplicantConnection();
public native static void closeSupplicantConnection(String iface);
/**
* Wait for the supplicant to send an event, returning the event string.
* @return the event string sent by the supplicant.
*/
public native static String waitForEvent();
public native static String waitForEvent(String iface);
private native static boolean doBooleanCommand(String command);
private native static boolean doBooleanCommand(String iface, String command);
private native static int doIntCommand(String command);
private native static int doIntCommand(String iface, String command);
private native static String doStringCommand(String command);
private native static String doStringCommand(String iface, String command);
public static void setDefaultInterface(String iface) {
sDefaultInterface = iface;
}
public static boolean connectToSupplicant() {
return connectToSupplicant(sDefaultInterface);
}
public static void closeSupplicantConnection() {
closeSupplicantConnection(sDefaultInterface);
}
public static String waitForEvent() {
return waitForEvent(sDefaultInterface);
}
private static boolean doBooleanCommand(String command) {
return doBooleanCommand(sDefaultInterface, command);
}
private static int doIntCommand(String command) {
return doIntCommand(sDefaultInterface, command);
}
private static String doStringCommand(String command) {
return doStringCommand(sDefaultInterface, command);
}
public static boolean ping() {
String pong = doStringCommand("PING");

View File

@@ -572,6 +572,9 @@ public class WifiStateMachine extends StateMachine {
mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
mLastSignalLevel = -1;
/* Set default interface for all primary socket communication */
WifiNative.setDefaultInterface(mInterfaceName);
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
Intent scanIntent = new Intent(ACTION_START_SCAN, null);
mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);