[IOT-1346] Enable network status monitoring for tcp network
authorhyuna0213.jo <hyuna0213.jo@samsung.com>
Tue, 11 Oct 2016 23:25:20 +0000 (08:25 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Mon, 24 Oct 2016 07:05:16 +0000 (07:05 +0000)
In case a connected wifi ap is changed, we have to close
the connected session previously. Otherwise we will use the
invalid session. If network status is down, we try to close
the session. and If network status is up, we create new socket
for listening.

Change-Id: I662df1a9a28d0ca629a8b23f83f94833787c5312
Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/12185
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: jihwan seo <jihwan.seo@samsung.com>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/13097
Reviewed-by: Dave Thaler <dthaler@microsoft.com>
15 files changed:
resource/csdk/connectivity/inc/caipinterface.h
resource/csdk/connectivity/inc/caipnwmonitor.h [new file with mode: 0644]
resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c
resource/csdk/connectivity/src/ip_adapter/arduino/caipclient_eth.cpp
resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor_eth.cpp
resource/csdk/connectivity/src/ip_adapter/arduino/caipnwmonitor_wifi.cpp
resource/csdk/connectivity/src/ip_adapter/arduino/caipserver_eth.cpp
resource/csdk/connectivity/src/ip_adapter/arduino/caipserver_wifi.cpp
resource/csdk/connectivity/src/ip_adapter/caipadapter.c
resource/csdk/connectivity/src/ip_adapter/caipserver.c
resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c
resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c
resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c
resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c
resource/csdk/connectivity/src/tcp_adapter/catcpserver.c

index 67018251b18169143e300c566d8e2d02245b5258..5cf683ae1b29860127d62dd71dd4a9fd46af2115 100644 (file)
@@ -162,54 +162,6 @@ void CAIPPullData();
 
 #define CA_COAP        5683
 #define CA_SECURE_COAP 5684
-#define INTERFACE_NAME_MAX 16
-
-typedef struct
-{
-    char name[INTERFACE_NAME_MAX];
-    uint32_t index;
-    uint32_t flags;
-    uint16_t family;
-    char addr[MAX_ADDR_STR_SIZE_CA];
-} CAInterface_t;
-
-
-/**
- * Callback to be notified when IP adapter connection state changes.
- *
- * @param[in]  adapter      Transport adapter.
- * @param[in]  status       Connection status either ::CA_INTERFACE_UP or ::CA_INTERFACE_DOWN.
- * @see CAIPSetConnectionStateChangeCallback() for registration.
- */
-typedef void (*CAIPConnectionStateChangeCallback)(CATransportAdapter_t adapter, CANetworkStatus_t status);
-
-/**
- * Set callback for receiving local IP adapter connection status.
- *
- * @param[in]  adapter      Callback to be notified when IP adapter connection state changes.
- */
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback);
-
-/**
- * Set callback for receiving local IP adapter connection status.
- *
- * @param[in]  callback     Callback to be notified when IP adapter connection state changes.
- */
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback);
-
-/**
- * Get a list of CAInterface_t items.
- *
- * @return  List of CAInterface_t items.
- */
-u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex);
-
-/**
- * Find a new network interface.
- *
- * @return  Description of interface (or NULL if no change)
- */
-CAInterface_t *CAFindInterfaceChange();
 
 /**
  * Let the network monitor update the polling interval.
@@ -224,20 +176,6 @@ int CAGetPollingInterval(int interval);
  */
 void CAWakeUpForChange();
 
