Fix issuse related unregisterReceiver
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / ip_adapter / android / caipnwmonitor.c
index ef3a5f7..2685880 100644 (file)
 /******************************************************************
- *
- * Copyright 2014 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * 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.
- *
- ******************************************************************/
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* 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.
+*
+******************************************************************/
 
 #include "caipinterface.h"
 
-#include <string.h>
-#include <sys/ioctl.h>
-#include <arpa/inet.h>
-#include <linux/if.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 #include <netdb.h>
+#include <string.h>
 #include <errno.h>
 #include <unistd.h>
 
+#include <arpa/inet.h>
+#include <linux/if.h>
+
 #include "caadapterutils.h"
-#include "camutex.h"
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 #include "org_iotivity_ca_CaIpInterface.h"
 
-#define IP_MONITOR_TAG "IP_MONITOR"
-#define MAX_INTERFACE_INFO_LENGTH (1024)
-
-/**
- * @var g_stopNetworkMonitor
- * @brief  Used to stop the network monitor thread.
- */
-static bool g_stopNetworkMonitor = false;
-
-/**
- * @var g_stopNetworkMonitorMutex
- * @brief  Mutex for synchronizing access to g_stopNetworkMonitor flag.
- */
-static ca_mutex g_stopNetworkMonitorMutex = NULL;
-
-/**
- * @struct CAIPNwMonitorContext
- * @brief  Used for storing network monitor context information.
- */
-typedef struct
-{
-    u_arraylist_t *netInterfaceList;
-    ca_thread_pool_t threadPool;
-    CANetworkStatus_t nwConnectivityStatus;
-    CAIPConnectionStateChangeCallback networkChangeCb;
-} CAIPNetworkMonitorContext;
-
-/**
- * @var g_networkMonitorContext
- * @brief  network monitor context.
- */
-static CAIPNetworkMonitorContext *g_networkMonitorContext = NULL;
+#define TAG "OIC_CA_IP_MONITOR"
 
-/**
- * @var g_networkMonitorContextMutex
- * @brief  Mutex for synchronizing access to cached interface and IP address information.
- */
-static ca_mutex g_networkMonitorContextMutex = NULL;
+static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
+                                         uint32_t addr, int flags);
 
-/**
- * @var g_jvm
- * @brief pointer to store JavaVM
- */
-static JavaVM *g_jvm = NULL;
+static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
+                            const char *name, int family, uint32_t addr, int flags);
 
-/**
- * @var g_context
- * @brief pointer to store Application Context
- */
-static jobject g_context = NULL;
+CAResult_t CAIPJniInit();
 
 /**
- * @fn CAIPUpdateInterfaceInformation
- * @brief This methods gets local interface name and IP address information.
+ * destroy JNI interface.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
-static CAResult_t CAIPUpdateInterfaceInformation(u_arraylist_t **netInterfaceList);
-/**
- * @fn CACreateIPJNIInterfaceObject
- * @brief creates new instance of CaIpInterface through JNI
- */
-static CAResult_t CACreateIPJNIInterfaceObject(jobject context);
+static CAResult_t CAIPDestroyJniInterface();
 
-/**
- * @fn CAIPSendNetworkChangeCallback
- * @brief updates network status to IP adapter
- */
-static void CAIPSendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus);
+#define MAX_INTERFACE_INFO_LENGTH 1024 // allows 32 interfaces from SIOCGIFCONF
 
-CAResult_t CAIPJniInit()
+CAResult_t CAIPStartNetworkMonitor()
 {
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPJniInit");
-    g_jvm = CANativeJNIGetJavaVM();
-
-    if (!g_jvm)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "JNI initialize error");
-        return CA_STATUS_FAILED;
-    }
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
+    return CAIPJniInit();
 }
 
-CAResult_t CAIPJniSetContext()
+CAResult_t CAIPStopNetworkMonitor()
 {
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPJniSetContext");
-    g_context = (jobject) CANativeJNIGetContext();
-
-    if (!g_context)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "unable to get application context");
-        return CA_STATUS_FAILED;
-    }
-
-    return CA_STATUS_OK;
+    return CAIPDestroyJniInterface();
 }
 
