/******************************************************************
- *
- * 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 "umutex.h"
#include "logger.h"
#include "oic_malloc.h"
#include "oic_string.h"
-#include "org_iotivity_jar_caipinterface.h"
+#include "org_iotivity_ca_CaIpInterface.h"
-#define IP_MONITOR_TAG "IP_MONITOR"
-#define MAX_INTERFACE_INFO_LENGTH (1024)
+#define TAG "OIC_CA_IP_MONITOR"
-/**
- * @var g_stopNetworkMonitor
- * @brief Used to stop the network monitor thread.
- */
-static bool g_stopNetworkMonitor = false;
+static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
+ uint32_t addr, int flags);
-/**
- * @var g_stopNetworkMonitorMutex
- * @brief Mutex for synchronizing access to g_stopNetworkMonitor flag.
- */
-static u_mutex g_stopNetworkMonitorMutex = NULL;
+static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
+ const char *name, int family, uint32_t addr, int flags);
-/**
- * @struct CAIPNwMonitorContext
- * @brief Used for storing network monitor context information.
- */
-typedef struct
-{
- u_arraylist_t *netInterfaceList;
- u_thread_pool_t threadPool;
- CANetworkStatus_t nwConnectivityStatus;
- CAIPConnectionStateChangeCallback networkChangeCb;
-} CAIPNetworkMonitorContext;
+CAResult_t CAIPJniInit();
/**
- * @var g_networkMonitorContext
- * @brief network monitor context.
+ * destroy JNI interface.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
*/
-static CAIPNetworkMonitorContext *g_networkMonitorContext = NULL;
+static CAResult_t CAIPDestroyJniInterface();
-/**
- * @var g_networkMonitorContextMutex
- * @brief Mutex for synchronizing access to cached interface and IP address information.
- */
-static u_mutex g_networkMonitorContextMutex = NULL;
-
-/**
- * @var g_jvm
- * @brief pointer to store JavaVM
- */
-static JavaVM *g_jvm = NULL;
+#define MAX_INTERFACE_INFO_LENGTH 1024 // allows 32 interfaces from SIOCGIFCONF
-/**
- * @var g_context
- * @brief pointer to store Application Context
- */
-static jobject g_context = NULL;
-
-/**
- * @fn CAIPUpdateInterfaceInformation
- * @brief This methods gets local interface name and IP address information.
- */
-static CAResult_t CAIPUpdateInterfaceInformation(u_arraylist_t **netInterfaceList);
-/**
- * @fn CACreateIPJNIInterfaceObject
- * @brief creates new instance of caipinterface through JNI
- */
-static CAResult_t CACreateIPJNIInterfaceObject(jobject context);
-
-/**
- * @fn CAIPSendNetworkChangeCallback
- * @brief updates network status to IP adapter
- */
-static void CAIPSendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus);
-
-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");
+ return interval;
+}
- JNIEnv* env;
+CAInterface_t *CAFindInterfaceChange()
+{
+ char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
+ struct ifconf ifc = { .ifc_len = MAX_INTERFACE_INFO_LENGTH, .ifc_buf = buf };
- if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
+ int s = caglobals.ip.u6.fd != -1 ? caglobals.ip.u6.fd : caglobals.ip.u4.fd;
+ if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get JNIEnv pointer");
- return CA_STATUS_FAILED;
+ OIC_LOG_V(ERROR, TAG, "SIOCGIFCONF failed: %s", strerror(errno));
+ return NULL;
}
- //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;
- }
+ CAInterface_t *foundNewInterface = NULL;
- 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;
- }
+ struct ifreq* ifr = ifc.ifc_req;
+ size_t interfaces = ifc.ifc_len / sizeof (ifc.ifc_req[0]);
+ size_t ifreqsize = ifc.ifc_len;
- jobject gApplicationContext = (*env)->CallObjectMethod(env, context,
- getApplicationContextMethod);
- if (!getApplicationContextMethod)
+ CAIfItem_t *previous = (CAIfItem_t *)OICMalloc(ifreqsize);
+ if (!previous)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get getApplicationContext");
- return CA_STATUS_FAILED;
+ OIC_LOG(ERROR, TAG, "OICMalloc failed");
+ return NULL;
}
- //Create caipinterface jni instance
- jclass IPJniInterface = (*env)->FindClass(env, "org/iotivity/jar/caipinterface");
- if (!IPJniInterface)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get caipinterface class");
- return CA_STATUS_FAILED;
- }
+ memcpy(previous, caglobals.ip.nm.ifItems, ifreqsize);
+ size_t numprevious = caglobals.ip.nm.numIfItems;
- jmethodID IPInterfaceConstructorMethod = (*env)->GetMethodID(env, IPJniInterface, "<init>",
- "(Landroid/content/Context;)V");
- if (!IPInterfaceConstructorMethod)
+ if (ifreqsize > caglobals.ip.nm.sizeIfItems)
{
- 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;
-}
-
-static CAResult_t CAIPUpdateInterfaceInformation(u_arraylist_t **netInterfaceList)
-{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
- VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null");
-
- /* Get a socket handle. */
- int sck = socket(AF_INET, SOCK_DGRAM, 0);
- if (sck < 0)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Error in socket creation");
- return CA_STATUS_FAILED;
- }
-
- char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
- struct ifconf ifc;
-
- /* Query available interfaces. */
- ifc.ifc_len = MAX_INTERFACE_INFO_LENGTH;
- ifc.ifc_buf = buf;
-
- if (ioctl(sck, SIOCGIFCONF, &ifc) < 0)
- {
- close(sck);
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Failed to get interface info");
- 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;
}
- /* 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);
-
- 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);
-
- strcpy(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))
{
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
- strncpy(netInfo->interfaceName, item->ifr_name, strlen(item->ifr_name));
-
- // set local ip address
- strncpy(netInfo->ipAddress, interfaceAddress, strlen(interfaceAddress));
+ foundNewInterface = CANewInterfaceItem(ifIndex, name, AF_INET, ipv4addr, flags);
+ }
- // set subnet mask
- strncpy(netInfo->subnetMask, interfaceSubnetMask, strlen(interfaceSubnetMask));
+ OICFree(previous);
+ return foundNewInterface;
+}
- 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;
- }
+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;
+ }
- OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "ipAddress : %s, interfaceName : %s, subnetmask : %s",
- netInfo->ipAddress, netInfo->interfaceName, netInfo->subnetMask);
- close(sck);
- return CA_STATUS_OK;
+ char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
+ struct ifconf ifc = { .ifc_len = MAX_INTERFACE_INFO_LENGTH, .ifc_buf = buf };
- break;
+ 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_FAILED;
-}
+ 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;
+ }
+ int16_t flags = item->ifr_flags;
+ if ((flags & IFF_LOOPBACK) || !(flags & IFF_RUNNING))
{
continue;
}
- if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
+ if (ioctl(s, SIOCGIFINDEX, item) < 0)
{
- return false;
+ 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);
-
- u_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)
- {
- u_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");
- u_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;
+ }
}
- memcpy(newNetInfo, info, sizeof(*newNetInfo));
+ 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);
- u_mutex_unlock(g_networkMonitorContextMutex);
- return false;
+ return CA_STATUS_FAILED;
}
- u_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)
- {
- g_networkMonitorContextMutex = u_mutex_new();
- if (!g_networkMonitorContextMutex)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContextMutex Malloc failed");
- return CA_MEMORY_ALLOC_FAILED;
- }
- }
-
- if (!g_stopNetworkMonitorMutex)
+ CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof (CAInterface_t));
+ if (!ifitem)
{
- g_stopNetworkMonitorMutex = u_mutex_new();
- if (!g_stopNetworkMonitorMutex)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "g_stopNetworkMonitorMutex Malloc failed");
- u_mutex_free(g_networkMonitorContextMutex);
- return CA_MEMORY_ALLOC_FAILED;
- }
+ OIC_LOG(ERROR, TAG, "Malloc failed");
+ return NULL;
}
- return CA_STATUS_OK;
-}
-static void CADestroyNetworkMonitorMutexes()
-{
- u_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;
- u_mutex_free(g_stopNetworkMonitorMutex);
- g_stopNetworkMonitorMutex = NULL;
+ return ifitem;
}
-CAResult_t CAIPInitializeNetworkMonitor(const u_thread_pool_t threadPool)
+CAResult_t CAIPJniInit()
{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
- VERIFY_NON_NULL(threadPool, IP_MONITOR_TAG, "threadPool is null");
-
- CAResult_t ret = CAIPJniInit();
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "Initialization failed");
- return ret;
- }
+ OIC_LOG(DEBUG, TAG, "CAIPJniInit_IN");
- ret = CAIPJniSetContext();
- if (CA_STATUS_OK != ret)
+ JavaVM *jvm = CANativeJNIGetJavaVM();
+ if (!jvm)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPJniSetContext failed");
- return ret;
+ OIC_LOG(ERROR, TAG, "Could not get JavaVM pointer");
+ return CA_STATUS_FAILED;
}
- ret = CACreateIPJNIInterfaceObject(g_context);
- if (CA_STATUS_OK != ret)
+ jobject context = CANativeJNIGetContext();
+ if (!context)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "unable to create caipinterface instance");
- return ret;
+ OIC_LOG(ERROR, TAG, "unable to get application context");
+ return CA_STATUS_FAILED;
}
- ret = CAInitializeNetworkMonitorMutexes();
-
- 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, "CAInitializeNetworkMonitorMutexes failed");
+ OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
return CA_STATUS_FAILED;
}
- u_mutex_lock(g_networkMonitorContextMutex);
+ jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
+ "getApplicationContext",
+ "()Landroid/content/Context;");
- g_networkMonitorContext = (CAIPNetworkMonitorContext *) OICCalloc(
- 1, sizeof(*g_networkMonitorContext));
- if (!g_networkMonitorContext)
+ if (!mid_getApplicationContext)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext Malloc failed");
- u_mutex_unlock(g_networkMonitorContextMutex);
- CADestroyNetworkMonitorMutexes();
- return CA_MEMORY_ALLOC_FAILED;
+ OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
+ return CA_STATUS_FAILED;
}
- g_networkMonitorContext->threadPool = threadPool;
- g_networkMonitorContext->netInterfaceList = u_arraylist_create();
- if (!g_networkMonitorContext->netInterfaceList)
+ jobject jApplicationContext = (*env)->CallObjectMethod(env, context,
+ mid_getApplicationContext);
+ if (!jApplicationContext)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_create failed");
- OICFree(g_networkMonitorContext);
- u_mutex_unlock(g_networkMonitorContextMutex);
- CADestroyNetworkMonitorMutexes();
- return CA_MEMORY_ALLOC_FAILED;
+ OIC_LOG(ERROR, TAG, "Could not get application context");
+ return CA_STATUS_FAILED;
}
- CAIPUpdateInterfaceInformation(&g_networkMonitorContext->netInterfaceList);
-
- if (u_arraylist_length(g_networkMonitorContext->netInterfaceList))
- {
- g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_UP;
- }
- else
+ jclass cls_CaIpInterface = (*env)->FindClass(env, "org/iotivity/ca/CaIpInterface");
+ if (!cls_CaIpInterface)
{
- g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
+ OIC_LOG(ERROR, TAG, "Could not get CaIpInterface class");
+ return CA_STATUS_FAILED;
}
- u_mutex_unlock(g_networkMonitorContextMutex);
-
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CAIPTerminateNetworkMonitor()
-{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
- u_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;
-
- u_mutex_unlock(g_networkMonitorContextMutex);
-
- u_mutex_lock(g_stopNetworkMonitorMutex);
- g_stopNetworkMonitor = true;
- u_mutex_unlock(g_stopNetworkMonitorMutex);
-
- CADestroyNetworkMonitorMutexes();
-
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-
-CAResult_t CAIPStartNetworkMonitor()
-{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
-
- u_mutex_lock(g_stopNetworkMonitorMutex);
- g_stopNetworkMonitor = false;
- u_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");
-
- u_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");
- u_mutex_unlock(g_networkMonitorContextMutex);
+ OIC_LOG(ERROR, TAG, "Could not get CaIpInterface constructor method");
return CA_STATUS_FAILED;
}
- u_mutex_unlock(g_networkMonitorContextMutex);
-
- u_mutex_lock(g_stopNetworkMonitorMutex);
- if (!g_stopNetworkMonitor)
- {
- g_stopNetworkMonitor = true;
- }
- else
- {
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPStopNetworkMonitor, already stopped!");
- }
- u_mutex_unlock(g_stopNetworkMonitorMutex);
+ (*env)->NewObject(env, cls_CaIpInterface, mid_CaIpInterface_ctor, jApplicationContext);
+ OIC_LOG(DEBUG, TAG, "Create CaIpInterface instance, success");
- 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");
-
- 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");
+ OIC_LOG(DEBUG, TAG, "CAIPDestroyJniInterface");
- // Get the interface and ipaddress information from cache
- u_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");
- u_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!");
- u_mutex_unlock(g_networkMonitorContextMutex);
- return CA_MEMORY_ALLOC_FAILED;
- }
+ OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
+ res = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
- memcpy(newNetinfo, info, sizeof(*info));
-
- 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!");
- u_mutex_unlock(g_networkMonitorContextMutex);
+ OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
return CA_STATUS_FAILED;
}
+ isAttached = true;
}
- u_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
- u_mutex_lock(g_networkMonitorContextMutex);
- if (!g_networkMonitorContext->netInterfaceList
- || (0 == u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
- {
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network not enabled");
- u_mutex_unlock(g_networkMonitorContextMutex);
- return CA_ADAPTER_NOT_ENABLED;
- }
-
- 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++)
- {
- CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(
- g_networkMonitorContext->netInterfaceList, list_index);
- if (!info)
- {
- continue;
- }
-
- if (strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0)
- {
- if (!info->subnetMask)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG,
- "CAIPGetInterfaceSubnetMask subnetmask is null");
- }
- OIC_LOG_V(DEBUG, IP_MONITOR_TAG,
- "CAIPGetInterfaceSubnetMask subnetmask is %s", info->subnetMask);
- *subnetMask = info->subnetMask ? OICStrdup(info->subnetMask) : NULL;
- break;
- }
- }
- u_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;
- }
-
- u_mutex_lock(g_networkMonitorContextMutex);
- if (0 == u_arraylist_length(g_networkMonitorContext->netInterfaceList))
+ jclass jni_IpInterface = (*env)->FindClass(env, "org/iotivity/ca/CaIpInterface");
+ if (!jni_IpInterface)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "IP is not connected");
- u_mutex_unlock(g_networkMonitorContextMutex);
- return false;
+ OIC_LOG(ERROR, TAG, "Could not get CaIpInterface class");
+ goto error_exit;
}
- u_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)
+ jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_IpInterface,
+ "destroyIpInterface",
+ "()V");
+ if (!jni_InterfaceDestroyMethod)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPSetConnectionStateChangeCallback failed");
- return;
+ OIC_LOG(ERROR, TAG, "Could not get CaIpInterface destroy method");
+ goto error_exit;
}
- u_mutex_lock(g_networkMonitorContextMutex);
-
- g_networkMonitorContext->networkChangeCb = callback;
-
- u_mutex_unlock(g_networkMonitorContextMutex);
-
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
-}
-void CAIPSendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus)
-{
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
- u_mutex_lock(g_stopNetworkMonitorMutex);
- if (g_stopNetworkMonitor)
- {
- OIC_LOG(DEBUG, IP_MONITOR_TAG, "Stop Network Monitor Thread is called");
- u_mutex_unlock(g_stopNetworkMonitorMutex);
- return;
- }
- u_mutex_unlock(g_stopNetworkMonitorMutex);
+ (*env)->CallStaticVoidMethod(env, jni_IpInterface, jni_InterfaceDestroyMethod);
- u_mutex_lock(g_networkMonitorContextMutex);
- if (!g_networkMonitorContext->networkChangeCb)
+ if ((*env)->ExceptionCheck(env))
{
- OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkChangeCb is NULL");
- u_mutex_unlock(g_networkMonitorContextMutex);
- return;
+ OIC_LOG(ERROR, TAG, "destroyIpInterface has failed");
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ goto error_exit;
}
- u_mutex_unlock(g_networkMonitorContextMutex);
- u_arraylist_t *netInterfaceList = u_arraylist_create();
-
- VERIFY_NON_NULL_VOID(netInterfaceList, IP_MONITOR_TAG,
- "memory allocation failed for netInterfaceList");
-
- // if network status is changed
- CAResult_t ret = CAIPUpdateInterfaceInformation(&netInterfaceList);
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG(ERROR, IP_MONITOR_TAG, "could not update interface information");
- }
+ OIC_LOG(DEBUG, TAG, "Destroy instance for CaIpInterface");
- u_mutex_lock(g_networkMonitorContextMutex);
- if (!g_networkMonitorContext->netInterfaceList)
+ if (isAttached)
{
- OIC_LOG(ERROR, IP_MONITOR_TAG,
- "u_arraylist_create failed. Network Monitor thread stopped");
- CAClearNetInterfaceInfoList(netInterfaceList);
- u_mutex_unlock(g_networkMonitorContextMutex);
- return;
+ (*jvm)->DetachCurrentThread(jvm);
}
- 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;
- u_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_jar_caipinterface_CAIPStateEnabled(JNIEnv *env, jclass class)
+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_jar_caipinterface_CAIPStateDisabled(JNIEnv *env, jclass class)
+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);
}
-