-/**
- * Start network monitor.
- *
- * @return ::CA_STATUS_OK or Appropriate error code.
- */
-CAResult_t CAIPStartNetworkMonitor();
-
-/**
- * Stops network monitor.
- *
- * @return ::CA_STATUS_OK or Appropriate error code.
- */
-CAResult_t CAIPStopNetworkMonitor();
-
 /**
  * Set callback for error handling.
  *
diff --git a/resource/csdk/connectivity/inc/caipnwmonitor.h b/resource/csdk/connectivity/inc/caipnwmonitor.h
new file mode 100644 (file)
index 0000000..8946135
--- /dev/null
@@ -0,0 +1,121 @@
+/******************************************************************
+ *
+ * Copyright 2016 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.
+ *
+ ******************************************************************/
+
+/**
+ * @file caipnwmonitor.h
+ * This file provides APIs IP network monitor modules.
+ */
+
+#ifndef CA_IP_NW_INTERFACE_H_
+#define CA_IP_NW_INTERFACE_H_
+
+#include "cacommon.h"
+#include "cathreadpool.h"
+#include "uarraylist.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define INTERFACE_NAME_MAX 16
+
+/**
+ * Callback to be notified when IP adapter network state changes.
+ *
+ * @param[in]  adapter      Transport adapter.
+ * @param[in]  status       Connection status either ::CA_INTERFACE_UP or ::CA_INTERFACE_DOWN.
+ * @see CAIPSetConnectionStateChangeCallback() for registration.
+ */
+typedef void (*CAIPAdapterStateChangeCallback)(CATransportAdapter_t adapter,
+                                               CANetworkStatus_t status);
+
+typedef struct
+{
+    char name[INTERFACE_NAME_MAX];
+    uint32_t index;
+    uint32_t flags;
+    uint16_t family;
+    char addr[MAX_ADDR_STR_SIZE_CA];
+} CAInterface_t;
+
+typedef struct CAIPCBData_t
+{
+    struct CAIPCBData_t *next;
+    CATransportAdapter_t adapter;
+    CAIPAdapterStateChangeCallback callback;
+} CAIPCBData_t;
+
+/**
+ * Set callback for receiving local IP/TCP adapter connection status.
+ *
+ * @param[in]  callback     Callback to be notified when IP/TCP adapter connection state changes.
+ * @param[in]  adapter      Transport adapter.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+                                         CATransportAdapter_t adapter);
+
+/**
+ * Unset callback for receiving local IP/TCP adapter connection status.
+ *
+ * @param[in]  adapter      Transport adapter.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter);
+
+/**
+ * Get a list of CAInterface_t items.
+ *
+ * @param[in]  desiredIndex      Network interface index.
+ * @return  List of CAInterface_t items.
+ */
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex);
+
+/**
+ * Find a new network interface.
+ *
+ * @return  Description of interface (or NULL if no change)
+ */
+CAInterface_t *CAFindInterfaceChange();
+
+/**
+ * Start network monitor.
+ *
+ * @param[in]  callback     Callback to be notified when IP/TCP adapter connection state changes.
+ * @param[in]  adapter      Transport adapter.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+                                   CATransportAdapter_t adapter);
+
+/**
+ * Stops network monitor.
+ *
+ * @param[in]  adapter      Transport adapter.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CA_IP_NW_INTERFACE_H_ */
index d9c09b0abf13d68c011c00bb3bfd43b6ae2d7af6..e3e2dc4ac3f39b73b9c3420889e64b19bbc3e016 100644 (file)
 
 #include <arpa/inet.h>
 #include <linux/if.h>
+#include <coap/utlist.h>
 
 #include "caadapterutils.h"
+#include "caipnwmonitor.h"
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 #define TAG "OIC_CA_IP_MONITOR"
 #define NETLINK_MESSAGE_LENGTH  (4096)
 
-static CAIPConnectionStateChangeCallback g_networkChangeCallback;
+/**
+ * Used to storing adapter changes callback interface.
+ */
+static struct CAIPCBData_t *g_adapterCallbackList = NULL;
 
+/**
+ * Create new interface item to add in activated interface list.
+ * @param[in]  index    Network interface index number.
+ * @param[in]  name     Network interface name.
+ * @param[in]  family   Network interface family type.
+ * @param[in]  addr     New interface address.
+ * @param[in]  flags    The active flag word of a device.
+ * @return  CAInterface_t objects.
+ */
 static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
                                          const char *addr, int flags);
 