-CAResult_t CACreateIPJNIInterfaceObject(jobject context)
+int CAGetPollingInterval(int interval)
 {
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "CACreateIPJNIInterfaceObject");
-
-    VERIFY_NON_NULL(context, IP_MONITOR_TAG, "context");
-
-    JNIEnv* env;
-
-    if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get JNIEnv pointer");
-        return CA_STATUS_FAILED;
-    }
-
-    //getApplicationContext
-    jclass contextClass = (*env)->FindClass(env, "android/content/Context");
-    if (!contextClass)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get context object class");
-        return CA_STATUS_FAILED;
-    }
-
-    jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
-                                                                "getApplicationContext",
-                                                                "()Landroid/content/Context;");
-    if (!getApplicationContextMethod)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get getApplicationContext method");
-        return CA_STATUS_FAILED;
-    }
-
-    jobject gApplicationContext = (*env)->CallObjectMethod(env, context,
-                                                           getApplicationContextMethod);
-    if (!getApplicationContextMethod)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get getApplicationContext");
-        return CA_STATUS_FAILED;
-    }
-
-    //Create CaIpInterface jni instance
-    jclass IPJniInterface = (*env)->FindClass(env, "org/iotivity/ca/CaIpInterface");
-    if (!IPJniInterface)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get CaIpInterface class");
-        return CA_STATUS_FAILED;
-    }
-
-    jmethodID IPInterfaceConstructorMethod = (*env)->GetMethodID(env, IPJniInterface, "<init>",
-                                                                   "(Landroid/content/Context;)V");
-    if (!IPInterfaceConstructorMethod)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get CaIpInterface constructor method");
-        return CA_STATUS_FAILED;
-    }
-
-    (*env)->NewObject(env, IPJniInterface, IPInterfaceConstructorMethod, gApplicationContext);
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "Create CaIpInterface instance, success");
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
+    return interval;
 }
 
-static CAResult_t CAIPUpdateInterfaceInformation(u_arraylist_t **netInterfaceList)
+CAInterface_t *CAFindInterfaceChange()
 {
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null");
-
-    /* Get a socket handle. */
-    int sck = -1;
-#ifdef SOCK_CLOEXEC
-    sck = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
-#endif
+    char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
+    struct ifconf ifc  = { .ifc_len = MAX_INTERFACE_INFO_LENGTH, .ifc_buf = buf };
 
-    if ( -1 == sck)
+    int s = caglobals.ip.u6.fd != -1 ? caglobals.ip.u6.fd : caglobals.ip.u4.fd;
+    if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
     {
-        sck=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+        OIC_LOG_V(ERROR, TAG, "SIOCGIFCONF failed: %s", strerror(errno));
+        return NULL;
     }
 
-    if (sck < 0)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Error in socket creation");
-        return CA_STATUS_FAILED;
-    }
+    CAInterface_t *foundNewInterface = NULL;
 
-    char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
-    struct ifconf ifc;
-
-    /* Query available interfaces. */
-    ifc.ifc_len = MAX_INTERFACE_INFO_LENGTH;
-    ifc.ifc_buf = buf;
+    struct ifreq* ifr = ifc.ifc_req;
+    size_t interfaces = ifc.ifc_len / sizeof (ifc.ifc_req[0]);
+    size_t ifreqsize = ifc.ifc_len;
 
-    if (ioctl(sck, SIOCGIFCONF, &ifc) < 0)
+    CAIfItem_t *previous = (CAIfItem_t *)OICMalloc(ifreqsize);
+    if (!previous)
     {
-        close(sck);
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Failed to get interface info");
-        return CA_STATUS_FAILED;
+        OIC_LOG(ERROR, TAG, "OICMalloc failed");
+        return NULL;
     }
 
-    /* Iterate through the list of interfaces. */
-    struct ifreq* ifr = ifc.ifc_req;
-    int32_t interfaces = ifc.ifc_len / sizeof(struct ifreq);
-
-    OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPUpdateInterfaceInformation : %d", interfaces);
+    memcpy(previous, caglobals.ip.nm.ifItems, ifreqsize);
+    size_t numprevious = caglobals.ip.nm.numIfItems;
 
-    if(0 == interfaces)
+    if (ifreqsize > caglobals.ip.nm.sizeIfItems)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "no interfaces");
-        return CA_STATUS_FAILED;
+
+        CAIfItem_t *items = (CAIfItem_t *)OICRealloc(caglobals.ip.nm.ifItems, ifreqsize);
+        if (!items)
+        {
+            OIC_LOG(ERROR, TAG, "OICRealloc failed");
+            OICFree(previous);
+            return NULL;
+        }
+        caglobals.ip.nm.ifItems = items;
+        caglobals.ip.nm.sizeIfItems = ifreqsize;
     }
 
