import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
+import java.lang.reflect.Method;
public class CaIpInterface {
private static Context mContext;
private static volatile boolean isIpInitialized = false;
- private static String TAG = "OIC_IP_CB_INTERFACE";
+
+ private static String WIFI_INTERFACE_PROP_KEY = "wifi.interface";
+ private static String ANDROID_SYS_PROPS_CLS = "android.os.SystemProperties";
+ private static String ANDROID_SYS_PROPS_GET_METHOD = "get";
+
+ private static String TAG = "OIC_IP_CB_INTERFACE";
private CaIpInterface(Context context) {
synchronized(CaIpInterface.class) {
private void registerIpStateReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-
mContext.registerReceiver(mReceiver, intentFilter);
}
+ private boolean hasWifiConnection() {
+ ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
+ return (activeNetwork != null && activeNetwork.getType() == ConnectivityManager.TYPE_WIFI &&
+ activeNetwork.isConnected());
+ }
+
+ private String getWiFiInterfaceName() {
+ String wifiInterfaceName= "";
+
+ try {
+ ClassLoader classLoader = mContext.getClassLoader();
+
+ Class systemPropertiesCls = classLoader.loadClass(ANDROID_SYS_PROPS_CLS);
+ Class[] paramTypes = new Class[1];
+ paramTypes[0] = String.class;
+
+ Method getMethod = systemPropertiesCls.getMethod(ANDROID_SYS_PROPS_GET_METHOD, paramTypes);
+ Object[] params = new Object[1];
+ params[0] = new String(WIFI_INTERFACE_PROP_KEY);
+
+ wifiInterfaceName = (String) getMethod.invoke(systemPropertiesCls, params);
+ } catch(Exception e) {
+ Log.d(TAG, "Error in getWiFiInterfaceName(). Details: " + e);
+ }
+
+ return wifiInterfaceName;
+ }
+
public static void destroyIpInterface() {
if (isIpInitialized) {
mContext.unregisterReceiver(mReceiver);
private static BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
- NetworkInfo activeNetwork = ((ConnectivityManager) mContext
- .getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
- if (activeNetwork != null) {
- Log.d(TAG, "CONNECTIVITY_ACTION - activeNetwork: "
- + activeNetwork.getTypeName()
- + " isConnected: " + activeNetwork.isConnected());
- caIpStateEnabled();
- } else {
- Log.d(TAG, "CONNECTIVITY_ACTION - activeNetwork: NONE");
- caIpStateDisabled();
- }
- } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
- NetworkInfo netInfo = (NetworkInfo) intent
- .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
- if (ConnectivityManager.TYPE_WIFI == netInfo.getType()) {
- NetworkInfo.State netState = netInfo.getState();
- if (NetworkInfo.State.CONNECTED == netState) {
- Log.d(TAG, "NETWORK_STATE_CHANGED_ACTION - CONNECTED: TYPE_WIFI");
- caIpStateEnabled();
- } else if (NetworkInfo.State.DISCONNECTED == netState) {
- Log.d(TAG, "NETWORK_STATE_CHANGED_ACTION - DISCONNECTED: TYPE_WIFI");
- }
- }
+ NetworkInfo activeNetwork = ((ConnectivityManager) mContext
+ .getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
+ if (activeNetwork != null) {
+ Log.d(TAG, "CONNECTIVITY_ACTION - activeNetwork: "
+ + activeNetwork.getTypeName()
+ + " isConnected: " + activeNetwork.isConnected());
+ boolean wifi = (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI);
+ caIpStateEnabled(wifi);
+ } else {
+ Log.d(TAG, "CONNECTIVITY_ACTION - activeNetwork: NONE");
+ caIpStateDisabled();
}
}
};
- private native static void caIpStateEnabled();
+ private native static void caIpStateEnabled(boolean wifi);
private native static void caIpStateDisabled();
}
*/
void CAProcessNewInterface(CAInterface_t *ifchanged);
+#ifdef __ANDROID__
+bool isWifiConnectedDuringInit();
+const char *getWifiInterfaceName();
+#endif
+
#ifdef __cplusplus
}
#endif
static struct CAIPCBData_t *g_adapterCallbackList = NULL;
/**
+ * Used to indicate whether WiFi is enabled or not during init.
+ */
+static bool g_wifiConnectionDuringInit = false;
+
+/**
+ * WiFi Interface's Name.
+ */
+static const char *g_wifiInterfaceName = NULL;
+
+/**
* Create new interface item to add in activated interface list.
* @param[in] index Network interface index number.
* @param[in] name Network interface name.
continue;
}
+ // Ignoring all non WiFi interfaces.
+ if (g_wifiInterfaceName != NULL && (strlen(g_wifiInterfaceName) > 0) &&
+ (strcmp(ifa->ifa_name, g_wifiInterfaceName) != 0))
+ {
+ OIC_LOG_V(DEBUG, TAG, "Ignoring Non-WiFi interface: %s(%d)", ifa->ifa_name, ifindex);
+ continue;
+ }
+
char ipaddr[MAX_ADDR_STR_SIZE_CA] = {0};
if (family == AF_INET6)
{
return CA_STATUS_FAILED;
}
- /* Added preventive patch for CONRO-1269
- * Network unreachable error was coming whenever WIFI-AP connection is changed.
- * To avoid that scenario we are creating sockets again when interfaces are identified.
- */
- CreateMulticastSocket();
-
return CA_STATUS_OK;
}
return CA_STATUS_FAILED;
}
- (*env)->NewObject(env, cls_CaIpInterface, mid_CaIpInterface_ctor, jApplicationContext);
- OIC_LOG(DEBUG, TAG, "Create CaIpInterface instance, success");
+ jobject jCaIpInterface = (*env)->NewObject(env, cls_CaIpInterface, mid_CaIpInterface_ctor, jApplicationContext);
+ if (!jCaIpInterface)
+ {
+ OIC_LOG(ERROR, TAG, "Could not create an instance of CaIpInterface");
+ return CA_STATUS_FAILED;
+ }
+
+ // Get WiFi Connection status.
+ jmethodID mid_hasWifiConnection = (*env)->GetMethodID(env, cls_CaIpInterface, "hasWifiConnection", "()Z");
+ if (!mid_hasWifiConnection)
+ {
+ OIC_LOG(ERROR, TAG, "Could not get hasWifiConnection method");
+ return CA_STATUS_FAILED;
+ }
+
+ g_wifiConnectionDuringInit = (*env)->CallBooleanMethod(env, jCaIpInterface, mid_hasWifiConnection);
+
+ // Get WiFi Interface's name.
+ jmethodID mid_getWiFiInterfaceName = (*env)->GetMethodID(env, cls_CaIpInterface,
+ "getWiFiInterfaceName", "()Ljava/lang/String;");
+ if (!mid_getWiFiInterfaceName)
+ {
+ OIC_LOG(ERROR, TAG, "Could not get getWiFiInterfaceName method");
+ return CA_STATUS_FAILED;
+ }
+
+ jstring jWifiInterfaceName = (*env)->CallObjectMethod(env, jCaIpInterface, mid_getWiFiInterfaceName);
+ const char *wifiInterfaceNameLocal = (*env)->GetStringUTFChars(env, jWifiInterfaceName, NULL);
+ g_wifiInterfaceName = OICStrdup(wifiInterfaceNameLocal);
+ if (!g_wifiInterfaceName)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to duplicate the Wifi Interface name.");
+ }
+
+ (*env)->ReleaseStringUTFChars(env, jWifiInterfaceName, wifiInterfaceNameLocal);
+
+ OIC_LOG_V(DEBUG, TAG, "WiFi Interface Name: %s, WiFi Connection State: %d", g_wifiInterfaceName,
+ g_wifiConnectionDuringInit);
OIC_LOG(DEBUG, TAG, "CAIPJniInit_OUT");
return CA_STATUS_OK;
OIC_LOG(DEBUG, TAG, "Destroy instance for CaIpInterface");
+ if (g_wifiInterfaceName)
+ {
+ OICFree(g_wifiInterfaceName);
+ g_wifiInterfaceName = NULL;
+ }
+
if (isAttached)
{
(*jvm)->DetachCurrentThread(jvm);
return CA_STATUS_FAILED;
}
+bool isWifiConnectedDuringInit()
+{
+ return g_wifiConnectionDuringInit;
+}
+
+const char *getWifiInterfaceName()
+{
+ return g_wifiInterfaceName;
+}
+
JNIEXPORT void JNICALL
-Java_org_iotivity_ca_CaIpInterface_caIpStateEnabled(JNIEnv *env, jclass class)
+Java_org_iotivity_ca_CaIpInterface_caIpStateEnabled(JNIEnv *env, jclass class,
+ jboolean wifi)
{
(void)env;
(void)class;
- OIC_LOG(DEBUG, TAG, "Wifi is in Activated State");
CAIPPassNetworkChangesToAdapter(CA_INTERFACE_UP);
- // Closing sockets so that it will be created again when interfaces are identified(CONPRO-1269).
+ if(!wifi)
+ {
+ return;
+ }
+
+ OIC_LOG(DEBUG, TAG, "Wifi is in Activated State");
+
+ // Closing sockets for safety reasons to handle missed out WiFi state disabled events.
CloseMulticastSocket();
+ // Creating sockets.
+ CreateMulticastSocket();
// Apply network interface changes.
u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
}
CAProcessNewInterface(ifitem);
-
}
u_arraylist_destroy(iflist);
}
(void)env;
(void)class;
- OIC_LOG(DEBUG, TAG, "Wifi is in Deactivated State");
+ OIC_LOG(DEBUG, TAG, "No network connectivity");
CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN);
+
+ CloseMulticastSocket();
}
/*
* Class: org_iotivity_ca_caIpInterface
* Method: CaIpStateEnabled
- * Signature: ()V
+ * Signature: (Z)V
*/
JNIEXPORT void JNICALL
-Java_org_iotivity_ca_CaIpInterface_caIpStateEnabled(JNIEnv *, jclass);
+Java_org_iotivity_ca_CaIpInterface_caIpStateEnabled(JNIEnv *, jclass, jboolean);
/*
* Class: org_iotivity_ca_caIpInterface
caglobals.ip.ipv4enabled = true; // only needed to run CA tests
}
+#ifdef __ANDROID__
+ bool hasWifiConnection = isWifiConnectedDuringInit();
+ if (hasWifiConnection)
+ {
+ CreateMulticastSocket();
+ }
+ else
+ {
+ OIC_LOG(INFO, TAG, "No WiFi connection. So UDP sockets are not created.");
+ }
+#else
CreateMulticastSocket();
+#endif
OIC_LOG_V(INFO, TAG,
"socket summary: u6=%d, u6s=%d, u4=%d, u4s=%d, m6=%d, m6s=%d, m4=%d, m4s=%d",
caglobals.ip.u6.port, caglobals.ip.u6s.port, caglobals.ip.u4.port,
caglobals.ip.u4s.port, caglobals.ip.m6.port, caglobals.ip.m6s.port,
caglobals.ip.m4.port, caglobals.ip.m4s.port);
+
#if defined (SIO_GET_EXTENSION_FUNCTION_POINTER)
caglobals.ip.wsaRecvMsg = NULL;
GUID GuidWSARecvMsg = WSAID_WSARECVMSG;
caglobals.ip.selectTimeout = CAGetPollingInterval(caglobals.ip.selectTimeout);
+#ifdef __ANDROID__
+ if (hasWifiConnection)
+ {
+ res = CAIPStartListenServer();
+ }
+ else
+ {
+ OIC_LOG(INFO, TAG, "No WiFi connection. So IP Listen/Multicast server is not started.");
+ }
+#else
res = CAIPStartListenServer();
+#endif
+
if (CA_STATUS_OK != res)
{
OIC_LOG_V(ERROR, TAG, "Failed to start listening server![%d]", res);