+/**
+ * Add created new interface item activated interface list.
+ * @param[in]  iflist   Network interface array list.
+ * @param[in]  index    Network interface index number.
+ * @param[in]  name     Network interface name.
+ * @param[in]  family   Network interface family type.
+ * @param[in]  addr     New interface address.
+ * @param[in]  flags    The active flag word of a device.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
 static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
                                      const char *name, int family, const char *addr, int flags);
 
+/**
+ * Initialize JNI interface.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
 CAResult_t CAIPJniInit();
 
 /**
- * destroy JNI interface.
+ * Destroy JNI interface.
  * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
 static CAResult_t CAIPDestroyJniInterface();
 
 #define MAX_INTERFACE_INFO_LENGTH 1024 // allows 32 interfaces from SIOCGIFCONF
 
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+                                   CATransportAdapter_t adapter)
 {
-    return CAIPJniInit();
+    CAResult_t res = CAIPJniInit();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "failed to initialize ip jni interface");
+        return res;
+    }
+
+    return CAIPSetNetworkMonitorCallback(callback, adapter);
 }
 
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
 {
-    return CAIPDestroyJniInterface();
+    CAIPUnSetNetworkMonitorCallback(adapter);
+
+    // if there is no callback to pass the changed status, stop monitoring.
+    if (!g_adapterCallbackList)
+    {
+        return CAIPDestroyJniInterface();
+    }
+
+    return CA_STATUS_OK;
 }
 
 int CAGetPollingInterval(int interval)
@@ -72,9 +116,66 @@ int CAGetPollingInterval(int interval)
     return interval;
 }
 
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status)
 {
-    g_networkChangeCallback = callback;
+    CAIPCBData_t *cbitem = NULL;
+    LL_FOREACH(g_adapterCallbackList, cbitem)
+    {
+        if (cbitem && cbitem->adapter)
+        {
+            cbitem->callback(cbitem->adapter, status);
+        }
+    }
+}
+
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+                                         CATransportAdapter_t adapter)
+{
+    if (!callback)
+    {
+        OIC_LOG(ERROR, TAG, "callback is null");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    CAIPCBData_t *cbitem = NULL;
+    LL_FOREACH(g_adapterCallbackList, cbitem)
+    {
+        if (cbitem && adapter == cbitem->adapter && callback == cbitem->callback)
+        {
+            OIC_LOG(DEBUG, TAG, "this callback is already added");
+            return CA_STATUS_OK;
+        }
+    }
+
+    cbitem = (CAIPCBData_t *)OICCalloc(1, sizeof(*cbitem));
+    if (!cbitem)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc failed");
+        return CA_STATUS_FAILED;
+    }
+
+    cbitem->adapter = adapter;
+    cbitem->callback = callback;
+    LL_APPEND(g_adapterCallbackList, cbitem);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter)
+{
+    CAIPCBData_t *cbitem = NULL;
+    CAIPCBData_t *tmpCbitem = NULL;
+    LL_FOREACH_SAFE(g_adapterCallbackList, cbitem, tmpCbitem)
+    {
+        if (cbitem && adapter == cbitem->adapter)
+        {
+            OIC_LOG(DEBUG, TAG, "remove specific callback");
+            LL_DELETE(g_adapterCallbackList, cbitem);
+            OICFree(cbitem);
+            return CA_STATUS_OK;
+        }
+    }
+    return CA_STATUS_OK;
 }
 
 CAInterface_t *CAFindInterfaceChange()
@@ -464,7 +565,7 @@ Java_org_iotivity_ca_CaIpInterface_caIpStateEnabled(JNIEnv *env, jclass class)
     (void)class;
 
     OIC_LOG(DEBUG, TAG, "Wifi is in Activated State");
-    g_networkChangeCallback(CA_ADAPTER_IP, CA_INTERFACE_UP);
+    CAIPPassNetworkChangesToAdapter(CA_INTERFACE_UP);
 }
 
 JNIEXPORT void JNICALL
@@ -474,5 +575,5 @@ Java_org_iotivity_ca_CaIpInterface_caIpStateDisabled(JNIEnv *env, jclass class)
     (void)class;
 
     OIC_LOG(DEBUG, TAG, "Wifi is in Deactivated State");
-    g_networkChangeCallback(CA_ADAPTER_IP, CA_INTERFACE_DOWN);
+    CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN);
 }
index cd31bec1f79dfa2b9de2519b5ba7a625bbaf3676..f36778fe0aa0ff28032e71a0224b3b35e9695aa7 100644 (file)
@@ -30,6 +30,7 @@
 #include "cacommon.h"
 #include "caadapterinterface.h"
 #include "caipadapter.h"
+#include "caipnwmonitor.h"
 #include "caipadapterutils_eth.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
index 97b4981796b1138023c85386fe5f1f1ed71d88d0..eb3dcd0202f7733d182d1d148af83f373ab15b77 100644 (file)
@@ -35,6 +35,7 @@
 #include "logger.h"
 #include "cacommon.h"
 #include "caipadapter.h"
+#include "caipnwmonitor.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 // defined & used (as-is defined in the linux socket headers).
 #define AF_INET (2)
 
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+                                   CATransportAdapter_t adapter)
 {
     return CA_STATUS_OK;
 }
 
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
 {
     return CA_STATUS_OK;
 }
index e31e825c858ddef6801f100fa96007808bf15a01..93507ca6fda25c00430055f35b3e2f1847155f3f 100644 (file)
@@ -36,6 +36,7 @@
 #include "logger.h"
 #include "cacommon.h"
 #include "caipadapter.h"
+#include "caipnwmonitor.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 // defined & used (as-is defined in the linux socket headers).
 #define AF_INET (2)
 
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+                                   CATransportAdapter_t adapter)
 {
     return CA_STATUS_OK;
 }
 
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
 {
     return CA_STATUS_OK;
 }
index 476a297cb57cec19fb987ba4d17541f3c9ed0421..d38ef073badab6fc96d4de839074b471d5aff322 100644 (file)
@@ -32,6 +32,7 @@
 #include "cainterface.h"
 #include "caadapterinterface.h"
 #include "caipadapter.h"
+#include "caipnwmonitor.h"
 #include "caipadapterutils_eth.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
index 5bbff11893b96747401048537312806713c04aaa..bd63d988639737e0876a43a462ab516d54193039 100644 (file)
@@ -33,6 +33,7 @@
 #include "cainterface.h"
 #include "caadapterinterface.h"
 #include "caipadapter.h"
+#include "caipnwmonitor.h"
 #include "caadapterutils.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
index 9f1805c4bc4d733c0740074dad58da30c1528ed9..51b6a9ee1ccffcfcba4b9522761fc275c3eb9dcb 100644 (file)
@@ -24,6 +24,7 @@
 #include <string.h>
 #include <stdint.h>
 
+#include "caipnwmonitor.h"
 #include "caipinterface.h"
 #include "caqueueingthread.h"
 #include "caadapterutils.h"
@@ -137,7 +138,7 @@ void CAIPDeinitializeQueueHandles()
 
 #endif // SINGLE_THREAD
 
-void CAIPConnectionStateCB(CATransportAdapter_t adapter, CANetworkStatus_t status)
+void CAIPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
 {
     if (g_networkChangeCallback)
     {
@@ -241,9 +242,7 @@ CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
 
     CAIPSetErrorHandler(CAIPErrorHandler);
     CAIPSetPacketReceiveCallback(CAIPPacketReceivedCB);
-#ifndef SINGLE_THREAD
-    CAIPSetConnectionStateChangeCallback(CAIPConnectionStateCB);
-#endif
+
 #ifdef __WITH_DTLS__
     if (CA_STATUS_OK != CAinitSslAdapter())
     {
@@ -283,7 +282,7 @@ CAResult_t CAStartIP()
     caglobals.ip.u4.port  = caglobals.ports.udp.u4;
     caglobals.ip.u4s.port = caglobals.ports.udp.u4s;
 
-    CAIPStartNetworkMonitor();
+    CAIPStartNetworkMonitor(CAIPAdapterHandler, CA_ADAPTER_IP);
 #ifdef SINGLE_THREAD
     uint16_t unicastPort = 55555;
     // Address is hardcoded as we are using Single Interface
@@ -417,7 +416,7 @@ CAResult_t CAStopIP()
     }
 #endif
 
-    CAIPStopNetworkMonitor();
+    CAIPStopNetworkMonitor(CA_ADAPTER_IP);
     CAIPStopServer();
     //Re-initializing the Globals to start them again
     CAInitializeIPGlobals();
index 19f376689add320a9ce722ca280396e73b4c65e2..35c9ee8886faa6fccf1f8ac86f1ed78c6debd0f9 100644 (file)
@@ -59,6 +59,7 @@
 
 #include <coap/pdu.h>
 #include "caipinterface.h"
+#include "caipnwmonitor.h"
 #include "caadapterutils.h"
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 #include "ca_adapter_net_ssl.h"
@@ -1187,11 +1188,6 @@ void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
     g_packetReceivedCallback = callback;
 }
 
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback)
-{
-    CAIPSetNetworkMonitorCallback(callback);
-}
-
 static void sendData(int fd, const CAEndpoint_t *endpoint,
                      const void *data, uint32_t dlen,
                      const char *cast, const char *fam)
index 7d09727d45c7e380dae66338f656f2ab66ec555c..1cd1c95b485a4f1912b769deb225f8c6b20474da 100644 (file)
 #endif
 
 #include "camutex.h"
+#include "caipnwmonitor.h"
 #include "caadapterutils.h"
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
+#include <coap/utlist.h>
 
 #define TAG "OIC_CA_IP_MONITOR"
 
@@ -57,10 +59,44 @@ static ca_mutex g_networkMonitorContextMutex = NULL;
  */
 static u_arraylist_t *g_netInterfaceList = NULL;
 