-    for (int32_t i = 0; i < interfaces; i++)
+    caglobals.ip.nm.numIfItems = 0;
+    for (size_t i = 0; i < interfaces; i++)
     {
-        struct ifreq temp_ifr = { 0 };
         struct ifreq* item = &ifr[i];
+        char *name = item->ifr_name;
+        struct sockaddr_in *sa4 = (struct sockaddr_in *)&item->ifr_addr;
+        uint32_t ipv4addr = sa4->sin_addr.s_addr;
 
-        char interfaceAddress[CA_IPADDR_SIZE] = { 0 };
-        char interfaceSubnetMask[CA_IPADDR_SIZE] = { 0 };
-        socklen_t len = sizeof(struct sockaddr_in);
-
-        OICStrcpy(temp_ifr.ifr_name, sizeof(temp_ifr.ifr_name), item->ifr_name);
-
-        if (ioctl(sck, SIOCGIFFLAGS, &temp_ifr))
+        if (ioctl(s, SIOCGIFFLAGS, item) < 0)
         {
-            OIC_LOG(ERROR, IP_MONITOR_TAG,
-                    "CAIPUpdateInterfaceInformation, SIOCGIFFLAGS Failed");
-            close(sck);
-            return CA_STATUS_FAILED;
+            OIC_LOG_V(ERROR, TAG, "SIOCGIFFLAGS failed: %s", strerror(errno));
+            continue;
         }
-
-        if ((temp_ifr.ifr_flags & IFF_LOOPBACK)
-            || !(temp_ifr.ifr_flags & IFF_UP) || !(temp_ifr.ifr_flags & IFF_RUNNING))
+        int16_t flags = item->ifr_flags;
+        if ((flags & IFF_LOOPBACK) || !(flags & IFF_RUNNING))
         {
-            OIC_LOG_V(ERROR, IP_MONITOR_TAG,
-                      "interface is not up or not running or loopback = %x", temp_ifr.ifr_flags);
             continue;
         }
-
-        if (AF_INET != ((struct sockaddr_in*) &item->ifr_addr)->sin_family)
+        if (ioctl(s, SIOCGIFINDEX, item) < 0)
         {
+            OIC_LOG_V(ERROR, TAG, "SIOCGIFINDEX failed: %s", strerror(errno));
             continue;
         }
 
-        //get the interface ip address
-        if (0 != getnameinfo(&item->ifr_addr, len, interfaceAddress, sizeof(interfaceAddress),
-                             NULL, 0, NI_NUMERICHOST))
-        {
-            OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get IPAddress, Error code: %s",
-                    strerror(errno));
-            close(sck);
-            return CA_STATUS_FAILED;
-        }
+        int ifIndex = item->ifr_ifindex;
+        caglobals.ip.nm.ifItems[i].ifIndex = ifIndex;  // refill interface list
+        caglobals.ip.nm.numIfItems++;
 
-        if (ioctl((int) sck, SIOCGIFNETMASK, item) < 0)
+        if (foundNewInterface)
         {
-            OIC_LOG(ERROR, IP_MONITOR_TAG,
-                    "CAIPUpdateInterfaceInformation, SIOCGIFNETMASK Failed");
-            close(sck);
-            return CA_STATUS_FAILED;
+            continue;   // continue updating interface list
         }
 
-        // get the interface subnet mask
-        if (0 != getnameinfo(&item->ifr_netmask, len, interfaceSubnetMask,
-                             sizeof(interfaceSubnetMask), NULL, 0, NI_NUMERICHOST))
+        // see if this interface didn't previously exist
+        bool found = false;
+        for (size_t j = 0; j < numprevious; j++)
         {
-            OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get subnet mask, Error code: %s",
-                    strerror(errno));
-            close(sck);
-            return CA_STATUS_FAILED;
+            if (ifIndex == previous[j].ifIndex)
+            {
+                found = true;
+                break;
+            }
         }
-
-        CANetInfo_t *netInfo = (CANetInfo_t *) OICCalloc(1, sizeof(CANetInfo_t));
-        if (!netInfo)
+        if (found)
         {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed");
-            close(sck);
-            return CA_MEMORY_ALLOC_FAILED;
+            OIC_LOG_V(INFO, TAG, "Interface found: %s", name);
+            continue;
         }
 
-        // set interface name
-        OICStrcpy(netInfo->interfaceName, sizeof(netInfo->interfaceName), item->ifr_name);
+        foundNewInterface = CANewInterfaceItem(ifIndex, name, AF_INET, ipv4addr, flags);
+    }
 
