Update snapshot(2017-12-14)
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / ip_adapter / caipadapter.c
index 2528db8..d6b1b89 100644 (file)
 #include <string.h>
 #include <stdint.h>
 
+#include "caipnwmonitor.h"
 #include "caipinterface.h"
 #include "caqueueingthread.h"
 #include "caadapterutils.h"
 #ifdef __WITH_DTLS__
-#include "caadapternetdtls.h"
+#include "ca_adapter_net_ssl.h"
+#ifdef WITH_TCP
+#include "catcpinterface.h"
 #endif
-#include "camutex.h"
+#endif
+
+#include "octhread.h"
 #include "uarraylist.h"
 #include "caremotehandler.h"
 #include "logger.h"
@@ -40,7 +45,7 @@
 /**
  * Logging tag for module name.
  */
-#define TAG "IP_ADAP"
+#define TAG "OIC_CA_IP_ADAP"
 
 #ifndef SINGLE_THREAD
 /**
@@ -52,7 +57,7 @@ typedef struct
     void *data;
     uint32_t dataLen;
     bool isMulticast;
-} CAIPData;
+} CAIPData_t;
 
 /**
  * Queue handle for Send Data.
@@ -68,18 +73,18 @@ static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
 /**
  * Network Changed Callback to CA.
  */
-static CANetworkChangeCallback g_networkChangeCallback = NULL;
+static CAAdapterChangeCallback g_networkChangeCallback = NULL;
 
 /**
  * error Callback to CA adapter.
  */
 static CAErrorHandleCallback g_errorCallback = NULL;
 
-static void CAIPPacketReceivedCB(const CASecureEndpoint_t *endpoint,
-                                 const void *data, uint32_t dataLength);
+static CAResult_t CAIPPacketReceivedCB(const CASecureEndpoint_t *endpoint,
+                                       const void *data, size_t dataLength);
 #ifdef __WITH_DTLS__
-static void CAIPPacketSendCB(CAEndpoint_t *endpoint,
-                             const void *data, uint32_t dataLength);
+static ssize_t CAIPPacketSendCB(CAEndpoint_t *endpoint,
+                                const void *data, size_t dataLength);
 #endif
 
 #ifndef SINGLE_THREAD
@@ -90,17 +95,16 @@ static void CAIPDeinitializeQueueHandles();
 
 static void CAIPSendDataThread(void *threadData);
 
-static CAIPData *CACreateIPData(const CAEndpoint_t *remoteEndpoint,
-                                const void *data, uint32_t dataLength,
-                                bool isMulticast);
-void CAFreeIPData(CAIPData *ipData);
+static CAIPData_t *CACreateIPData(const CAEndpoint_t *remoteEndpoint,
+                                  const void *data, uint32_t dataLength,
+                                  bool isMulticast);
+
+void CAFreeIPData(CAIPData_t *ipData);
 
 static void CADataDestroyer(void *data, uint32_t size);
 
 CAResult_t CAIPInitializeQueueHandles()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     // Check if the message queue is already initialized
     if (g_sendQueueHandle)
     {
@@ -126,88 +130,91 @@ CAResult_t CAIPInitializeQueueHandles()
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 void CAIPDeinitializeQueueHandles()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     CAQueueingThreadDestroy(g_sendQueueHandle);
     OICFree(g_sendQueueHandle);
     g_sendQueueHandle = NULL;
-
-    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
 #endif // SINGLE_THREAD
 
-void CAIPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status)
+void CAIPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
 {
-    (void)ipAddress;
-    (void)status;
-    OIC_LOG(DEBUG, TAG, "IN");
+    if (g_networkChangeCallback)
+    {
+        g_networkChangeCallback(adapter, status);
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "g_networkChangeCallback is NULL");
+    }
+
+    if (CA_INTERFACE_DOWN == status)
+    {
+        OIC_LOG(DEBUG, TAG, "Network status for IP is down");
+
+        CAResult_t res = CAQueueingThreadClearData(g_sendQueueHandle);
+        if (res != CA_STATUS_OK)
+        {
+            OIC_LOG_V(ERROR, TAG, "CAQueueingThreadClearData failed[%d]", res);
+        }
+
+#ifdef __WITH_DTLS__
+#ifdef WITH_TCP
+        CATCPCloseInProgressConnections();
+#endif
+        OIC_LOG(DEBUG, TAG, "close all ssl session");
+        CAcloseSslConnectionAll(CA_ADAPTER_IP);
+#endif
+    }
 }
 
 #ifdef __WITH_DTLS__