-static CAIPConnectionStateChangeCallback g_networkChangeCallback = NULL;
+/**
+ * Used to storing adapter changes callback interface.
+ */
+static struct CAIPCBData_t *g_adapterCallbackList = NULL;
 
+/**
+ * Initialize the network interface monitoring list.
+ */
 static CAResult_t CAIPInitializeNetworkMonitorList();
+
+/**
+ * Destroy the network interface monitoring list.
+ */
 static void CAIPDestroyNetworkMonitorList();
+
+/**
+ * Compare the interface with the already added interface in list.
+ */
+static bool CACmpNetworkList(uint32_t ifiindex);
+
+/**
+ * Add new network interface in list.
+ */
+static CAResult_t CAAddNetworkMonitorList(CAInterface_t *ifitem);
+
+/**
+ * Remove network interace from list.
+ */
+static void CARemoveNetworkMonitorList(int ifiindex);
+
+/**
+ * Pass the changed network status through the stored callback.
+ */
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status);
+
+/**
+ * Create new interface item.
+ */
 static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
                                          const char *addr, int flags);
 
@@ -117,7 +153,8 @@ static bool CACmpNetworkList(uint32_t ifiindex)
     uint32_t list_length = u_arraylist_length(g_netInterfaceList);
     for (uint32_t list_index = 0; list_index < list_length; list_index++)
     {
-        CAInterface_t *currItem = (CAInterface_t *) u_arraylist_get(g_netInterfaceList, list_index);
+        CAInterface_t *currItem = (CAInterface_t *) u_arraylist_get(g_netInterfaceList,
+                                                                    list_index);
         if (currItem->index == ifiindex)
         {
             ca_mutex_unlock(g_networkMonitorContextMutex);
@@ -171,15 +208,21 @@ static void CARemoveNetworkMonitorList(int ifiindex)
     return;
 }
 
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+                                   CATransportAdapter_t adapter)
 {
-    return CAIPInitializeNetworkMonitorList();
+    CAResult_t res = CAIPInitializeNetworkMonitorList();
+    if (CA_STATUS_OK == res)
+    {
+        return CAIPSetNetworkMonitorCallback(callback, adapter);
+    }
+    return res;
 }
 
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
 {
     CAIPDestroyNetworkMonitorList();
-    return CA_STATUS_OK;
+    return CAIPUnSetNetworkMonitorCallback(adapter);
 }
 
 int CAGetPollingInterval(int interval)