-        // set local ip address
-        OICStrcpy(netInfo->ipAddress, sizeof(netInfo->ipAddress), interfaceAddress);
+    OICFree(previous);
+    return foundNewInterface;
+}
 
-        // set subnet mask
-        OICStrcpy(netInfo->subnetMask, sizeof(netInfo->subnetMask), interfaceSubnetMask);
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
+{
+    u_arraylist_t *iflist = u_arraylist_create();
+    if (!iflist)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
+        return NULL;
+    }
 
-        CAResult_t result = u_arraylist_add(*netInterfaceList, (void *) netInfo);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!Thread exiting.");
-            close(sck);
-            return CA_STATUS_FAILED;
-        }
+    char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
+    struct ifconf ifc = { .ifc_len = MAX_INTERFACE_INFO_LENGTH, .ifc_buf = buf };
 
-        OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "ipAddress : %s, interfaceName : %s, subnetmask : %s",
-                netInfo->ipAddress, netInfo->interfaceName, netInfo->subnetMask);
+    int s = caglobals.ip.u6.fd != -1 ? caglobals.ip.u6.fd : caglobals.ip.u4.fd;
+    if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
+    {
+        OIC_LOG_V(ERROR, TAG, "SIOCGIFCONF failed: %s", strerror(errno));
+        u_arraylist_destroy(iflist);
+        return NULL;
     }
 
-    close(sck);
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
+    struct ifreq* ifr = ifc.ifc_req;
+    size_t interfaces = ifc.ifc_len / sizeof (ifc.ifc_req[0]);
+    size_t ifreqsize = ifc.ifc_len;
 
-static bool CACheckIsAnyInterfaceDown(const u_arraylist_t *netInterfaceList,
-                                      const CANetInfo_t *info)
-{
-    VERIFY_NON_NULL_RET(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null", false);
-    VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
+    if (ifreqsize > caglobals.ip.nm.sizeIfItems)
+    {
+        CAIfItem_t *items = (CAIfItem_t *)OICRealloc(caglobals.ip.nm.ifItems, ifreqsize);
+        if (!items)
+        {
+            OIC_LOG(ERROR, TAG, "OICRealloc failed");
+            goto exit;
+        }
+        caglobals.ip.nm.ifItems = items;
+        caglobals.ip.nm.sizeIfItems = ifreqsize;
+    }
 
-    uint32_t list_length = u_arraylist_length(netInterfaceList);
-    for (uint32_t list_index = 0; list_index < list_length; list_index++)
+    caglobals.ip.nm.numIfItems = 0;
+    for (size_t i = 0; i < interfaces; i++)
     {
-        CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, list_index);
-        if (!netInfo)
+        CAResult_t result = CA_STATUS_OK;
+        struct ifreq* item = &ifr[i];
+        char *name = item->ifr_name;
+        struct sockaddr_in *sa4 = (struct sockaddr_in *)&item->ifr_addr;
+        uint32_t ipv4addr = sa4->sin_addr.s_addr;
+
+        if (ioctl(s, SIOCGIFFLAGS, item) < 0)
         {
+            OIC_LOG_V(ERROR, TAG, "SIOCGIFFLAGS failed: %s", strerror(errno));
             continue;
         }
-        if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
+        int16_t flags = item->ifr_flags;
+        if ((flags & IFF_LOOPBACK) || !(flags & IFF_RUNNING))
         {
-            return false;
+            continue;
+        }
+        if (ioctl(s, SIOCGIFINDEX, item) < 0)
+        {
+            OIC_LOG_V(ERROR, TAG, "SIOCGIFINDEX failed: %s", strerror(errno));
+            continue;
         }
-    }
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "Interface is down");
-    return true;
-}
-
-static bool CACheckIsInterfaceInfoChanged(const CANetInfo_t *info)
-{
-    VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
 
-    ca_mutex_lock(g_networkMonitorContextMutex);
+        int ifindex = item->ifr_ifindex;
+        caglobals.ip.nm.ifItems[i].ifIndex = ifindex;
+        caglobals.ip.nm.numIfItems++;
 
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    for (uint32_t list_index = 0; list_index < list_length; list_index++)
-    {
-        CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(
-                               g_networkMonitorContext->netInterfaceList, list_index);
-        if (!netInfo)
+        if (desiredIndex && (ifindex != desiredIndex))
         {
             continue;
         }
-        if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
+
+        // Add IPv4 interface
+        result = CAAddInterfaceItem(iflist, ifindex, name, AF_INET, ipv4addr, flags);
+        if (CA_STATUS_OK != result)
         {
-            if (strncmp(netInfo->ipAddress, info->ipAddress, strlen(info->ipAddress)) == 0)
-            {
-                ca_mutex_unlock(g_networkMonitorContextMutex);
-                return false;
-            }
-            else
-            {
-                OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network interface info changed");
-                if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, list_index))
-                {
-                    if (g_networkMonitorContext->networkChangeCb)
-                    {
-                        g_networkMonitorContext->networkChangeCb(netInfo->ipAddress,
-                                                                 CA_INTERFACE_DOWN);
-                    }
-                    OICFree(netInfo);
-                }
-                else
-                {
-                    OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
-                }
-                break;
-            }
+            goto exit;
         }
