IP adapter error handling
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / ip_adapter / caipserver.c
index 35e4c77..e78936b 100644 (file)
@@ -77,6 +77,7 @@ typedef struct
     ca_thread_pool_t threadPool;
     CAIPPacketReceivedCallback packetReceivedCallback;
     CAIPExceptionCallback exceptionCallback;
+    CAIPErrorHandleCallback IPErrorCallback;
 } CAAdapterIPServerContext_t;
 
 /**
@@ -92,10 +93,10 @@ static u_arraylist_t *g_serverInfoList = NULL;
 static ca_mutex g_mutexServerInfoList = NULL;
 
 /**
- * @var g_adapterEthServerContext
+ * @var g_adapterIPServerContext
  * @brief Mutex to synchronize ethenet adapter context.
  */
-static CAAdapterIPServerContext_t *g_adapterEthServerContext = NULL;
+static CAAdapterIPServerContext_t *g_adapterIPServerContext = NULL;
 
 /**
  * @var g_mutexAdapterServerContext
@@ -205,7 +206,7 @@ static void CAReceiveHandler(void *data)
             {
                 OIC_LOG_V(ERROR, IP_SERVER_TAG,
                           "data Received server information ip %s, port %d socket %d",
-                          info->ipAddress, info->port, sd);
+                          info->endpoint.addr, info->endpoint.port, sd);
                 memset(recvBuffer, 0, sizeof(recvBuffer));
 
                 struct sockaddr_in srcSockAddress = { 0 };
@@ -224,10 +225,10 @@ static void CAReceiveHandler(void *data)
                     OIC_LOG_V(ERROR, IP_SERVER_TAG, "Server socket shutdown sock fd[%d]", sd);
                     ca_mutex_lock(g_mutexAdapterServerContext);
                     // Notify upper layer this exception
-                    if (g_adapterEthServerContext->exceptionCallback)
+                    if (g_adapterIPServerContext->exceptionCallback)
                     {
                         // need to make proper exception callback.
-                        //g_adapterEthServerContext->exceptionCallback(ctx->type);
+                        //g_adapterIPServerContext->exceptionCallback(ctx->type);
                     }
                     ca_mutex_unlock(g_mutexAdapterServerContext);
                 }
@@ -262,12 +263,17 @@ static void CAReceiveHandler(void *data)
                 }
                 OICFree(netMask);
 
-                if (info->isSecured)
+                CAEndpoint_t ep;
+                strncpy(ep.addr, srcIPAddress, MAX_ADDR_STR_SIZE_CA);
+                ep.port = srcPort;
+                ep.flags = CA_IPV4;
+                ep.adapter = CA_ADAPTER_IP;
+
+                if (info->endpoint.flags & CA_SECURE)
                 {
 #ifdef __WITH_DTLS__
-                    CAResult_t ret = CAAdapterNetDtlsDecrypt(srcIPAddress, srcPort,
-                                                             (uint8_t *)recvBuffer, recvLen,
-                                                             CA_IPV4);
+                    ep.flags |= CA_SECURE;
+                    (void)CAAdapterNetDtlsDecrypt(&ep, (uint8_t *)recvBuffer, recvLen);
                     OIC_LOG_V(DEBUG, IP_SERVER_TAG,
                               "CAAdapterNetDtlsDecrypt returns [%d]", ret);
 #endif
@@ -276,11 +282,10 @@ static void CAReceiveHandler(void *data)
                 {
                     ca_mutex_lock(g_mutexAdapterServerContext);
 
-                    if (g_adapterEthServerContext->packetReceivedCallback)
+                    if (g_adapterIPServerContext->packetReceivedCallback)
                     {
-                        g_adapterEthServerContext->packetReceivedCallback(srcIPAddress, srcPort,
-                                                                          recvBuffer, recvLen,
-                                                                          false, NULL);
+                        g_adapterIPServerContext->packetReceivedCallback(&ep,
+                                                          recvBuffer, recvLen);
                     }
 
                     ca_mutex_unlock(g_mutexAdapterServerContext);
@@ -292,8 +297,7 @@ static void CAReceiveHandler(void *data)
     OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
 }
 
-static CAResult_t CACreateSocket(int *socketFD, const char *localIp, uint16_t *port,
-                                 bool forceBindStart)
+static CAResult_t CACreateSocket(int *socketFD, const char *localIp, uint16_t *port)
 {
     VERIFY_NON_NULL(socketFD, IP_SERVER_TAG, "socketFD is NULL");
     VERIFY_NON_NULL(localIp, IP_SERVER_TAG, "localIp is NULL");
@@ -327,7 +331,7 @@ static CAResult_t CACreateSocket(int *socketFD, const char *localIp, uint16_t *p
         return CA_STATUS_FAILED;
     }
 
-    if (true == forceBindStart)
+    if (0 != *port)
     {
         int setOptionOn = SOCKETOPTION;
         if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &setOptionOn,
@@ -349,36 +353,27 @@ static CAResult_t CACreateSocket(int *socketFD, const char *localIp, uint16_t *p
         sockAddr.sin_addr.s_addr = inet_addr(localIp);
     }
 
-    int16_t i = 0;
-    bool isBound = false;
-    for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
+    if (-1 != bind(sock, (struct sockaddr *) &sockAddr, sizeof(sockAddr)))
     {
-        if (-1 == bind(sock, (struct sockaddr *) &sockAddr, sizeof(sockAddr)))
-        {
-            if (false == forceBindStart)
-            {
-                OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to bind socket[%s]. Trying again..",
-                          strerror(errno));
+        struct sockaddr_in sin;
+        socklen_t len = sizeof(sin);
 
-                //Set the port to next one
-                serverPort += 1;
-                sockAddr.sin_port = htons(serverPort);
-                continue;
-            }
-            else
-            {
-                OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to bind socket[%s]!",
-                          strerror(errno));
-                break;
-            }
+        if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
+        {
+            OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to get socket[%s]!",
+                      strerror(errno));
+            close(sock);
+            return CA_STATUS_FAILED;
+        }
+        else
+        {
+            serverPort = (uint16_t) ntohs(sin.sin_port);
         }
-
-        isBound = true;
-        break;
     }
-
-    if (false == isBound)
+    else
     {
+        OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to bind socket[%s]!",
+                  strerror(errno));
         close(sock);
         return CA_STATUS_FAILED;
     }
@@ -405,7 +400,7 @@ static void CACloseSocket(int socketFD)
 }
 
 static CAResult_t CAStartUnicastServer(const char *localAddress, uint16_t *port,
-                                       bool forceBindStart, bool isSecured, int *serverFD)
+                                       bool isSecured, int *serverFD)
 {
     OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
 
@@ -413,7 +408,7 @@ static CAResult_t CAStartUnicastServer(const char *localAddress, uint16_t *port,
     VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
     VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
 
-    CAResult_t ret = CACreateSocket(serverFD, localAddress, port, forceBindStart);
+    CAResult_t ret = CACreateSocket(serverFD, localAddress, port);
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create unicast socket");
@@ -435,9 +430,9 @@ static CAResult_t CAIPStartPacketReceiverHandler()
 
     ca_mutex_lock(g_mutexAdapterServerContext);
 
-    if (!g_adapterEthServerContext)
+    if (!g_adapterIPServerContext)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
+        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
         ca_mutex_unlock(g_mutexAdapterServerContext);
         return CA_STATUS_FAILED;
     }
@@ -445,7 +440,7 @@ static CAResult_t CAIPStartPacketReceiverHandler()
     if (1 == listLength) //Its first time.
     {
         g_packetHandlerStopFlag = false;
-        if (CA_STATUS_OK != ca_thread_pool_add_task(g_adapterEthServerContext->threadPool,
+        if (CA_STATUS_OK != ca_thread_pool_add_task(g_adapterIPServerContext->threadPool,
                                                    CAReceiveHandler, NULL ))
         {
             OIC_LOG(ERROR, IP_SERVER_TAG, "thread_pool_add_task failed!");
@@ -523,17 +518,17 @@ CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool)
     }
 
     ca_mutex_lock(g_mutexAdapterServerContext);
-    g_adapterEthServerContext = (CAAdapterIPServerContext_t *) OICCalloc(1,
+    g_adapterIPServerContext = (CAAdapterIPServerContext_t *) OICCalloc(1,
                                  sizeof(CAAdapterIPServerContext_t));
 
-    if (!g_adapterEthServerContext)
+    if (!g_adapterIPServerContext)
     {
         OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
         ca_mutex_unlock(g_mutexAdapterServerContext);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    g_adapterEthServerContext->threadPool = threadPool;
+    g_adapterIPServerContext->threadPool = threadPool;
 
     ca_mutex_unlock(g_mutexAdapterServerContext);
 
@@ -555,15 +550,15 @@ void CAIPTerminateServer()
 {
     OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
     ca_mutex_lock(g_mutexAdapterServerContext);
-    if (!g_adapterEthServerContext)
+    if (!g_adapterIPServerContext)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
+        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
         ca_mutex_unlock(g_mutexAdapterServerContext);
         return;
     }
 
-    OICFree(g_adapterEthServerContext);
-    g_adapterEthServerContext = NULL;
+    OICFree(g_adapterIPServerContext);
+    g_adapterIPServerContext = NULL;
 
     ca_mutex_unlock(g_mutexAdapterServerContext);
 
@@ -580,8 +575,7 @@ void CAIPTerminateServer()
 
 }
 
-CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
-                                        bool forceBindStart, bool isSecured)
+CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, bool isSecured)
 {
     OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
 
@@ -589,18 +583,12 @@ CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
     VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
     VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
 
-    if (0 >= *port)
-    {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: port is invalid!");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
     ca_mutex_lock(g_mutexServerInfoList);
     bool isUnicastServerStarted = CAIsUnicastServerStarted(g_serverInfoList, localAddress, *port);
     if (!isUnicastServerStarted)
     {
         int unicastServerFd = -1;
-        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceBindStart, isSecured,
+        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, isSecured,
                                                  &unicastServerFd))
         {
             OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to start unicast server!");
@@ -627,10 +615,11 @@ CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
             OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask);
             OICFree(netMask);
         }
-        OICStrcpy(info->ipAddress, sizeof(info->ipAddress), localAddress);
-        info->port = *port;
+        OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), localAddress);
+        info->endpoint.port = *port;
+        info->endpoint.flags = isSecured ? CA_SECURE : 0;
+        info->endpoint.adapter = CA_ADAPTER_IP;
         info->socketFd = unicastServerFd;
-        info->isSecured = isSecured;
         info->isServerStarted = true;
         info->isMulticastServer = false;
         OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress);
@@ -686,7 +675,7 @@ CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multic
     if (!isMulticastServerStarted)
     {
         int mulicastServerFd = -1;
-        CAResult_t ret = CACreateSocket(&mulicastServerFd, multicastAddress, &port, true);
+        CAResult_t ret = CACreateSocket(&mulicastServerFd, multicastAddress, &port);
         if (ret != CA_STATUS_OK)
         {
             OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create multicast socket");
@@ -727,10 +716,10 @@ CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multic
             OICFree(netMask);
         }
 
-        OICStrcpy(info->ipAddress, sizeof(info->ipAddress), multicastAddress);
-        info->port = multicastPort;
+        OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), multicastAddress);
+        info->endpoint.port = multicastPort;
+        info->endpoint.flags = 0;
         info->socketFd = mulicastServerFd;
-        info->isSecured = false;
         info->isServerStarted = true;
         info->isMulticastServer = true;
         OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress);
@@ -792,7 +781,7 @@ CAResult_t CAIPStopServer(const char *interfaceAddress)
                 struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
 
                 multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
-                inet_aton(info->ipAddress, &multicastMemberReq.imr_multiaddr);
+                inet_aton(info->endpoint.addr, &multicastMemberReq.imr_multiaddr);
                 if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
                                      (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
                 {
@@ -812,7 +801,7 @@ CAResult_t CAIPStopServer(const char *interfaceAddress)
                 return CA_STATUS_FAILED;
             }
         }
-        else if (strncmp(interfaceAddress, info->ipAddress, strlen(info->ipAddress)) == 0)
+        else if (strncmp(interfaceAddress, info->endpoint.addr, strlen(info->endpoint.addr)) == 0)
         {
             if (u_arraylist_remove(g_serverInfoList, listIndex))
             {
@@ -865,7 +854,7 @@ CAResult_t CAIPStopAllServers()
                 struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
 
                 multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
-                inet_aton(info->ipAddress, &multicastMemberReq.imr_multiaddr);
+                inet_aton(info->endpoint.addr, &multicastMemberReq.imr_multiaddr);
                 if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
                                      (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
                 {
@@ -948,13 +937,30 @@ void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
 
     ca_mutex_lock(g_mutexAdapterServerContext);
 
-    if (!g_adapterEthServerContext)
+    if (g_adapterIPServerContext)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
-        ca_mutex_unlock(g_mutexAdapterServerContext);
-        return;
+        g_adapterIPServerContext->packetReceivedCallback = callback;
+    }
+    else
+    {
+        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
+    }
+
+    ca_mutex_unlock(g_mutexAdapterServerContext);
+
+    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
+}
+
+void CAIPSetErrorHandleCallback(CAIPErrorHandleCallback ipErrorCallback)
+{
+    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
+
+    ca_mutex_lock(g_mutexAdapterServerContext);
+
+    if (g_adapterIPServerContext)
+    {
+        g_adapterIPServerContext->IPErrorCallback = ipErrorCallback;
     }
-    g_adapterEthServerContext->packetReceivedCallback = callback;
 
     ca_mutex_unlock(g_mutexAdapterServerContext);
 
@@ -966,13 +972,14 @@ void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
     OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
     ca_mutex_lock(g_mutexAdapterServerContext);
 
-    if (!g_adapterEthServerContext)
+    if (g_adapterIPServerContext)
     {
-        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
-        ca_mutex_unlock(g_mutexAdapterServerContext);
-        return;
+        g_adapterIPServerContext->exceptionCallback = callback;
+    }
+    else
+    {
+        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
     }
-    g_adapterEthServerContext->exceptionCallback = callback;
 
     ca_mutex_unlock(g_mutexAdapterServerContext);