@@ -187,9 +230,66 @@ int CAGetPollingInterval(int interval)
     return interval;
 }
 
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status)
 {
-    g_networkChangeCallback = callback;
+    CAIPCBData_t *cbitem = NULL;
+    LL_FOREACH(g_adapterCallbackList, cbitem)
+    {
+        if (cbitem && cbitem->adapter)
+        {
+            cbitem->callback(cbitem->adapter, status);
+        }
+    }
+}
+
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+                                         CATransportAdapter_t adapter)
+{
+    if (!callback)
+    {
+        OIC_LOG(ERROR, TAG, "callback is null");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    CAIPCBData_t *cbitem = NULL;
+    LL_FOREACH(g_adapterCallbackList, cbitem)
+    {
+        if (cbitem && adapter == cbitem->adapter && callback == cbitem->callback)
+        {
+            OIC_LOG(DEBUG, TAG, "this callback is already added");
+            return CA_STATUS_OK;
+        }
+    }
+
+    cbitem = (CAIPCBData_t *)OICCalloc(1, sizeof(*cbitem));
+    if (!cbitem)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc failed");
+        return CA_STATUS_FAILED;
+    }
+
+    cbitem->adapter = adapter;
+    cbitem->callback = callback;
+    LL_APPEND(g_adapterCallbackList, cbitem);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter)
+{
+    CAIPCBData_t *cbitem = NULL;
+    CAIPCBData_t *tmpCbitem = NULL;
+    LL_FOREACH_SAFE(g_adapterCallbackList, cbitem, tmpCbitem)
+    {
+        if (cbitem && adapter == cbitem->adapter)
+        {
+            OIC_LOG(DEBUG, TAG, "remove specific callback");
+            LL_DELETE(g_adapterCallbackList, cbitem);
+            OICFree(cbitem);
+            return CA_STATUS_OK;
+        }
+    }
+    return CA_STATUS_OK;
 }
 
 static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
@@ -245,10 +345,7 @@ CAInterface_t *CAFindInterfaceChange()
             if (isFound)
             {
                 CARemoveNetworkMonitorList(ifiIndex);
-                if (g_networkChangeCallback)
-                {
-                    g_networkChangeCallback(CA_ADAPTER_IP ,CA_INTERFACE_DOWN);
-                }
+                CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN);
             }
             continue;
         }
@@ -305,7 +402,6 @@ u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
         u_arraylist_destroy(iflist);
         return NULL;
     }