-    }
 
-    CANetInfo_t *newNetInfo = (CANetInfo_t *) OICMalloc(sizeof(CANetInfo_t));
-    if (!newNetInfo)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "newNetInfo malloc failed");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
+        // Add IPv6 interface
+        result = CAAddInterfaceItem(iflist, ifindex, name, AF_INET6, ipv4addr, flags);
+        if (CA_STATUS_OK != result)
+        {
+            goto exit;
+        }
     }
-    *newNetInfo = *info;
+    return iflist;
 
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "New Interface found");
+exit:
+    u_arraylist_destroy(iflist);
+    return NULL;
+}
 
-    CAResult_t result = u_arraylist_add(g_networkMonitorContext->netInterfaceList,
-                                        (void *) newNetInfo);
-    if (CA_STATUS_OK != result)
+static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
+                            const char *name, int family, uint32_t addr, int flags)
+{
+    CAInterface_t *ifitem = CANewInterfaceItem(index, name, family, addr, flags);
+    if (!ifitem)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
-        OICFree(newNetInfo);
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
+        return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    /*Callback will be unset only at the time of termination. By that time, all the threads will be
-      stopped gracefully. This callback is properly protected*/
-    if (g_networkMonitorContext->networkChangeCb)
+    bool result = u_arraylist_add(iflist, ifitem);
+    if (!result)
     {
-        g_networkMonitorContext->networkChangeCb(newNetInfo->ipAddress, CA_INTERFACE_UP);
+        OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+        OICFree(ifitem);
+        return CA_STATUS_FAILED;
     }
 
-    return true;
+    return CA_STATUS_OK;
 }
 
-static CAResult_t CAInitializeNetworkMonitorMutexes()
+static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
+                                         uint32_t addr, int flags)
 {
-    if (!g_networkMonitorContextMutex)
+    CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof (CAInterface_t));
+    if (!ifitem)
     {
-        g_networkMonitorContextMutex = ca_mutex_new();
-        if (!g_networkMonitorContextMutex)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContextMutex Malloc  failed");
-            return CA_MEMORY_ALLOC_FAILED;
-        }
+        OIC_LOG(ERROR, TAG, "Malloc failed");
+        return NULL;
     }
 
-    if (!g_stopNetworkMonitorMutex)
-    {
-        g_stopNetworkMonitorMutex = ca_mutex_new();
-        if (!g_stopNetworkMonitorMutex)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "g_stopNetworkMonitorMutex Malloc  failed");
-            ca_mutex_free(g_networkMonitorContextMutex);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-    }
-    return CA_STATUS_OK;
-}
-
-static void CADestroyNetworkMonitorMutexes()
-{
-    ca_mutex_free(g_networkMonitorContextMutex);
-    g_networkMonitorContextMutex = NULL;
+    OICStrcpy(ifitem->name, sizeof (ifitem->name), name);
+    ifitem->index = index;
+    ifitem->family = family;
+    ifitem->ipv4addr = addr;
+    ifitem->flags = flags;
 
-    ca_mutex_free(g_stopNetworkMonitorMutex);
-    g_stopNetworkMonitorMutex = NULL;
+    return ifitem;
 }
 
-CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
+CAResult_t CAIPJniInit()
 {
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPInitializeNetworkMonitor IN");
+    OIC_LOG(DEBUG, TAG, "CAIPJniInit_IN");
 
-    VERIFY_NON_NULL(threadPool, IP_MONITOR_TAG, "threadPool is null");
-
-    CAResult_t ret = CAIPJniInit();
-    if (CA_STATUS_OK != ret)
+    JavaVM *jvm = CANativeJNIGetJavaVM();
+    if (!jvm)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Initialization failed");
-        return ret;
+        OIC_LOG(ERROR, TAG, "Could not get JavaVM pointer");
+        return CA_STATUS_FAILED;
     }
 