-static void CAIPPacketSendCB(CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
+static ssize_t CAIPPacketSendCB(CAEndpoint_t *endpoint, const void *data, size_t dataLength)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");
-    VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
+    VERIFY_NON_NULL_RET(endpoint, TAG, "endpoint is NULL", -1);
+    VERIFY_NON_NULL_RET(data, TAG, "data is NULL", -1);
 
     CAIPSendData(endpoint, data, dataLength, false);
-
-    OIC_LOG(DEBUG, TAG, "OUT");
+    return dataLength;
 }
 #endif
 
 
-void CAIPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
-                          uint32_t dataLength)
+CAResult_t CAIPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
+                                size_t dataLength)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    VERIFY_NON_NULL_VOID(sep, TAG, "sep is NULL");
-    VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
+    VERIFY_NON_NULL(sep, TAG, "sep is NULL");
+    VERIFY_NON_NULL(data, TAG, "data is NULL");
 
     OIC_LOG_V(DEBUG, TAG, "Address: %s, port:%d", sep->endpoint.addr, sep->endpoint.port);
 
+    CAResult_t res = CA_STATUS_OK;
     if (g_networkPacketCallback)
     {
-        g_networkPacketCallback(sep, data, dataLength);
+        res = g_networkPacketCallback(sep, data, dataLength);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "Error parsing CoAP data");
+        }
     }
-    OIC_LOG(DEBUG, TAG, "OUT");
+    return res;
 }
 
-void CAIPErrorHandler (const CAEndpoint_t *endpoint, const void *data,
-                       uint32_t dataLength, CAResult_t result)
+void CAIPErrorHandler(const CAEndpoint_t *endpoint, const void *data,
+                      uint32_t dataLength, CAResult_t result)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");
-
     VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
 
-    void *buf = (void*)OICMalloc(sizeof(char) * dataLength);
-    if (!buf)
-    {
-        OIC_LOG(ERROR, TAG, "Memory Allocation failed!");
-        return;
-    }
-    memcpy(buf, data, dataLength);
     if (g_errorCallback)
     {
-        g_errorCallback(endpoint, buf, dataLength, result);
+        g_errorCallback(endpoint, data, dataLength, result);
     }
-    else
-    {
-        OICFree(buf);
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
 static void CAInitializeIPGlobals()
@@ -238,14 +245,17 @@ static void CAInitializeIPGlobals()
     {
         flags |= caglobals.serverFlags;
     }
+//TODO Enable once TizenRT supports IPv6
+#ifndef __TIZENRT__
     caglobals.ip.ipv6enabled = flags & CA_IPV6;
+#endif
     caglobals.ip.ipv4enabled = flags & CA_IPV4;
     caglobals.ip.dualstack = caglobals.ip.ipv6enabled && caglobals.ip.ipv4enabled;
 }
 
 CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
                           CANetworkPacketReceivedCallback networkPacketCallback,
-                          CANetworkChangeCallback netCallback,
+                          CAAdapterChangeCallback netCallback,
                           CAErrorHandleCallback errorCallback, ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TAG, "IN");
@@ -263,24 +273,28 @@ CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
     CAInitializeIPGlobals();
     caglobals.ip.threadpool = handle;
 
+    CAIPSetErrorHandler(CAIPErrorHandler);
     CAIPSetPacketReceiveCallback(CAIPPacketReceivedCB);
-#ifdef __WITH_DTLS__
-    CAAdapterNetDtlsInit();
 
-    CADTLSSetAdapterCallbacks(CAIPPacketReceivedCB, CAIPPacketSendCB, 0);
+#ifdef __WITH_DTLS__
+    CAsetSslAdapterCallbacks(CAIPPacketReceivedCB, CAIPPacketSendCB, CA_ADAPTER_IP);
 #endif
 