-    OIC_LOG(DEBUG, TAG, "Got ifaddrs");
 
     struct ifaddrs *ifa = NULL;
     for (ifa = ifp; ifa; ifa = ifa->ifa_next)
@@ -388,10 +484,7 @@ u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
                 OICFree(newifitem);
                 goto exit;
             }
-            if (g_networkChangeCallback)
-            {
-                g_networkChangeCallback(CA_ADAPTER_IP, CA_INTERFACE_UP);
-            }
+            CAIPPassNetworkChangesToAdapter(CA_INTERFACE_UP);
             OIC_LOG_V(DEBUG, TAG, "Added interface: %s (%d)", ifitem->name, ifitem->family);
         }
     }
index 3635f159ba1f1f0eac61baa637200252337880f0..bad3fdb21494aae5fdd3d71b29937fc517f32d0b 100644 (file)
 #include <arpa/inet.h>
 #include <netinet/in.h>
 
+#include "caipnwmonitor.h"
 #include "caadapterutils.h"
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
+#include <coap/utlist.h>
 
 #define TAG "IP_MONITOR"
 
 
 #define NETLINK_MESSAGE_LENGTH  (4096)
 
-static CAIPConnectionStateChangeCallback g_networkChangeCallback;
+/**
+ * Used to storing adapter changes callback interface.
+ */
+static struct CAIPCBData_t *g_adapterCallbackList = NULL;
 
+/**
+ * Create new interface item.
+ */
 static CAInterface_t *CANewInterfaceItem(int index, char *name, int family,
                                          const char *addr, int flags);
 
+/**
+ * Add new network interface in list.
+ */
 static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
                                      char *name, int family, const char *addr, int flags);
 
+/**
+ * Pass the changed network status through the stored callback.
+ */
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status);
+
+/**
+ * Callback function to received connection state changes.
+ */
 static void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
                                            void *userData);
 
+/**
+ * Callback function to received device state changes.
+ */
 static void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData);
 
 
@@ -65,9 +87,66 @@ int CAGetPollingInterval(int interval)
     return interval;
 }
 
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status)
 {
-    g_networkChangeCallback = callback;
+    CAIPCBData_t *cbitem = NULL;
+    LL_FOREACH(g_adapterCallbackList, cbitem)
+    {
+        if (cbitem && cbitem->adapter)
+        {
+            cbitem->callback(cbitem->adapter, status);
+        }
+    }
+}
+
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+                                         CATransportAdapter_t adapter)
+{
+    if (!callback)
+    {
+        OIC_LOG(ERROR, TAG, "callback is null");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    CAIPCBData_t *cbitem = NULL;
+    LL_FOREACH(g_adapterCallbackList, cbitem)
+    {
+        if (cbitem && adapter == cbitem->adapter && callback == cbitem->callback)
+        {
+            OIC_LOG(DEBUG, TAG, "this callback is already added");
+            return CA_STATUS_OK;
+        }
+    }
+
+    cbitem = (CAIPCBData_t *)OICCalloc(1, sizeof(*cbitem));
+    if (!cbitem)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc failed");
+        return CA_STATUS_FAILED;
+    }
+
+    cbitem->adapter = adapter;
+    cbitem->callback = callback;
+    LL_APPEND(g_adapterCallbackList, cbitem);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter)
+{
+    CAIPCBData_t *cbitem = NULL;
+    CAIPCBData_t *tmpCbitem = NULL;
+    LL_FOREACH_SAFE(g_adapterCallbackList, cbitem, tmpCbitem)
+    {
+        if (cbitem && adapter == cbitem->adapter)
+        {
+            OIC_LOG(DEBUG, TAG, "remove specific callback");
+            LL_DELETE(g_adapterCallbackList, cbitem);
+            OICFree(cbitem);
+            return CA_STATUS_OK;
+        }
+    }
+    return CA_STATUS_OK;
 }
 
 CAInterface_t *CAFindInterfaceChange()