-    ret = CAIPJniSetContext();
-    if (CA_STATUS_OK != ret)
+    jobject context = CANativeJNIGetContext();
+    if (!context)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPJniSetContext failed");
-        return ret;
+        OIC_LOG(ERROR, TAG, "unable to get application context");
+        return CA_STATUS_FAILED;
     }
 
-    ret = CACreateIPJNIInterfaceObject(g_context);
-    if (CA_STATUS_OK != ret)
+    JNIEnv* env;
+    if ((*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "unable to create CaIpInterface instance");
-        return ret;
+        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
+        return CA_STATUS_FAILED;
     }
 
-    ret = CAInitializeNetworkMonitorMutexes();
+    jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
+                                                           "getApplicationContext",
+                                                           "()Landroid/content/Context;");
 
-    if (CA_STATUS_OK != ret)
+    if (!mid_getApplicationContext)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "CAInitializeNetworkMonitorMutexes failed");
+        OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-    g_networkMonitorContext = (CAIPNetworkMonitorContext *) OICCalloc(
-            1, sizeof(*g_networkMonitorContext));
-    if (!g_networkMonitorContext)
+    jobject jApplicationContext = (*env)->CallObjectMethod(env, context,
+                                                           mid_getApplicationContext);
+    if (!jApplicationContext)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext Malloc  failed");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        CADestroyNetworkMonitorMutexes();
-        return CA_MEMORY_ALLOC_FAILED;
+        OIC_LOG(ERROR, TAG, "Could not get application context");
+        return CA_STATUS_FAILED;
     }
-    g_networkMonitorContext->threadPool = threadPool;
 
