[IOT-1346] Enable network status monitoring for tcp network 85/12185/7
authorhyuna0213.jo <hyuna0213.jo@samsung.com>
Mon, 26 Sep 2016 00:19:40 +0000 (09:19 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Thu, 29 Sep 2016 06:44:44 +0000 (06:44 +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>
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 6701825..5cf683a 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 ec426d9..05f2673 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"
 
-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)
@@ -71,9 +115,66 @@ int CAGetPollingInterval(int interval)
     return interval;
 }
 
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status)
+{
+    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)
 {
-    g_networkChangeCallback = callback;
+    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()
@@ -452,7 +553,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
@@ -462,5 +563,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 cd31bec..f36778f 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 97b4981..eb3dcd0 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 e31e825..93507ca 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 476a297..d38ef07 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 5bbff11..bd63d98 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 8b39412..381b67c 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__
     CAAdapterNetDtlsInit();
 
@@ -278,7 +277,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
@@ -412,7 +411,7 @@ CAResult_t CAStopIP()
     }
 #endif
 
-    CAIPStopNetworkMonitor();
+    CAIPStopNetworkMonitor(CA_ADAPTER_IP);
     CAIPStopServer();
     //Re-initializing the Globals to start them again
     CAInitializeIPGlobals();
index 474e694..281a618 100644 (file)
@@ -59,6 +59,7 @@
 
 #include <coap/pdu.h>
 #include "caipinterface.h"
+#include "caipnwmonitor.h"
 #include "caadapterutils.h"
 #ifdef __WITH_DTLS__
 #include "caadapternetdtls.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 a839ab9..d7cb718 100644 (file)
 #include <linux/rtnetlink.h>
 #endif
 
+#include "caipnwmonitor.h"
 #include "octhread.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 oc_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)
         {
             oc_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 3635f15..a141c3b 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);
+
+/**
+ * Used to passing the network status changes to adapter.
+ */
+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 +92,66 @@ int CAGetPollingInterval(int interval)
     return interval;
 }
 
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status)
+{
+    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)
 {
-    g_networkChangeCallback = callback;
+    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 +214,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)
+    if (!g_adapterCallbackList)
     {
-        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;
+        // 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;
+       }
     }
 
-    // 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 +426,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 7d3088f..353beca 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 afe653f..082bd19 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;
@@ -290,7 +320,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;
 
@@ -308,7 +341,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)
@@ -422,11 +454,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();
@@ -443,11 +478,8 @@ CAResult_t CAStopTCP()
 
 void CATerminateTCP()
 {
+    CAStopTCP();
     CATCPSetPacketReceiveCallback(NULL);
-
-#ifndef SINGLE_THREAD
-    CATCPDeinitializeQueueHandles();
-#endif
 }
 
 void CATCPSendDataThread(void *threadData)
index 6ebccc6..dfdf6a7 100644 (file)
@@ -38,7 +38,7 @@
 #endif
 
 #include "catcpinterface.h"
-#include "caipinterface.h"
+#include "caipnwmonitor.h"
 #include <coap/pdu.h>
 #include "caadapterutils.h"
 #include "octhread.h"
@@ -1239,14 +1239,23 @@ void CATCPDisconnectAll()
         svritem = (CATCPSessionInfo_t *) u_arraylist_get(caglobals.tcp.svrlist, i);
         if (svritem && svritem->fd >= 0)
         {
+#ifdef __WITH_TLS__
+            CAcloseTlsConnection(&svritem->sep.endpoint);
+#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;
     oc_mutex_unlock(g_mutexObjectList);
 }