@@ -130,64 +209,70 @@ CAInterface_t *CAFindInterfaceChange()
     return foundNewInterface;
 }
 
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+                                   CATransportAdapter_t adapter)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-     // Initialize Wifi service
-    wifi_error_e ret = wifi_initialize();
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, TAG, "wifi_initialize failed");
-        return CA_STATUS_FAILED;
-    }
-
-    // Set callback for receiving state changes
-    ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, TAG, "wifi_set_device_state_changed_cb failed");
-        return CA_STATUS_FAILED;
-    }
-
-    // Set callback for receiving connection state changes
-    ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
-    if (WIFI_ERROR_NONE != ret)
+    if (!g_adapterCallbackList)
     {
-        OIC_LOG(ERROR, TAG, "wifi_set_connection_state_changed_cb failed");
-        return CA_STATUS_FAILED;
+        // Initialize Wifi service
+       wifi_error_e ret = wifi_initialize();
+       if (WIFI_ERROR_NONE != ret)
+       {
+           OIC_LOG(ERROR, TAG, "wifi_initialize failed");
+           return CA_STATUS_FAILED;
+       }
+
+       // Set callback for receiving state changes
+       ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
+       if (WIFI_ERROR_NONE != ret)
+       {
+           OIC_LOG(ERROR, TAG, "wifi_set_device_state_changed_cb failed");
+           return CA_STATUS_FAILED;
+       }
+
+       // Set callback for receiving connection state changes
+       ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
+       if (WIFI_ERROR_NONE != ret)
+       {
+           OIC_LOG(ERROR, TAG, "wifi_set_connection_state_changed_cb failed");
+           return CA_STATUS_FAILED;
+       }
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
+    return CAIPSetNetworkMonitorCallback(callback, adapter);
 }
 
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-     // Reset callback for receiving state changes
-    wifi_error_e ret = wifi_unset_device_state_changed_cb();
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, TAG, "wifi_unset_device_state_changed_cb failed");
-    }
-
-    // Reset callback for receiving connection state changes
-    ret = wifi_unset_connection_state_changed_cb();
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, TAG, "wifi_unset_connection_state_changed_cb failed");
-    }
-
-    // Deinitialize Wifi service
-    ret = wifi_deinitialize();
-    if (WIFI_ERROR_NONE != ret)
+    CAIPUnSetNetworkMonitorCallback(adapter);
+    if (!g_adapterCallbackList)
     {
-        OIC_LOG(ERROR, TAG, "wifi_deinitialize failed");
+        // Reset callback for receiving state changes
+       wifi_error_e ret = wifi_unset_device_state_changed_cb();
+       if (WIFI_ERROR_NONE != ret)
+       {
+           OIC_LOG(ERROR, TAG, "wifi_unset_device_state_changed_cb failed");
+       }
+
+       // Reset callback for receiving connection state changes
+       ret = wifi_unset_connection_state_changed_cb();
+       if (WIFI_ERROR_NONE != ret)
+       {
+           OIC_LOG(ERROR, TAG, "wifi_unset_connection_state_changed_cb failed");
+       }
+
+       // Deinitialize Wifi service
+       ret = wifi_deinitialize();
+       if (WIFI_ERROR_NONE != ret)
+       {
+           OIC_LOG(ERROR, TAG, "wifi_deinitialize failed");
+       }
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
@@ -336,11 +421,11 @@ void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
 
     if (WIFI_CONNECTION_STATE_CONNECTED == state)
     {
-        g_networkChangeCallback(CA_ADAPTER_IP, CA_INTERFACE_UP);
+        CAIPPassNetworkChangesToAdapter(CA_INTERFACE_UP);
     }
     else
     {
-        g_networkChangeCallback(CA_ADAPTER_IP, CA_INTERFACE_DOWN);
+        CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN);
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
index a91b159d0ff3ad18f4663e311b56832b802176fe..53b058cf0fd53528ec3a7d65e0365f5ab497b45f 100644 (file)
@@ -32,6 +32,7 @@
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
+#include "caipnwmonitor.h"
 
 #define TAG "IP_MONITOR"
 
@@ -39,7 +40,8 @@
  * @todo Implement network interface monitoring in case the IP changes.
  * Not critical for win32 bring-up.
  */
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+                                   CATransportAdapter_t adapter)
 {
     return CA_STATUS_OK;
 }
@@ -48,7 +50,8 @@ CAResult_t CAIPStartNetworkMonitor()
  * @todo Implement network interface monitoring in case the IP changes.
  * Not critical for win32 bring-up.
  */
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
+
 {
     return CA_STATUS_OK;
 }
@@ -78,9 +81,10 @@ CAInterface_t *CAFindInterfaceChange()
  * @todo Implement network interface monitoring.
  * Not critical for win32 bring-up.
  */
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+                                         CATransportAdapter_t adapter)
 {
-    return;
+    return CA_NOT_SUPPORTED;
 }
 
 bool IsValidAdapter(PIP_ADAPTER_ADDRESSES pAdapterAddr, int desiredIndex, uint16_t family)
index 0d125b29bfba5aa6d6ec20b03cd315ed105a8425..93a12e8f071163ca5c961ae6fb2bb5a54af092f8 100644 (file)
@@ -29,6 +29,7 @@
 #include <inttypes.h>
 
 #include "cainterface.h"