-    CAConnectivityHandler_t ipHandler;
-    ipHandler.startAdapter = CAStartIP;
-    ipHandler.startListenServer = CAStartIPListeningServer;
-    ipHandler.startDiscoveryServer = CAStartIPDiscoveryServer;
-    ipHandler.sendData = CASendIPUnicastData;
-    ipHandler.sendDataToAll = CASendIPMulticastData;
-    ipHandler.GetnetInfo = CAGetIPInterfaceInformation;
-    ipHandler.readData = CAReadIPData;
-    ipHandler.stopAdapter = CAStopIP;
-    ipHandler.terminate = CATerminateIP;
-    registerCallback(ipHandler, CA_ADAPTER_IP);
+    static const CAConnectivityHandler_t ipHandler =
+        {
+            .startAdapter = CAStartIP,
+            .stopAdapter = CAStopIP,
+            .startListenServer = CAStartIPListeningServer,
+            .stopListenServer = CAStopIPListeningServer,
+            .startDiscoveryServer = CAStartIPDiscoveryServer,
+            .sendData = CASendIPUnicastData,
+            .sendDataToAll = CASendIPMulticastData,
+            .GetnetInfo = CAGetIPInterfaceInformation,
+            .readData = CAReadIPData,
+            .terminate = CATerminateIP,
+            .cType = CA_ADAPTER_IP
+        };
+    registerCallback(ipHandler);
 
     OIC_LOG(INFO, TAG, "OUT IntializeIP is Success");
     return CA_STATUS_OK;
@@ -288,9 +302,13 @@ CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
 
 CAResult_t CAStartIP()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
+    // Specific the port number received from application.
+    caglobals.ip.u6.port  = caglobals.ports.udp.u6;
+    caglobals.ip.u6s.port = caglobals.ports.udp.u6s;
+    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
@@ -309,7 +327,11 @@ CAResult_t CAStartIP()
     }
 
     // Start send queue thread
+#ifndef __TIZENRT__
     if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle))
+#else
+    if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle, "IoT_IPSendQueue"))
+#endif
     {
         OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
         return CA_STATUS_FAILED;
@@ -324,29 +346,40 @@ CAResult_t CAStartIP()
 
 #endif
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 CAResult_t CAStartIPListeningServer()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
+    CAResult_t ret = CAIPStartListenServer();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to start listening server![%d]", ret);
+        return ret;
+    }
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
+CAResult_t CAStopIPListeningServer()
+{
+    CAResult_t ret = CAIPStopListenServer();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to stop listening server![%d]", ret);
+    }
+
+    return ret;
+}
+
 CAResult_t CAStartIPDiscoveryServer()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
     return CAStartIPListeningServer();
 }
 
 static int32_t CAQueueIPData(bool isMulticast, const CAEndpoint_t *endpoint,
-                            const void *data, uint32_t dataLength)
+                             const void *data, uint32_t dataLength)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     VERIFY_NON_NULL_RET(endpoint, TAG, "remoteEndpoint", -1);
     VERIFY_NON_NULL_RET(data, TAG, "data", -1);
 
@@ -365,72 +398,62 @@ static int32_t CAQueueIPData(bool isMulticast, const CAEndpoint_t *endpoint,
 
     VERIFY_NON_NULL_RET(g_sendQueueHandle, TAG, "sendQueueHandle", -1);
     // Create IPData to add to queue
-    CAIPData *ipData = CACreateIPData(endpoint, data, dataLength, isMulticast);
+    CAIPData_t *ipData = CACreateIPData(endpoint, data, dataLength, isMulticast);
     if (!ipData)
     {
         OIC_LOG(ERROR, TAG, "Failed to create ipData!");
         return -1;
     }
     // Add message to send queue
-    CAQueueingThreadAddData(g_sendQueueHandle, ipData, sizeof(CAIPData));
+    CAQueueingThreadAddData(g_sendQueueHandle, ipData, sizeof(CAIPData_t));
 
 #endif // SINGLE_THREAD
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return dataLength;
 }
 
 int32_t CASendIPUnicastData(const CAEndpoint_t *endpoint,
-                            const void *data, uint32_t dataLength)
+                            const void *data, uint32_t dataLength,
+                            CADataType_t dataType)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
+    (void)dataType;
     return CAQueueIPData(false, endpoint, data, dataLength);
 }
 
-int32_t CASendIPMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
+int32_t CASendIPMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength,
+                              CADataType_t dataType)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
+    (void)dataType;
     return CAQueueIPData(true, endpoint, data, dataLength);
 }
 
 CAResult_t CAReadIPData()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
     CAIPPullData();
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 CAResult_t CAStopIP()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
-#ifdef __WITH_DTLS__
-    CAAdapterNetDtlsDeInit();
-#endif
-
 #ifndef SINGLE_THREAD
     if (g_sendQueueHandle && g_sendQueueHandle->threadMutex)
     {
         CAQueueingThreadStop(g_sendQueueHandle);
     }
-
-    CAIPDeinitializeQueueHandles();
 #endif
 
