Fix memory leak in IP Monitor for tizen.
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / ip_adapter / tizen / caipnwmonitor.c
1 /******************************************************************
2 *
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
4 *
5 *
6 *
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
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
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.
18 *
19 ******************************************************************/
20
21 #include "caipinterface.h"
22
23 #include <wifi.h>
24
25 #include "caadapterutils.h"
26 #include "camutex.h"
27 #include "logger.h"
28 #include "oic_malloc.h"
29 #include "oic_string.h"
30
31 #define IP_MONITOR_TAG "IP_MONITOR"
32
33 /**
34  * @var g_networkMonitorContextMutex
35  * @brief  Mutex for synchronizing access to cached interface and IP address information.
36  */
37 static ca_mutex g_networkMonitorContextMutex = NULL;
38
39 /**
40  * @struct CAIPNwMonitorContext
41  * @brief  Used for storing network monitor context information.
42  */
43 typedef struct
44 {
45     u_arraylist_t  *netInterfaceList;
46     ca_thread_pool_t threadPool;
47     CANetworkStatus_t nwConnectivityStatus;
48     CAIPConnectionStateChangeCallback networkChangeCb;
49 } CAIPNetworkMonitorContext;
50
51 /**
52  * @var g_networkMonitorContext
53  * @brief  network monitor context.
54  */
55 static CAIPNetworkMonitorContext *g_networkMonitorContext = NULL;
56
57 static void CARemoveInterfaceInfo()
58 {
59     ca_mutex_lock(g_networkMonitorContextMutex);
60     if (!g_networkMonitorContext->netInterfaceList)
61     {
62         OIC_LOG(ERROR, IP_MONITOR_TAG,
63                 "netInterfaceList is empty");
64         ca_mutex_unlock(g_networkMonitorContextMutex);
65         return;
66     }
67
68     uint32_t list_index = 0;
69     uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
70     for (list_index = 0; list_index < list_length; list_index++)
71     {
72         CANetInfo_t *netInfo = (CANetInfo_t *)u_arraylist_get(
73                                g_networkMonitorContext->netInterfaceList, list_index);
74         if (!netInfo)
75         {
76             continue;
77         }
78
79         if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, list_index))
80         {
81             if (g_networkMonitorContext->networkChangeCb)
82             {
83                 g_networkMonitorContext->networkChangeCb(netInfo->ipAddress,
84                                                          CA_INTERFACE_DOWN);
85             }
86         }
87         else
88         {
89             OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
90         }
91
92         OICFree(netInfo);
93     }
94
95     u_arraylist_free(&g_networkMonitorContext->netInterfaceList);
96
97     ca_mutex_unlock(g_networkMonitorContextMutex);
98 }
99
100 static bool CACheckIsInterfaceInfoChanged(const CANetInfo_t *info)
101 {
102     VERIFY_NON_NULL_RET(info, IP_MONITOR_TAG, "info is null", false);
103
104     ca_mutex_lock(g_networkMonitorContextMutex);
105     uint32_t list_index = 0;
106     uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
107     for (list_index = 0; list_index < list_length; list_index++)
108     {
109         CANetInfo_t *netInfo = (CANetInfo_t *)u_arraylist_get(
110                                g_networkMonitorContext->netInterfaceList, list_index);
111         if (!netInfo)
112         {
113             continue;
114         }
115
116         if (strncmp(netInfo->interfaceName, info->interfaceName, strlen(info->interfaceName)) == 0)
117         {
118             if (strncmp(netInfo->ipAddress, info->ipAddress, strlen(info->ipAddress)) == 0)
119             {
120                 ca_mutex_unlock(g_networkMonitorContextMutex);
121                 return false;
122             }
123             else
124             {
125                 OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network interface info changed");
126                 if (u_arraylist_remove(g_networkMonitorContext->netInterfaceList, list_index))
127                 {
128                     if (g_networkMonitorContext->networkChangeCb)
129                     {
130                         g_networkMonitorContext->networkChangeCb(netInfo->ipAddress,
131                                                                  CA_INTERFACE_DOWN);
132                     }
133                     OICFree(netInfo);
134                 }
135                 else
136                 {
137                     OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_remove failed");
138                 }
139                 break;
140             }
141         }
142     }
143
144     CANetInfo_t *newNetInfo = (CANetInfo_t *)OICMalloc(sizeof(CANetInfo_t));
145     if (!newNetInfo)
146     {
147         OIC_LOG(ERROR, IP_MONITOR_TAG, "newNetInfo malloc failed");
148         ca_mutex_unlock(g_networkMonitorContextMutex);
149         return false;
150     }
151     *newNetInfo = *info;
152
153     OIC_LOG(DEBUG, IP_MONITOR_TAG, "New Interface found");
154
155     CAResult_t result = u_arraylist_add(g_networkMonitorContext->netInterfaceList,
156                                         (void *)newNetInfo);
157     if (CA_STATUS_OK != result)
158     {
159         OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
160         OICFree(newNetInfo);
161         ca_mutex_unlock(g_networkMonitorContextMutex);
162         return false;
163     }
164     ca_mutex_unlock(g_networkMonitorContextMutex);
165
166     /*Callback will be unset only at the time of termination. By that time, all the threads will be
167       stopped gracefully. This callback is properly protected*/
168     if (g_networkMonitorContext->networkChangeCb)
169     {
170         g_networkMonitorContext->networkChangeCb(newNetInfo->ipAddress, CA_INTERFACE_UP);
171     }
172
173     return true;
174 }
175
176 void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress, char **subnetMask)
177 {
178     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
179
180     int ret = WIFI_ERROR_NONE;
181
182     if (!interfaceName || !ipAddress || !subnetMask)
183     {
184         OIC_LOG(ERROR, IP_MONITOR_TAG, "Invalid input: interface/ipaddress holder is NULL!");
185         return;
186     }
187
188     // Get wifi interface name
189     if (WIFI_ERROR_NONE != (ret = wifi_get_network_interface_name(interfaceName)))
190     {
191         OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get interface name! error num [%d]", ret);
192         return;
193     }
194
195     // Get wifi connected IP address
196     wifi_ap_h accessPoint = NULL;
197     if (WIFI_ERROR_NONE != (ret = wifi_get_connected_ap(&accessPoint)))
198     {
199         OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get access point! error num [%d]",
200                   ret);
201
202         OICFree(*interfaceName);
203         *interfaceName = NULL;
204         return;
205     }
206
207     if (WIFI_ERROR_NONE != (ret = wifi_ap_get_ip_address(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
208                                   ipAddress)))
209     {
210         OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get interface address! error num [%d]",
211                   ret);
212         OICFree(*interfaceName);
213         *interfaceName = NULL;
214         return;
215     }
216
217     if (WIFI_ERROR_NONE != (ret = wifi_ap_get_subnet_mask(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
218                                   subnetMask)))
219     {
220         OIC_LOG_V(ERROR, IP_MONITOR_TAG, "Failed to get interface address! error num [%d]",
221                   ret);
222         OICFree(*ipAddress);
223         OICFree(*interfaceName);
224         *ipAddress = NULL;
225         *interfaceName = NULL;
226         return;
227     }
228
229     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
230 }
231
232 static void CAIPGetInterfaceInformation(u_arraylist_t **netInterfaceList)
233 {
234     VERIFY_NON_NULL_VOID(netInterfaceList, IP_MONITOR_TAG, "netInterfaceList is null");
235
236     // Get wifi network information
237     char *interfaceName = NULL;
238     char *ipAddress = NULL;
239     char *subnetMask = NULL;
240     ///TODO: currently we are filling single interface. Once found the proper tizen apis for
241     // getting multiple interfaces, then this function will be updated.
242     CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
243
244     if (!interfaceName || !ipAddress || !subnetMask)
245     {
246         OIC_LOG(ERROR, IP_MONITOR_TAG, "interface/ipaddress/subnetmask is NULL!");
247         return;
248     }
249
250     CANetInfo_t *netInfo = (CANetInfo_t *)OICCalloc(1, sizeof(CANetInfo_t));
251     if (!netInfo)
252     {
253         OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed");
254         OICFree(interfaceName);
255         OICFree(ipAddress);
256         OICFree(subnetMask);
257         return;
258     }
259
260     // set interface name
261     OICStrcpy(netInfo->interfaceName, sizeof(netInfo->interfaceName), interfaceName);
262
263     // set local ip address
264     OICStrcpy(netInfo->ipAddress, sizeof(netInfo->ipAddress), ipAddress);
265
266     // set subnet mask
267     OICStrcpy(netInfo->subnetMask, sizeof(netInfo->subnetMask), subnetMask);
268
269     CAResult_t result = u_arraylist_add(*netInterfaceList, (void *)netInfo);
270     if (CA_STATUS_OK != result)
271     {
272         OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
273     }
274     OICFree(interfaceName);
275     OICFree(ipAddress);
276     OICFree(subnetMask);
277 }
278
279
280 void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
281                                     void *userData)
282 {
283     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
284
285     if (WIFI_CONNECTION_STATE_ASSOCIATION == state
286         || WIFI_CONNECTION_STATE_CONFIGURATION == state)
287     {
288         OIC_LOG(DEBUG, IP_MONITOR_TAG, "Connection is in Association State");
289         return;
290     }
291
292     // If Wifi is connected, then get the latest IP from the WIFI Interface
293     if (WIFI_CONNECTION_STATE_CONNECTED == state)
294     {
295         // Get network information
296         char *interfaceName = NULL;
297         char *ipAddress = NULL;
298         char *subnetMask = NULL;
299         CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress, &subnetMask);
300
301         CANetInfo_t *netInfo = (CANetInfo_t *)OICCalloc(1, sizeof(CANetInfo_t));
302         if (!netInfo)
303         {
304             OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed");
305             OICFree(interfaceName);
306             OICFree(ipAddress);
307             OICFree(subnetMask);
308             return;
309         }
310
311         // set interface name
312         OICStrcpy(netInfo->interfaceName, sizeof(netInfo->interfaceName), interfaceName);
313
314         // set local ip address
315         OICStrcpy(netInfo->ipAddress, sizeof(netInfo->ipAddress), ipAddress);
316
317         // set subnet mask
318         OICStrcpy(netInfo->subnetMask, sizeof(netInfo->subnetMask), subnetMask);
319
320         bool ret = CACheckIsInterfaceInfoChanged(netInfo);
321         if (ret)
322         {
323             OIC_LOG(DEBUG, IP_MONITOR_TAG, "CACheckIsInterfaceInfoChanged true");
324         }
325         OICFree(netInfo);
326
327         OICFree(interfaceName);
328         OICFree(ipAddress);
329         OICFree(subnetMask);
330     }
331     else
332     {
333         CARemoveInterfaceInfo();
334     }
335
336     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
337 }
338
339 void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData)
340 {
341     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
342
343     if (WIFI_DEVICE_STATE_ACTIVATED == state)
344     {
345         OIC_LOG(DEBUG, IP_MONITOR_TAG, "Wifi is in Activated State");
346     }
347     else
348     {
349         CAWIFIConnectionStateChangedCb(WIFI_CONNECTION_STATE_DISCONNECTED, NULL, NULL);
350         OIC_LOG(DEBUG, IP_MONITOR_TAG, "Wifi is in Deactivated State");
351     }
352
353     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
354 }
355
356 static CAResult_t CAInitializeNetworkMonitorMutexes()
357 {
358     if (!g_networkMonitorContextMutex)
359     {
360         g_networkMonitorContextMutex = ca_mutex_new();
361         if (!g_networkMonitorContextMutex)
362         {
363             OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContextMutex Malloc  failed");
364             return CA_MEMORY_ALLOC_FAILED;
365         }
366     }
367
368     return CA_STATUS_OK;
369 }
370
371 static void CADestroyNetworkMonitorMutexes()
372 {
373     ca_mutex_free(g_networkMonitorContextMutex);
374     g_networkMonitorContextMutex = NULL;
375 }
376
377 CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
378 {
379     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
380
381     VERIFY_NON_NULL(threadPool, IP_MONITOR_TAG, "threadPool is null");
382
383     CAResult_t ret = CAInitializeNetworkMonitorMutexes();
384
385     if (CA_STATUS_OK != ret)
386     {
387         OIC_LOG(ERROR, IP_MONITOR_TAG, "CAInitializeNetworkMonitorMutexes failed");
388         return CA_STATUS_FAILED;
389     }
390     ca_mutex_lock(g_networkMonitorContextMutex);
391
392      // Initialize Wifi service
393     wifi_error_e retValue = wifi_initialize();
394     if (WIFI_ERROR_NONE != retValue)
395     {
396         OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_initialize failed");
397         return CA_STATUS_FAILED;
398     }
399
400     g_networkMonitorContext = (CAIPNetworkMonitorContext *)OICCalloc(1,
401                               sizeof(*g_networkMonitorContext));
402     if (!g_networkMonitorContext)
403     {
404         OIC_LOG(ERROR, IP_MONITOR_TAG, "g_networkMonitorContext Malloc  failed");
405         ca_mutex_unlock(g_networkMonitorContextMutex);
406         CADestroyNetworkMonitorMutexes();
407         return CA_MEMORY_ALLOC_FAILED;
408     }
409
410     g_networkMonitorContext->netInterfaceList = u_arraylist_create();
411     if (!g_networkMonitorContext->netInterfaceList)
412     {
413         OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_create failed");
414         OICFree(g_networkMonitorContext);
415         ca_mutex_unlock(g_networkMonitorContextMutex);
416         CADestroyNetworkMonitorMutexes();
417         return CA_MEMORY_ALLOC_FAILED;
418     }
419
420     CAIPGetInterfaceInformation(&g_networkMonitorContext->netInterfaceList);
421
422     ca_mutex_unlock(g_networkMonitorContextMutex);
423
424     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
425     return CA_STATUS_OK;
426 }
427
428 void CAIPTerminateNetworkMonitor()
429 {
430     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
431
432     ca_mutex_lock(g_networkMonitorContextMutex);
433
434      // Deinitialize Wifi service
435     wifi_error_e ret = wifi_deinitialize();
436     if (WIFI_ERROR_NONE != ret)
437     {
438         OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_deinitialize failed");
439     }
440
441     CAClearNetInterfaceInfoList(g_networkMonitorContext->netInterfaceList);
442
443     g_networkMonitorContext->netInterfaceList = NULL;
444     g_networkMonitorContext->nwConnectivityStatus = CA_INTERFACE_DOWN;
445     g_networkMonitorContext->networkChangeCb = NULL;
446
447     OICFree(g_networkMonitorContext);
448     g_networkMonitorContext = NULL;
449
450     ca_mutex_unlock(g_networkMonitorContextMutex);
451
452     CADestroyNetworkMonitorMutexes();
453
454     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
455 }
456
457 CAResult_t CAIPStartNetworkMonitor()
458 {
459     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
460
461      // Set callback for receiving state changes
462     wifi_error_e ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
463     if (WIFI_ERROR_NONE != ret)
464     {
465         OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_set_device_state_changed_cb failed");
466         return CA_STATUS_FAILED;
467     }
468
469     // Set callback for receiving connection state changes
470     ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
471     if (WIFI_ERROR_NONE != ret)
472     {
473         OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_set_connection_state_changed_cb failed");
474         return CA_STATUS_FAILED;
475     }
476
477     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
478     return CA_STATUS_OK;
479 }
480
481 CAResult_t CAIPStopNetworkMonitor()
482 {
483     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
484
485      // Reset callback for receiving state changes
486     wifi_error_e ret = wifi_unset_device_state_changed_cb();
487     if (WIFI_ERROR_NONE != ret)
488     {
489         OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_unset_device_state_changed_cb failed");
490     }
491
492     // Reset callback for receiving connection state changes
493     ret = wifi_unset_connection_state_changed_cb();
494     if (WIFI_ERROR_NONE != ret)
495     {
496         OIC_LOG(ERROR, IP_MONITOR_TAG, "wifi_unset_connection_state_changed_cb failed");
497     }
498
499     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
500     return CA_STATUS_OK;
501 }
502
503 CAResult_t CAIPGetInterfaceInfo(u_arraylist_t **netInterfaceList)
504 {
505     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
506
507     VERIFY_NON_NULL(netInterfaceList, IP_MONITOR_TAG, "u_array_list is null");
508     VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG,
509                     "g_networkMonitorContext is null");
510     VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
511                     "g_networkMonitorContextMutex is null");
512
513     // Get the interface and ipaddress information from cache
514     ca_mutex_lock(g_networkMonitorContextMutex);
515     if (!g_networkMonitorContext->netInterfaceList
516         || !(u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
517     {
518         OIC_LOG(ERROR, IP_MONITOR_TAG, "Network not enabled");
519         ca_mutex_unlock(g_networkMonitorContextMutex);
520         return CA_ADAPTER_NOT_ENABLED;
521     }
522
523     uint32_t list_index = 0;
524     uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
525     OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo list length [%d]",
526               list_length);
527     for (list_index = 0; list_index < list_length; list_index++)
528     {
529         CANetInfo_t *info = (CANetInfo_t *)u_arraylist_get(
530                             g_networkMonitorContext->netInterfaceList, list_index);
531         if (!info)
532         {
533             continue;
534         }
535         OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "CAIPGetInterfaceInfo ip [%s]",
536                   info->ipAddress);
537         CANetInfo_t *newNetinfo = (CANetInfo_t *) OICMalloc(sizeof(CANetInfo_t));
538         if (!newNetinfo)
539         {
540             OIC_LOG(ERROR, IP_MONITOR_TAG, "Malloc failed!");
541             ca_mutex_unlock(g_networkMonitorContextMutex);
542             return CA_MEMORY_ALLOC_FAILED;
543         }
544
545         *newNetinfo = *info;
546
547         CAResult_t result = u_arraylist_add(*netInterfaceList, (void *)newNetinfo);
548         if (CA_STATUS_OK != result)
549         {
550             OIC_LOG(ERROR, IP_MONITOR_TAG, "u_arraylist_add failed!");
551             ca_mutex_unlock(g_networkMonitorContextMutex);
552             return CA_STATUS_FAILED;
553         }
554     }
555
556     ca_mutex_unlock(g_networkMonitorContextMutex);
557
558     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
559     return CA_STATUS_OK;
560 }
561
562 CAResult_t CAIPGetInterfaceSubnetMask(const char *ipAddress, char **subnetMask)
563 {
564     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
565
566     VERIFY_NON_NULL(subnetMask, IP_MONITOR_TAG, "subnet mask");
567     VERIFY_NON_NULL(ipAddress, IP_MONITOR_TAG, "ipAddress is null");
568     VERIFY_NON_NULL(g_networkMonitorContext, IP_MONITOR_TAG,
569                     "g_networkMonitorContext is null");
570     VERIFY_NON_NULL(g_networkMonitorContextMutex, IP_MONITOR_TAG,
571                     "g_networkMonitorContextMutex is null");
572
573     // Get the interface and ipaddress information from cache
574     ca_mutex_lock(g_networkMonitorContextMutex);
575     if (!g_networkMonitorContext->netInterfaceList
576         || !(u_arraylist_length(g_networkMonitorContext->netInterfaceList)))
577     {
578         OIC_LOG(DEBUG, IP_MONITOR_TAG, "Network not enabled");
579         ca_mutex_unlock(g_networkMonitorContextMutex);
580         return CA_ADAPTER_NOT_ENABLED;
581     }
582
583     uint32_t list_index = 0;
584     uint32_t list_length = u_arraylist_length(g_networkMonitorContext->netInterfaceList);
585     OIC_LOG_V(DEBUG, IP_MONITOR_TAG, "list lenght [%d]", list_length);
586     for (list_index = 0; list_index < list_length; list_index++)
587     {
588         CANetInfo_t *info = (CANetInfo_t *)u_arraylist_get(
589                             g_networkMonitorContext->netInterfaceList, list_index);
590         if (!info)
591         {
592             continue;
593         }
594
595         if (strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0)
596         {
597             OIC_LOG_V(DEBUG, IP_MONITOR_TAG,
598                       "CAIPGetInterfaceSubnetMask subnetmask is %s", info->subnetMask);
599             *subnetMask = OICStrdup(info->subnetMask);
600             break;
601         }
602     }
603     ca_mutex_unlock(g_networkMonitorContextMutex);
604
605     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
606     return CA_STATUS_OK;
607 }
608
609 bool CAIPIsConnected()
610 {
611     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
612
613     wifi_connection_state_e connection_state;
614     wifi_error_e ret = wifi_get_connection_state(&connection_state);
615     if (WIFI_ERROR_NONE != ret)
616     {
617         OIC_LOG(ERROR, IP_MONITOR_TAG, "Failed to get the Connection State");
618         return false;
619     }
620
621     if (WIFI_CONNECTION_STATE_DISCONNECTED == connection_state)
622     {
623         OIC_LOG(DEBUG, IP_MONITOR_TAG, "WIFI is not Connected");
624         return false;
625     }
626
627     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
628     return true;
629 }
630
631 void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback)
632 {
633     OIC_LOG(DEBUG, IP_MONITOR_TAG, "IN");
634     if (!g_networkMonitorContextMutex || !g_networkMonitorContext)
635     {
636         OIC_LOG(ERROR, IP_MONITOR_TAG, "CAIPSetConnectionStateChangeCallback failed");
637         return;
638     }
639     ca_mutex_lock(g_networkMonitorContextMutex);
640
641     g_networkMonitorContext->networkChangeCb = callback;
642
643     ca_mutex_unlock(g_networkMonitorContextMutex);
644
645     OIC_LOG(DEBUG, IP_MONITOR_TAG, "OUT");
646 }