-    g_networkMonitorContext->netInterfaceList = u_arraylist_create();
-    if (!g_networkMonitorContext->netInterfaceList)
+    jclass cls_CaIpInterface = (*env)->FindClass(env, "org/iotivity/ca/CaIpInterface");
+    if (!cls_CaIpInterface)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_create failed");
-        OICFree(g_networkMonitorContext);
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        CADestroyNetworkMonitorMutexes();
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    CAIPUpdateInterfaceInformation(&g_networkMonitorContext->netInterfaceList);
-
-    if (u_arraylist_length(g_networkMonitorContext->netInterfaceList))
-    {
-        g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_UP;
-    }
-    else
-    {
-        g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
+        OIC_LOG(ERROR, TAG, "Could not get CaIpInterface class");
+        return CA_STATUS_FAILED;
     }
 
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CAIPTerminateNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    g_networkMonitorContext->threadPool = NULL;
-
-    CAClearNetInterfaceInfoList(g_networkMonitorContext->netInterfaceList);
-
-    g_networkMonitorContext->netInterfaceList = NULL;
-    g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
-    g_networkMonitorContext->networkChangeCb = NULL;
-    g_networkMonitorContext->threadPool = NULL;
-
-    OICFree(g_networkMonitorContext);
-    g_networkMonitorContext = NULL;
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-    g_stopNetworkMonitor = true;
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
-
-    CADestroyNetworkMonitorMutexes();
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-CAResult_t CAIPStartNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-    g_stopNetworkMonitor = false;
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPStopNetworkMonitor()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext)
+    jmethodID mid_CaIpInterface_ctor = (*env)->GetMethodID(env, cls_CaIpInterface, "<init>",
+                                                                   "(Landroid/content/Context;)V");
+    if (!mid_CaIpInterface_ctor)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext is null");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
+        OIC_LOG(ERROR, TAG, "Could not get CaIpInterface constructor method");
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_unlock(g_networkMonitorContextMutex);
+    (*env)->NewObject(env, cls_CaIpInterface, mid_CaIpInterface_ctor, jApplicationContext);
+    OIC_LOG(DEBUG, TAG, "Create CaIpInterface instance, success");
 
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-    if (!g_stopNetworkMonitor)
-    {
-        g_stopNetworkMonitor = true;
-    }
-    else
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPStopNetworkMonitor, already stopped!");
-    }
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
+    OIC_LOG(DEBUG, TAG, "CAIPJniInit_OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t CAIPGetInterfaceInfo(u_arraylist_t **netInterfaceList)
+static CAResult_t CAIPDestroyJniInterface()
 {
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "CAIPDestroyJniInterface");
 
-    VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "u_array_list is null");
-    VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG, "g_networkMonitorContext is null");
-    VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
-                    "g_networkMonitorContextMutex is null");
-
-    // Get the interface and ipaddress information from cache
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList
-        || !(u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
+    JavaVM *jvm = CANativeJNIGetJavaVM();
+    if (!jvm)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "Network not enabled");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_ADAPTER_NOT_ENABLED;
+        OIC_LOG(ERROR, TAG, "Could not get JavaVM pointer");
+        return CA_STATUS_FAILED;
     }
 
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo list length [%d]",
-            list_length);
-    for (uint32_t list_index = 0; list_index < list_length; list_index++)
+    bool isAttached = false;
+    JNIEnv* env;
+    jint res = (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
     {
-        CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(
-                g_networkMonitorContext->netInterfaceList, list_index);
-        if (!info)
-        {
-            continue;
-        }
-        OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo ip [%s]",
-                  info->ipAddress);
-        CANetInfo_t *newNetinfo = (CANetInfo_t *) OICMalloc(sizeof(CANetInfo_t));
-        if (!newNetinfo)
-        {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed!");
-            ca_mutex_unlock(g_networkMonitorContextMutex);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-
-        *newNetinfo = *info;
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
+        res = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
 
-        CAResult_t result = u_arraylist_add(*netInterfaceList, (void *) newNetinfo);
-        if (CA_STATUS_OK != result)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
-            ca_mutex_unlock(g_networkMonitorContextMutex);
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
             return CA_STATUS_FAILED;
         }
+        isAttached = true;
     }
 
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAIPGetInterfaceSubnetMask(const char *ipAddress, char **subnetMask)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
-    VERIFY_NON_NULL(subnetMask, IP_MONITOR_TAG, "subnet mask");
-    VERIFY_NON_NULL(ipAddress, IP_MONITOR_TAG, "ipAddress is null");
-    VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG, "g_networkMonitorContext is null");
-    VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
-                    "g_networkMonitorContextMutex is null");
-
-    // Get the interface and ipaddress information from cache
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList
-        || (0 == u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
+    jclass jni_IpInterface = (*env)->FindClass(env, "org/iotivity/ca/CaIpInterface");
+    if (!jni_IpInterface)
     {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network not enabled");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return CA_ADAPTER_NOT_ENABLED;
+        OIC_LOG(ERROR, TAG, "Could not get CaIpInterface class");
+        goto error_exit;
     }
 
-    uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "list lenght [%d]", list_length);
-    for (uint32_t list_index = 0; list_index < list_length; list_index++)
+    jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_IpInterface,
+                                                                     "destroyIpInterface",
+                                                                     "()V");
+    if (!jni_InterfaceDestroyMethod)
     {
-        CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(
-                g_networkMonitorContext->netInterfaceList, list_index);
-        if (!info)
-        {
-            continue;
-        }
-
-        if (strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0)
-        {
-            OIC_LOG_V(DEBUG, IP_MONITOR_TAG,
-                      "CAIPGetInterfaceSubnetMask subnetmask is %s", info->subnetMask);
-            *subnetMask = OICStrdup(info->subnetMask);
-            break;
-        }
-    }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-bool CAIPIsConnected()
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-    if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "IP is not connected");
-        return false;
-    }
-
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (0 == u_arraylist_length(g_networkMonitorContext->netInterfaceList))
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "IP is not connected");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return false;
-    }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-    return true;
-}
-
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-    if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPSetConnectionStateChangeCallback failed");
-        return;
-    }
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-    g_networkMonitorContext->networkChangeCb = callback;
-
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-void CAIPSendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus)
-{
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-    ca_mutex_lock(g_stopNetworkMonitorMutex);
-
-    if (g_stopNetworkMonitor)
-    {
-        OIC_LOG(DEBUG, IP_MONITOR_TAG, "Stop Network Monitor Thread is called");
-        ca_mutex_unlock(g_stopNetworkMonitorMutex);
-        return;
+        OIC_LOG(ERROR, TAG, "Could not get CaIpInterface destroy method");
+        goto error_exit;
     }
 
-    ca_mutex_unlock(g_stopNetworkMonitorMutex);
+    (*env)->CallStaticVoidMethod(env, jni_IpInterface, jni_InterfaceDestroyMethod);
 
-    ca_mutex_lock(g_networkMonitorContextMutex);
-
-    if (!g_networkMonitorContext)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext is NULL");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return;
-    }
-
-    if (!g_networkMonitorContext->networkChangeCb)
+    if ((*env)->ExceptionCheck(env))
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext->networkChangeCb is NULL");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return;
+        OIC_LOG(ERROR, TAG, "destroyIpInterface has failed");
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        goto error_exit;
     }
 