-    CAIPStopNetworkMonitor();
+    CAIPStopNetworkMonitor(CA_ADAPTER_IP);
     CAIPStopServer();
+    //Re-initializing the Globals to start them again
+    CAInitializeIPGlobals();
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 void CATerminateIP()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
 #ifdef __WITH_DTLS__
-    CADTLSSetAdapterCallbacks(NULL, NULL, 0);
+    CAsetSslAdapterCallbacks(NULL, NULL, CA_ADAPTER_IP);
 #endif
 
     CAIPSetPacketReceiveCallback(NULL);
@@ -438,17 +461,13 @@ void CATerminateIP()
 #ifndef SINGLE_THREAD
     CAIPDeinitializeQueueHandles();
 #endif
-
-    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
 #ifndef SINGLE_THREAD
 
 void CAIPSendDataThread(void *threadData)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    CAIPData *ipData = (CAIPData *) threadData;
+    CAIPData_t *ipData = (CAIPData_t *) threadData;
     if (!ipData)
     {
         OIC_LOG(DEBUG, TAG, "Invalid ip data!");
@@ -465,17 +484,15 @@ void CAIPSendDataThread(void *threadData)
     {
         //Processing for sending unicast
 #ifdef __WITH_DTLS__
-        if (ipData->remoteEndpoint->flags & CA_SECURE)
+        if (ipData->remoteEndpoint && ipData->remoteEndpoint->flags & CA_SECURE)
         {
-            OIC_LOG(DEBUG, TAG, "CAAdapterNetDtlsEncrypt called!");
-            CAResult_t result = CAAdapterNetDtlsEncrypt(ipData->remoteEndpoint,
-                                               ipData->data, ipData->dataLen);
+            OIC_LOG(INFO, TAG, "DTLS encrypt called");
+            CAResult_t result = CAencryptSsl(ipData->remoteEndpoint, ipData->data, ipData->dataLen);
             if (CA_STATUS_OK != result)
             {
-                OIC_LOG(ERROR, TAG, "CAAdapterNetDtlsEncrypt failed!");
+                OIC_LOG(ERROR, TAG, "CAencryptSsl failed!");
             }
-            OIC_LOG_V(DEBUG, TAG,
-                      "CAAdapterNetDtlsEncrypt returned with result[%d]", result);
+            OIC_LOG_V(INFO, TAG, "CAencryptSsl returned with result[%d]", result);
         }
         else
         {
@@ -486,20 +503,18 @@ void CAIPSendDataThread(void *threadData)
         CAIPSendData(ipData->remoteEndpoint, ipData->data, ipData->dataLen, false);
 #endif
     }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
 #endif
 
 #ifndef SINGLE_THREAD
-
-CAIPData *CACreateIPData(const CAEndpoint_t *remoteEndpoint, const void *data,
-                                     uint32_t dataLength, bool isMulticast)
+CAIPData_t *CACreateIPData(const CAEndpoint_t *remoteEndpoint, const void *data,
+                           uint32_t dataLength, bool isMulticast)
 {
+    VERIFY_NON_NULL_RET(remoteEndpoint, TAG, "remoteEndpoint is NULL", NULL);
     VERIFY_NON_NULL_RET(data, TAG, "IPData is NULL", NULL);
 
-    CAIPData *ipData = (CAIPData *) OICMalloc(sizeof(CAIPData));
+    CAIPData_t *ipData = (CAIPData_t *) OICMalloc(sizeof(*ipData));
     if (!ipData)
     {
         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
@@ -523,7 +538,7 @@ CAIPData *CACreateIPData(const CAEndpoint_t *remoteEndpoint, const void *data,
     return ipData;
 }
 
-void CAFreeIPData(CAIPData *ipData)
+void CAFreeIPData(CAIPData_t *ipData)
 {
     VERIFY_NON_NULL_VOID(ipData, TAG, "ipData is NULL");
 
@@ -534,11 +549,11 @@ void CAFreeIPData(CAIPData *ipData)
 
 void CADataDestroyer(void *data, uint32_t size)
 {
-    if (size < sizeof(CAIPData))
+    if (size < sizeof(CAIPData_t))
     {
         OIC_LOG_V(ERROR, TAG, "Destroy data too small %p %d", data, size);
     }
-    CAIPData *etdata = (CAIPData *) data;
+    CAIPData_t *etdata = (CAIPData_t *) data;
 
     CAFreeIPData(etdata);
 }