1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
21 #include "caipinterface.h"
24 #include <sys/ioctl.h>
25 #include <arpa/inet.h>
31 #include "caadapterutils.h"
34 #include "oic_malloc.h"
35 #include "oic_string.h"
36 #include "org_iotivity_ca_CaIpInterface.h"
38 #define IP_MONITOR_TAG "IP_MONITOR"
39 #define MAX_INTERFACE_INFO_LENGTH (1024)
42 * @var g_stopNetworkMonitor
43 * @brief Used to stop the network monitor thread.
45 static bool g_stopNetworkMonitor = false;
48 * @var g_stopNetworkMonitorMutex
49 * @brief Mutex for synchronizing access to g_stopNetworkMonitor flag.
51 static ca_mutex g_stopNetworkMonitorMutex = NULL;
54 * @struct CAIPNwMonitorContext
55 * @brief Used for storing network monitor context information.
59 u_arraylist_t *netInterfaceList;
60 ca_thread_pool_t threadPool;
61 CANetworkStatus_t nwConnectivityStatus;
62 CAIPConnectionStateChangeCallback networkChangeCb;
63 } CAIPNetworkMonitorContext;
66 * @var g_networkMonitorContext
67 * @brief network monitor context.
69 static CAIPNetworkMonitorContext *g_networkMonitorContext = NULL;
72 * @var g_networkMonitorContextMutex
73 * @brief Mutex for synchronizing access to cached interface and IP address information.
75 static ca_mutex g_networkMonitorContextMutex = NULL;
79 * @brief pointer to store JavaVM
81 static JavaVM *g_jvm = NULL;
85 * @brief pointer to store Application Context
87 static jobject g_context = NULL;
90 * @fn CAIPUpdateInterfaceInformation
91 * @brief This methods gets local interface name and IP address information.
93 static CAResult_t CAIPUpdateInterfaceInformation(u_arraylist_t **netInterfaceList);
95 * @fn CACreateIPJNIInterfaceObject
96 * @brief creates new instance of CaIpInterface through JNI
98 static CAResult_t CACreateIPJNIInterfaceObject(jobject context);
101 * @fn CAIPSendNetworkChangeCallback
102 * @brief updates network status to IP adapter
104 static void CAIPSendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus);
106 CAResult_t CAIPJniInit()
108 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
110 OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPJniInit");
111 g_jvm = CANativeJNIGetJavaVM();
115 OIC_LOG(ERROR, IP_MONITOR_TAG, "JNI initialize error");
116 return CA_STATUS_FAILED;
119 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
123 CAResult_t CAIPJniSetContext()
125 OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPJniSetContext");
126 g_context = (jobject) CANativeJNIGetContext();
130 OIC_LOG(ERROR, IP_MONITOR_TAG, "unable to get application context");
131 return CA_STATUS_FAILED;
137 CAResult_t CACreateIPJNIInterfaceObject(jobject context)
139 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
141 OIC_LOG(DEBUG, IP_MONITOR_TAG, "CACreateIPJNIInterfaceObject");
143 VERIFY_NON_NULL(context, IP_MONITOR_TAG, "context");
147 if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
149 OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get JNIEnv pointer");
150 return CA_STATUS_FAILED;
153 //getApplicationContext
154 jclass contextClass = (*env)->FindClass(env, "android/content/Context");
157 OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get context object class");
158 return CA_STATUS_FAILED;
161 jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
162 "getApplicationContext",
163 "()Landroid/content/Context;");
164 if (!getApplicationContextMethod)
166 OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get getApplicationContext method");
167 return CA_STATUS_FAILED;
170 jobject gApplicationContext = (*env)->CallObjectMethod(env, context,
171 getApplicationContextMethod);
172 if (!getApplicationContextMethod)
174 OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get getApplicationContext");
175 return CA_STATUS_FAILED;
178 //Create CaIpInterface jni instance
179 jclass IPJniInterface = (*env)->FindClass(env, "org/iotivity/ca/CaIpInterface");
182 OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get CaIpInterface class");
183 return CA_STATUS_FAILED;
186 jmethodID IPInterfaceConstructorMethod = (*env)->GetMethodID(env, IPJniInterface, "<init>",
187 "(Landroid/content/Context;)V");
188 if (!IPInterfaceConstructorMethod)
190 OIC_LOG(ERROR, IP_MONITOR_TAG, "Could not get CaIpInterface constructor method");
191 return CA_STATUS_FAILED;
194 (*env)->NewObject(env, IPJniInterface, IPInterfaceConstructorMethod, gApplicationContext);
195 OIC_LOG(DEBUG, IP_MONITOR_TAG, "Create CaIpInterface instance, success");
197 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
201 static CAResult_t CAIPUpdateInterfaceInformation(u_arraylist_t **netInterfaceList)
203 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
205 VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null");
207 /* Get a socket handle. */
210 sck = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
215 sck=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
220 OIC_LOG(ERROR, IP_MONITOR_TAG, "Error in socket creation");
221 return CA_STATUS_FAILED;
224 char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 };
227 /* Query available interfaces. */
228 ifc.ifc_len = MAX_INTERFACE_INFO_LENGTH;
231 if (ioctl(sck, SIOCGIFCONF, &ifc) < 0)
234 OIC_LOG(ERROR, IP_MONITOR_TAG, "Failed to get interface info");
235 return CA_STATUS_FAILED;
238 /* Iterate through the list of interfaces. */
239 struct ifreq* ifr = ifc.ifc_req;
240 int32_t interfaces = ifc.ifc_len / sizeof(struct ifreq);
242 OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPUpdateInterfaceInformation : %d", interfaces);
246 OIC_LOG(ERROR, IP_MONITOR_TAG, "no interfaces");
247 return CA_STATUS_FAILED;
250 for (int32_t i = 0; i < interfaces; i++)
252 struct ifreq temp_ifr = { 0 };
253 struct ifreq* item = &ifr[i];
255 char interfaceAddress[CA_IPADDR_SIZE] = { 0 };
256 char interfaceSubnetMask[CA_IPADDR_SIZE] = { 0 };
257 socklen_t len = sizeof(struct sockaddr_in);
259 strcpy(temp_ifr.ifr_name, item->ifr_name);
261 if (ioctl(sck, SIOCGIFFLAGS, &temp_ifr))
263 OIC_LOG(ERROR, IP_MONITOR_TAG,
264 "CAIPUpdateInterfaceInformation, SIOCGIFFLAGS Failed");
266 return CA_STATUS_FAILED;
269 if ((temp_ifr.ifr_flags & IFF_LOOPBACK)
270 || !(temp_ifr.ifr_flags & IFF_UP) || !(temp_ifr.ifr_flags & IFF_RUNNING))
272 OIC_LOG_V(ERROR, IP_MONITOR_TAG,
273 "interface is not up or not running or loopback = %x", temp_ifr.ifr_flags);
277 if (AF_INET != ((struct sockaddr_in*) &item->ifr_addr)->sin_family)
282 //get the interface ip address
283 if (0 != getnameinfo(&item->ifr_addr, len, interfaceAddress, sizeof(interfaceAddress),
284 NULL, 0, NI_NUMERICHOST))
286 OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get IPAddress, Error code: %s",
289 return CA_STATUS_FAILED;
292 if (ioctl((int) sck, SIOCGIFNETMASK, item) < 0)
294 OIC_LOG(ERROR, IP_MONITOR_TAG,
295 "CAIPUpdateInterfaceInformation, SIOCGIFNETMASK Failed");
297 return CA_STATUS_FAILED;
300 // get the interface subnet mask
301 if (0 != getnameinfo(&item->ifr_netmask, len, interfaceSubnetMask,
302 sizeof(interfaceSubnetMask), NULL, 0, NI_NUMERICHOST))
304 OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get subnet mask, Error code: %s",
307 return CA_STATUS_FAILED;
310 CANetInfo_t *netInfo = (CANetInfo_t *) OICCalloc(1, sizeof(CANetInfo_t));
313 OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed");
315 return CA_MEMORY_ALLOC_FAILED;
318 // set interface name
319 strncpy(netInfo->interfaceName, item->ifr_name, strlen(item->ifr_name));
321 // set local ip address
322 strncpy(netInfo->ipAddress, interfaceAddress, strlen(interfaceAddress));
325 strncpy(netInfo->subnetMask, interfaceSubnetMask, strlen(interfaceSubnetMask));
327 CAResult_t result = u_arraylist_add(*netInterfaceList, (void *) netInfo);
328 if (CA_STATUS_OK != result)
330 OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!Thread exiting.");
332 return CA_STATUS_FAILED;
335 OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "ipAddress : %s, interfaceName : %s, subnetmask : %s",
336 netInfo->ipAddress, netInfo->interfaceName, netInfo->subnetMask);
340 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
344 static bool CACheckIsAnyInterfaceDown(const u_arraylist_t *netInterfaceList,
345 const CANetInfo_t *info)
347 VERIFY_NON_NULL_RET(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null", false);
348 VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
350 uint32_t list_length = u_arraylist_length(netInterfaceList);
351 for (uint32_t list_index = 0; list_index < list_length; list_index++)
353 CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, list_index);
358 if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
363 OIC_LOG(DEBUG, IP_MONITOR_TAG, "Interface is down");
367 static bool CACheckIsInterfaceInfoChanged(const CANetInfo_t *info)
369 VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
371 ca_mutex_lock(g_networkMonitorContextMutex);
373 uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
374 for (uint32_t list_index = 0; list_index < list_length; list_index++)
376 CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(
377 g_networkMonitorContext->netInterfaceList, list_index);
382 if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
384 if (strncmp(netInfo->ipAddress, info->ipAddress, strlen(info->ipAddress)) == 0)
386 ca_mutex_unlock(g_networkMonitorContextMutex);
391 OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network interface info changed");
392 if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, list_index))
394 if (g_networkMonitorContext->networkChangeCb)
396 g_networkMonitorContext->networkChangeCb(netInfo->ipAddress,
403 OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
410 CANetInfo_t *newNetInfo = (CANetInfo_t *) OICMalloc(sizeof(CANetInfo_t));
413 OIC_LOG(ERROR, IP_MONITOR_TAG, "newNetInfo malloc failed");
414 ca_mutex_unlock(g_networkMonitorContextMutex);
417 memcpy(newNetInfo, info, sizeof(*newNetInfo));
419 OIC_LOG(DEBUG, IP_MONITOR_TAG, "New Interface found");
421 CAResult_t result = u_arraylist_add(g_networkMonitorContext->netInterfaceList,
422 (void *) newNetInfo);
423 if (CA_STATUS_OK != result)
425 OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
427 ca_mutex_unlock(g_networkMonitorContextMutex);
430 ca_mutex_unlock(g_networkMonitorContextMutex);
432 /*Callback will be unset only at the time of termination. By that time, all the threads will be
433 stopped gracefully. This callback is properly protected*/
434 if (g_networkMonitorContext->networkChangeCb)
436 g_networkMonitorContext->networkChangeCb(newNetInfo->ipAddress, CA_INTERFACE_UP);
442 static CAResult_t CAInitializeNetworkMonitorMutexes()
444 if (!g_networkMonitorContextMutex)
446 g_networkMonitorContextMutex = ca_mutex_new();
447 if (!g_networkMonitorContextMutex)
449 OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContextMutex Malloc failed");
450 return CA_MEMORY_ALLOC_FAILED;
454 if (!g_stopNetworkMonitorMutex)
456 g_stopNetworkMonitorMutex = ca_mutex_new();
457 if (!g_stopNetworkMonitorMutex)
459 OIC_LOG(ERROR, IP_MONITOR_TAG, "g_stopNetworkMonitorMutex Malloc failed");
460 ca_mutex_free(g_networkMonitorContextMutex);
461 return CA_MEMORY_ALLOC_FAILED;
467 static void CADestroyNetworkMonitorMutexes()
469 ca_mutex_free(g_networkMonitorContextMutex);
470 g_networkMonitorContextMutex = NULL;
472 ca_mutex_free(g_stopNetworkMonitorMutex);
473 g_stopNetworkMonitorMutex = NULL;
476 CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
478 OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPInitializeNetworkMonitor IN");
480 VERIFY_NON_NULL(threadPool, IP_MONITOR_TAG, "threadPool is null");
482 CAResult_t ret = CAIPJniInit();
483 if (CA_STATUS_OK != ret)
485 OIC_LOG(ERROR, IP_MONITOR_TAG, "Initialization failed");
489 ret = CAIPJniSetContext();
490 if (CA_STATUS_OK != ret)
492 OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPJniSetContext failed");
496 ret = CACreateIPJNIInterfaceObject(g_context);
497 if (CA_STATUS_OK != ret)
499 OIC_LOG(ERROR, IP_MONITOR_TAG, "unable to create CaIpInterface instance");
503 ret = CAInitializeNetworkMonitorMutexes();
505 if (CA_STATUS_OK != ret)
507 OIC_LOG(ERROR, IP_MONITOR_TAG, "CAInitializeNetworkMonitorMutexes failed");
508 return CA_STATUS_FAILED;
511 ca_mutex_lock(g_networkMonitorContextMutex);
513 g_networkMonitorContext = (CAIPNetworkMonitorContext *) OICCalloc(
514 1, sizeof(*g_networkMonitorContext));
515 if (!g_networkMonitorContext)
517 OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext Malloc failed");
518 ca_mutex_unlock(g_networkMonitorContextMutex);
519 CADestroyNetworkMonitorMutexes();
520 return CA_MEMORY_ALLOC_FAILED;
522 g_networkMonitorContext->threadPool = threadPool;
524 g_networkMonitorContext->netInterfaceList = u_arraylist_create();
525 if (!g_networkMonitorContext->netInterfaceList)
527 OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_create failed");
528 OICFree(g_networkMonitorContext);
529 ca_mutex_unlock(g_networkMonitorContextMutex);
530 CADestroyNetworkMonitorMutexes();
531 return CA_MEMORY_ALLOC_FAILED;
534 CAIPUpdateInterfaceInformation(&g_networkMonitorContext->netInterfaceList);
536 if (u_arraylist_length(g_networkMonitorContext->netInterfaceList))
538 g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_UP;
542 g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
545 ca_mutex_unlock(g_networkMonitorContextMutex);
547 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
551 void CAIPTerminateNetworkMonitor()
553 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
555 ca_mutex_lock(g_networkMonitorContextMutex);
556 g_networkMonitorContext->threadPool = NULL;
558 CAClearNetInterfaceInfoList(g_networkMonitorContext->netInterfaceList);
560 g_networkMonitorContext->netInterfaceList = NULL;
561 g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
562 g_networkMonitorContext->networkChangeCb = NULL;
563 g_networkMonitorContext->threadPool = NULL;
565 OICFree(g_networkMonitorContext);
566 g_networkMonitorContext = NULL;
568 ca_mutex_unlock(g_networkMonitorContextMutex);
570 ca_mutex_lock(g_stopNetworkMonitorMutex);
571 g_stopNetworkMonitor = true;
572 ca_mutex_unlock(g_stopNetworkMonitorMutex);
574 CADestroyNetworkMonitorMutexes();
576 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
579 CAResult_t CAIPStartNetworkMonitor()
581 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
583 ca_mutex_lock(g_stopNetworkMonitorMutex);
584 g_stopNetworkMonitor = false;
585 ca_mutex_unlock(g_stopNetworkMonitorMutex);
587 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
591 CAResult_t CAIPStopNetworkMonitor()
593 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
595 ca_mutex_lock(g_networkMonitorContextMutex);
596 if (!g_networkMonitorContext)
598 OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext is null");
599 ca_mutex_unlock(g_networkMonitorContextMutex);
600 return CA_STATUS_FAILED;
603 ca_mutex_unlock(g_networkMonitorContextMutex);
605 ca_mutex_lock(g_stopNetworkMonitorMutex);
606 if (!g_stopNetworkMonitor)
608 g_stopNetworkMonitor = true;
612 OIC_LOG(DEBUG, IP_MONITOR_TAG, "CAIPStopNetworkMonitor, already stopped!");
614 ca_mutex_unlock(g_stopNetworkMonitorMutex);
616 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
620 CAResult_t CAIPGetInterfaceInfo(u_arraylist_t **netInterfaceList)
622 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
624 VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "u_array_list is null");
625 VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG, "g_networkMonitorContext is null");
626 VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
627 "g_networkMonitorContextMutex is null");
629 // Get the interface and ipaddress information from cache
630 ca_mutex_lock(g_networkMonitorContextMutex);
631 if (!g_networkMonitorContext->netInterfaceList
632 || !(u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
634 OIC_LOG(ERROR, IP_MONITOR_TAG, "Network not enabled");
635 ca_mutex_unlock(g_networkMonitorContextMutex);
636 return CA_ADAPTER_NOT_ENABLED;
639 uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
640 OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo list length [%d]",
642 for (uint32_t list_index = 0; list_index < list_length; list_index++)
644 CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(
645 g_networkMonitorContext->netInterfaceList, list_index);
650 OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo ip [%s]",
652 CANetInfo_t *newNetinfo = (CANetInfo_t *) OICMalloc(sizeof(CANetInfo_t));
655 OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed!");
656 ca_mutex_unlock(g_networkMonitorContextMutex);
657 return CA_MEMORY_ALLOC_FAILED;
660 memcpy(newNetinfo, info, sizeof(*info));
662 CAResult_t result = u_arraylist_add(*netInterfaceList, (void *) newNetinfo);
663 if (CA_STATUS_OK != result)
665 OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
666 ca_mutex_unlock(g_networkMonitorContextMutex);
667 return CA_STATUS_FAILED;
671 ca_mutex_unlock(g_networkMonitorContextMutex);
673 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
677 CAResult_t CAIPGetInterfaceSubnetMask(const char *ipAddress, char **subnetMask)
679 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
681 VERIFY_NON_NULL(subnetMask, IP_MONITOR_TAG, "subnet mask");
682 VERIFY_NON_NULL(ipAddress, IP_MONITOR_TAG, "ipAddress is null");
683 VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG, "g_networkMonitorContext is null");
684 VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
685 "g_networkMonitorContextMutex is null");
687 // Get the interface and ipaddress information from cache
688 ca_mutex_lock(g_networkMonitorContextMutex);
689 if (!g_networkMonitorContext->netInterfaceList
690 || (0 == u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
692 OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network not enabled");
693 ca_mutex_unlock(g_networkMonitorContextMutex);
694 return CA_ADAPTER_NOT_ENABLED;
697 uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
698 OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "list lenght [%d]", list_length);
699 for (uint32_t list_index = 0; list_index < list_length; list_index++)
701 CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(
702 g_networkMonitorContext->netInterfaceList, list_index);
708 if (strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0)
710 OIC_LOG_V(DEBUG, IP_MONITOR_TAG,
711 "CAIPGetInterfaceSubnetMask subnetmask is %s", info->subnetMask);
712 *subnetMask = OICStrdup(info->subnetMask);
716 ca_mutex_unlock(g_networkMonitorContextMutex);
718 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
722 bool CAIPIsConnected()
724 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
725 if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
727 OIC_LOG(ERROR, IP_MONITOR_TAG, "IP is not connected");
731 ca_mutex_lock(g_networkMonitorContextMutex);
732 if (0 == u_arraylist_length(g_networkMonitorContext->netInterfaceList))
734 OIC_LOG(ERROR, IP_MONITOR_TAG, "IP is not connected");
735 ca_mutex_unlock(g_networkMonitorContextMutex);
738 ca_mutex_unlock(g_networkMonitorContextMutex);
740 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
744 void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback)
746 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
747 if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
749 OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPSetConnectionStateChangeCallback failed");
752 ca_mutex_lock(g_networkMonitorContextMutex);
754 g_networkMonitorContext->networkChangeCb = callback;
756 ca_mutex_unlock(g_networkMonitorContextMutex);
758 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
761 void CAIPSendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus)
763 OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
764 ca_mutex_lock(g_stopNetworkMonitorMutex);
766 if (g_stopNetworkMonitor)
768 OIC_LOG(DEBUG, IP_MONITOR_TAG, "Stop Network Monitor Thread is called");
769 ca_mutex_unlock(g_stopNetworkMonitorMutex);
773 ca_mutex_unlock(g_stopNetworkMonitorMutex);
775 ca_mutex_lock(g_networkMonitorContextMutex);
777 if (!g_networkMonitorContext)
779 OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext is NULL");
780 ca_mutex_unlock(g_networkMonitorContextMutex);
784 if (!g_networkMonitorContext->networkChangeCb)
786 OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext->networkChangeCb is NULL");
787 ca_mutex_unlock(g_networkMonitorContextMutex);
791 ca_mutex_unlock(g_networkMonitorContextMutex);
793 u_arraylist_t *netInterfaceList = u_arraylist_create();
795 VERIFY_NON_NULL_VOID(netInterfaceList, IP_MONITOR_TAG,
796 "memory allocation failed for netInterfaceList");
798 // if network status is changed
799 CAResult_t ret = CAIPUpdateInterfaceInformation(&netInterfaceList);
800 if (CA_STATUS_OK != ret)
802 OIC_LOG(ERROR, IP_MONITOR_TAG, "could not update interface information");
805 ca_mutex_lock(g_networkMonitorContextMutex);
806 if (!g_networkMonitorContext->netInterfaceList)
808 OIC_LOG(ERROR, IP_MONITOR_TAG,
809 "u_arraylist_create failed. Network Monitor thread stopped");
810 CAClearNetInterfaceInfoList(netInterfaceList);
811 ca_mutex_unlock(g_networkMonitorContextMutex);
815 uint32_t listLength = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
816 for (uint32_t listIndex = 0; listIndex < listLength;)
818 CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(
819 g_networkMonitorContext->netInterfaceList, listIndex);
826 bool ret = CACheckIsAnyInterfaceDown(netInterfaceList, info);
829 OIC_LOG(DEBUG, IP_MONITOR_TAG, "Interface is down");
830 if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, listIndex))
832 OIC_LOG(DEBUG, IP_MONITOR_TAG, "u_arraylist_remove success");
833 if (g_networkMonitorContext->networkChangeCb)
835 g_networkMonitorContext->networkChangeCb(info->ipAddress, CA_INTERFACE_DOWN);
842 OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
852 ca_mutex_unlock(g_networkMonitorContextMutex);
854 listLength = u_arraylist_length(netInterfaceList);
855 for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
857 CANetInfo_t *info = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex);
862 bool ret = CACheckIsInterfaceInfoChanged(info);
865 OIC_LOG(DEBUG, IP_MONITOR_TAG, "CACheckIsInterfaceInfoChanged true");
869 CAClearNetInterfaceInfoList(netInterfaceList);
870 OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
873 JNIEXPORT void JNICALL
874 Java_org_iotivity_ca_CaIpInterface_caIpStateEnabled(JNIEnv *env, jclass class)
876 CANetworkStatus_t currNetworkStatus = CA_INTERFACE_UP;
877 OIC_LOG(DEBUG, IP_MONITOR_TAG, "caIpStateEnabled");
879 CAIPSendNetworkChangeCallback(currNetworkStatus);
882 JNIEXPORT void JNICALL
883 Java_org_iotivity_ca_CaIpInterface_caIpStateDisabled(JNIEnv *env, jclass class)
885 CANetworkStatus_t currNetworkStatus = CA_INTERFACE_DOWN;
886 OIC_LOG(DEBUG, IP_MONITOR_TAG, "caIpStateDisabled");
888 CAIPSendNetworkChangeCallback(currNetworkStatus);