-    ca_mutex_unlock(g_networkMonitorContextMutex);
-
-    u_arraylist_t *netInterfaceList = u_arraylist_create();
-
-    VERIFY_NON_NULL_VOID(netInterfaceList, IP_MONITOR_TAG,
-                         "memory allocation failed for netInterfaceList");
+    OIC_LOG(DEBUG, TAG, "Destroy instance for CaIpInterface");
 
-    // if network status is changed
-    CAResult_t ret = CAIPUpdateInterfaceInformation(&netInterfaceList);
-    if (CA_STATUS_OK != ret)
+    if (isAttached)
     {
-        OIC_LOG(ERROR, IP_MONITOR_TAG, "could not update interface information");
+        (*jvm)->DetachCurrentThread(jvm);
     }
 
-    ca_mutex_lock(g_networkMonitorContextMutex);
-    if (!g_networkMonitorContext->netInterfaceList)
-    {
-        OIC_LOG(ERROR, IP_MONITOR_TAG,
-                "u_arraylist_create failed. Network Monitor thread stopped");
-        CAClearNetInterfaceInfoList(netInterfaceList);
-        ca_mutex_unlock(g_networkMonitorContextMutex);
-        return;
-    }
-
-    uint32_t listLength = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
-    for (uint32_t listIndex = 0; listIndex < listLength;)
-    {
-        CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(
-                g_networkMonitorContext->netInterfaceList, listIndex);
-        if (!info)
-        {
-            listIndex++;
-            continue;
-        }
-
-        bool ret = CACheckIsAnyInterfaceDown(netInterfaceList, info);
-        if (ret)
-        {
-            OIC_LOG(DEBUG, IP_MONITOR_TAG, "Interface is down");
-            if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, listIndex))
-            {
-                OIC_LOG(DEBUG, IP_MONITOR_TAG, "u_arraylist_remove success");
-                if (g_networkMonitorContext->networkChangeCb)
-                {
-                    g_networkMonitorContext->networkChangeCb(info->ipAddress, CA_INTERFACE_DOWN);
-                }
-                OICFree(info);
-                listLength--;
-            }
-            else
-            {
-                OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
-                break;
-            }
-        }
-        else
-        {
-            listIndex++;
-        }
-    }
+    return CA_STATUS_OK;
 
-    ca_mutex_unlock(g_networkMonitorContextMutex);
+error_exit:
 
-    listLength = u_arraylist_length(netInterfaceList);
-    for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
+    if (isAttached)
     {
-        CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex);
-        if (!info)
-        {
-            continue;
-        }
-        bool ret = CACheckIsInterfaceInfoChanged(info);
-        if (ret)
-        {
-            OIC_LOG(DEBUG, IP_MONITOR_TAG, "CACheckIsInterfaceInfoChanged true");
-        }
+        (*jvm)->DetachCurrentThread(jvm);
     }
 
-    CAClearNetInterfaceInfoList(netInterfaceList);
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
+    return CA_STATUS_FAILED;
 }
 
 JNIEXPORT void JNICALL
 Java_org_iotivity_ca_CaIpInterface_caIpStateEnabled(JNIEnv *env, jclass class)
 {
-    CANetworkStatus_t currNetworkStatus = CA_INTERFACE_UP;
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "caIpStateEnabled");
+    (void)env;
+    (void)class;
+    OIC_LOG(DEBUG, TAG, "caIpStateEnabled");
 
-    CAIPSendNetworkChangeCallback(currNetworkStatus);
+    CAWakeUpForChange();
 }
 
 JNIEXPORT void JNICALL
 Java_org_iotivity_ca_CaIpInterface_caIpStateDisabled(JNIEnv *env, jclass class)
 {
-    CANetworkStatus_t currNetworkStatus = CA_INTERFACE_DOWN;
-    OIC_LOG(DEBUG, IP_MONITOR_TAG, "caIpStateDisabled");
+    (void)env;
+    (void)class;
+    OIC_LOG(DEBUG, TAG, "caIpStateDisabled");
 
-    CAIPSendNetworkChangeCallback(currNetworkStatus);
+    u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
+    if (!iflist)
+    {
+        OIC_LOG_V(ERROR, TAG, "get interface info failed");
+        return;
+    }
+    u_arraylist_destroy(iflist);
 }
-