+#include "caipnwmonitor.h"
 #include "catcpadapter.h"
 #include "catcpinterface.h"
 #include "caqueueingthread.h"
@@ -212,6 +213,35 @@ void CATCPSetKeepAliveCallbacks(CAKeepAliveConnectionCallback ConnHandler)
     g_connKeepAliveCallback = ConnHandler;
 }
 
+void CATCPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
+{
+    if (g_networkChangeCallback)
+    {
+        g_networkChangeCallback(adapter, status);
+    }
+
+    if (CA_INTERFACE_DOWN == status)
+    {
+        OIC_LOG(DEBUG, TAG, "Network status is down, close all session");
+        CATCPStopServer();
+    }
+    else if (CA_INTERFACE_UP == status)
+    {
+        OIC_LOG(DEBUG, TAG, "Network status is up, create new socket for listening");
+
+        CAResult_t ret = CA_STATUS_FAILED;
+#ifndef SINGLE_THREAD
+        ret = CATCPStartServer((const ca_thread_pool_t)caglobals.tcp.threadpool);
+#else
+        ret = CATCPStartServer();
+#endif
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG_V(DEBUG, TAG, "CATCPStartServer failed[%d]", ret);
+        }
+    }
+}
+
 static void CAInitializeTCPGlobals()
 {
     caglobals.tcp.ipv4.fd = -1;
@@ -296,7 +326,10 @@ CAResult_t CAStartTCP()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    // Specific the port number received from application.
+    // Start network monitoring to receive adapter status changes.
+    CAIPStartNetworkMonitor(CATCPAdapterHandler, CA_ADAPTER_TCP);
+
+    // Set the port number received from application.
     caglobals.tcp.ipv4.port = caglobals.ports.tcp.u4;
     caglobals.tcp.ipv6.port = caglobals.ports.tcp.u6;
 
@@ -314,7 +347,6 @@ CAResult_t CAStartTCP()
         OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
         return CA_STATUS_FAILED;
     }
-
 #else
     CAResult_t ret = CATCPStartServer();
     if (CA_STATUS_OK != ret)
@@ -428,11 +460,14 @@ CAResult_t CAReadTCPData()
 
 CAResult_t CAStopTCP()
 {
+    CAIPStopNetworkMonitor(CA_ADAPTER_TCP);
+
 #ifndef SINGLE_THREAD
     if (g_sendQueueHandle && g_sendQueueHandle->threadMutex)
     {
         CAQueueingThreadStop(g_sendQueueHandle);
     }
+    CATCPDeinitializeQueueHandles();
 #endif
 
     CATCPStopServer();
@@ -449,11 +484,8 @@ CAResult_t CAStopTCP()
 
 void CATerminateTCP()
 {
+    CAStopTCP();
     CATCPSetPacketReceiveCallback(NULL);
-
-#ifndef SINGLE_THREAD
-    CATCPDeinitializeQueueHandles();
-#endif
 }
 
 void CATCPSendDataThread(void *threadData)
index 7e0065e9ac4b016eb0ce77d3f93db9ef9b44a70f..5b19f9cb7df53d0abeb9223d734c3bff4d3f664b 100644 (file)
@@ -38,6 +38,7 @@
 #endif
 
 #include "catcpinterface.h"
+#include "caipnwmonitor.h"
 #include <coap/pdu.h>
 #include "caadapterutils.h"
 #include "camutex.h"
@@ -1184,14 +1185,26 @@ void CATCPDisconnectAll()
         svritem = (CATCPSessionInfo_t *) u_arraylist_get(caglobals.tcp.svrlist, i);
         if (svritem && svritem->fd >= 0)
         {
+#ifdef __WITH_TLS__
+            if (CA_STATUS_OK != CAcloseSslConnection(&svritem->sep.endpoint))
+            {
+                OIC_LOG(ERROR, TAG, "Failed to close TLS session");
+            }
+#endif
             shutdown(svritem->fd, SHUT_RDWR);
             close(svritem->fd);
-
             OICFree(svritem->data);
             svritem->data = NULL;
+
+            // pass the connection information to CA Common Layer.
+            if (g_connectionCallback)
+            {
+                g_connectionCallback(&(svritem->sep.endpoint), false);
+            }
         }
     }
     u_arraylist_destroy(caglobals.tcp.svrlist);
+    caglobals.tcp.svrlist = NULL;
     ca_mutex_unlock(g_mutexObjectList);
 }