1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
21 #include "caipinterface.h"
23 #include <sys/types.h>
24 #include <sys/socket.h>
27 #include <sys/select.h>
28 #include <arpa/inet.h>
29 #include <netinet/in.h>
33 #include "caadapterutils.h"
35 #include "caadapternetdtls.h"
38 #include "oic_malloc.h"
42 * @brief Logging tag for module name
44 #define IP_SERVER_TAG "IP_SERVER"
47 * @def CA_UDP_BIND_RETRY_COUNT
48 * @brief Retry count in case of socket bind failure.
50 #define CA_UDP_BIND_RETRY_COUNT 10
54 * @brief Max length for ip address.
60 * @brief Socket option.
62 #define SOCKETOPTION 1
65 * @var g_packetHandlerStopFlag
66 * @brief Flag for stopping packet handler thread.
68 static bool g_packetHandlerStopFlag = false;
71 * @var CAAdapterIPServerContext_t
72 * @brief Thread context information for callbacks and threadpool.
76 ca_thread_pool_t threadPool;
77 CAIPPacketReceivedCallback packetReceivedCallback;
78 CAIPExceptionCallback exceptionCallback;
79 } CAAdapterIPServerContext_t;
82 * @var g_serverInfoList
83 * @brief Mutex to synchronize ethenet adapter context.
85 static u_arraylist_t *g_serverInfoList = NULL;
88 * @var g_mutexServerInfoList
89 * @brief Mutex to synchronize Server Information.
91 static ca_mutex g_mutexServerInfoList = NULL;
94 * @var g_adapterEthServerContext
95 * @brief Mutex to synchronize ethenet adapter context.
97 static CAAdapterIPServerContext_t *g_adapterEthServerContext = NULL;
100 * @var g_mutexAdapterServerContext
101 * @brief Mutex to synchronize unicast server
103 static ca_mutex g_mutexAdapterServerContext = NULL;
105 static void CAReceiveHandler(void *data)
107 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
111 struct timeval timeout;
112 char recvBuffer[COAP_MAX_PDU_SIZE] = { 0 };
114 while (true != g_packetHandlerStopFlag)
120 ca_mutex_lock(g_mutexServerInfoList);
121 uint32_t listIndex = 0;
122 uint32_t listLength = u_arraylist_length(g_serverInfoList);
124 u_arraylist_t *tempServerInfoList = u_arraylist_create();
125 if (!tempServerInfoList)
127 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_create failed");
128 ca_mutex_unlock(g_mutexServerInfoList);
132 for (listIndex = 0; listIndex < listLength; listIndex++)
134 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
141 int sd = info->socketFd;
142 //if valid socket descriptor then add to read list
145 FD_SET(sd, &readFds);
148 //highest file descriptor number, need it for the select function
154 CAServerInfo_t *newInfo = (CAServerInfo_t *) OICMalloc(sizeof(CAServerInfo_t));
157 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
158 CAClearServerInfoList(tempServerInfoList);
159 ca_mutex_unlock(g_mutexServerInfoList);
163 memcpy(newInfo, info, sizeof(CAServerInfo_t));
165 CAResult_t result = u_arraylist_add(tempServerInfoList, (void *) newInfo);
166 if (CA_STATUS_OK != result)
168 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_add failed!Thread exit");
169 CAClearServerInfoList(tempServerInfoList);
170 ca_mutex_unlock(g_mutexServerInfoList);
175 ca_mutex_unlock(g_mutexServerInfoList);
177 int ret = select(maxSd + 1, &readFds, NULL, NULL, &timeout);
178 if (g_packetHandlerStopFlag)
180 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
181 "Packet receiver handler Stop request received. Thread exited");
182 CAClearServerInfoList(tempServerInfoList);
187 OIC_LOG_V(FATAL, IP_SERVER_TAG, "select returned error %s", strerror(errno));
188 CAClearServerInfoList(tempServerInfoList);
192 listLength = u_arraylist_length(tempServerInfoList);
193 for (listIndex = 0; listIndex < listLength; listIndex++)
195 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(tempServerInfoList,
202 int sd = info->socketFd;
203 if (FD_ISSET(sd , &readFds))
205 OIC_LOG_V(ERROR, IP_SERVER_TAG,
206 "data Received server information ip %s, port %d socket %d",
207 info->ipAddress, info->port, sd);
208 memset(recvBuffer, 0, sizeof(recvBuffer));
210 struct sockaddr_in srcSockAddress = { 0 };
211 socklen_t srcAddressLen = sizeof(srcSockAddress);
213 //Reading from socket
214 ssize_t recvLen = recvfrom(sd, recvBuffer, sizeof(recvBuffer), 0,
215 (struct sockaddr *) &srcSockAddress, &srcAddressLen);
218 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Recvfrom failed %s", strerror(errno));
221 else if (0 == recvLen)
223 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Server socket shutdown sock fd[%d]", sd);
224 ca_mutex_lock(g_mutexAdapterServerContext);
225 // Notify upper layer this exception
226 if (g_adapterEthServerContext->exceptionCallback)
228 // need to make proper exception callback.
229 //g_adapterEthServerContext->exceptionCallback(ctx->type);
231 ca_mutex_unlock(g_mutexAdapterServerContext);
234 char srcIPAddress[CA_IPADDR_SIZE] = { 0 };
235 if (!inet_ntop(AF_INET, &srcSockAddress.sin_addr.s_addr, srcIPAddress,
236 sizeof(srcIPAddress)))
239 OIC_LOG(ERROR, IP_SERVER_TAG, "inet_ntop is failed!");
243 uint16_t srcPort = ntohs(srcSockAddress.sin_port);
245 OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Received packet from %s:%d len %d",
246 srcIPAddress, srcPort, recvLen);
248 char *netMask = NULL;
249 if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(info->ifAddr, &netMask))
251 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
255 if (!CAAdapterIsSameSubnet(info->ifAddr, srcIPAddress, netMask))
257 OIC_LOG(DEBUG, IP_SERVER_TAG,
258 "Packet received from different subnet, Ignore!");
267 CAResult_t ret = CAAdapterNetDtlsDecrypt(srcIPAddress, srcPort,
268 (uint8_t *)recvBuffer, recvLen,
270 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
271 "CAAdapterNetDtlsDecrypt returns [%d]", ret);
274 else //both multicast and unicast
276 ca_mutex_lock(g_mutexAdapterServerContext);
278 if (g_adapterEthServerContext->packetReceivedCallback)
280 g_adapterEthServerContext->packetReceivedCallback(srcIPAddress, srcPort,
285 ca_mutex_unlock(g_mutexAdapterServerContext);
289 CAClearServerInfoList(tempServerInfoList);
291 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
294 static CAResult_t CACreateSocket(int *socketFD, const char *localIp, uint16_t *port,
297 VERIFY_NON_NULL(socketFD, IP_SERVER_TAG, "socketFD is NULL");
298 VERIFY_NON_NULL(localIp, IP_SERVER_TAG, "localIp is NULL");
299 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port is NULL");
300 // Create a UDP socket
304 sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
309 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
314 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to create Socket, Error code: %s",
316 return CA_STATUS_FAILED;
319 // Make the socket non-blocking
320 if (-1 == fcntl(sock, F_SETFL, O_NONBLOCK))
322 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
326 return CA_STATUS_FAILED;
329 if (true == forceBindStart)
331 int setOptionOn = SOCKETOPTION;
332 if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &setOptionOn,
333 sizeof(setOptionOn)))
335 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
338 return CA_STATUS_FAILED;
342 struct sockaddr_in sockAddr = { 0 };
343 uint16_t serverPort = *port;
344 sockAddr.sin_family = AF_INET;
345 sockAddr.sin_port = htons(serverPort);
348 sockAddr.sin_addr.s_addr = inet_addr(localIp);
352 sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
356 bool isBound = false;
357 for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
359 if (-1 == bind(sock, (struct sockaddr *) &sockAddr, sizeof(sockAddr)))
361 if (false == forceBindStart)
363 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to bind socket[%s]. Trying again..",
366 //Set the port to next one
368 sockAddr.sin_port = htons(serverPort);
373 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to bind socket[%s]!",
383 if (false == isBound)
386 return CA_STATUS_FAILED;
394 static void CACloseSocket(int socketFD)
398 OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid Socket Fd");
403 if (-1 == close(socketFD))
405 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
410 static CAResult_t CAStartUnicastServer(const char *localAddress, uint16_t *port,
411 bool forceBindStart, bool isSecured, int *serverFD)
413 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
415 VERIFY_NON_NULL(serverFD, IP_SERVER_TAG, "serverFD");
416 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
417 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
419 CAResult_t ret = CACreateSocket(serverFD, localAddress, port, forceBindStart);
420 if (CA_STATUS_OK != ret)
422 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create unicast socket");
425 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
429 static CAResult_t CAIPStartPacketReceiverHandler()
431 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
433 ca_mutex_lock(g_mutexServerInfoList);
435 uint32_t listLength = u_arraylist_length(g_serverInfoList);
437 ca_mutex_unlock(g_mutexServerInfoList);
439 ca_mutex_lock(g_mutexAdapterServerContext);
441 if (!g_adapterEthServerContext)
443 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
444 ca_mutex_unlock(g_mutexAdapterServerContext);
445 return CA_STATUS_FAILED;
448 if (1 == listLength) //Its first time.
450 g_packetHandlerStopFlag = false;
451 if (CA_STATUS_OK != ca_thread_pool_add_task(g_adapterEthServerContext->threadPool,
452 CAReceiveHandler, NULL ))
454 OIC_LOG(ERROR, IP_SERVER_TAG, "thread_pool_add_task failed!");
455 ca_mutex_unlock(g_mutexAdapterServerContext);
456 return CA_STATUS_FAILED;
458 OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread started successfully.");
462 OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread already is running");
464 ca_mutex_unlock(g_mutexAdapterServerContext);
466 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
471 static void CAIPServerDestroyMutex(void)
473 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
475 if (g_mutexServerInfoList)
477 ca_mutex_free(g_mutexServerInfoList);
478 g_mutexServerInfoList = NULL;
481 if (g_mutexAdapterServerContext)
483 ca_mutex_free(g_mutexAdapterServerContext);
484 g_mutexAdapterServerContext = NULL;
487 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
490 static CAResult_t CAIPServerCreateMutex(void)
492 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
494 g_mutexServerInfoList = ca_mutex_new();
495 if (!g_mutexServerInfoList)
497 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
498 return CA_MEMORY_ALLOC_FAILED;
501 g_mutexAdapterServerContext = ca_mutex_new();
502 if (!g_mutexAdapterServerContext)
504 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to created mutex!");
505 ca_mutex_free(g_mutexServerInfoList);
506 g_mutexServerInfoList = NULL;
507 return CA_MEMORY_ALLOC_FAILED;
510 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
514 CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool)
516 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
519 VERIFY_NON_NULL(threadPool, IP_SERVER_TAG, "Thread pool handle is NULL");
522 if (CA_STATUS_OK != CAIPServerCreateMutex())
524 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create mutex!");
525 return CA_STATUS_FAILED;
528 ca_mutex_lock(g_mutexAdapterServerContext);
529 g_adapterEthServerContext = (CAAdapterIPServerContext_t *) OICCalloc(1,
530 sizeof(CAAdapterIPServerContext_t));
532 if (!g_adapterEthServerContext)
534 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
535 ca_mutex_unlock(g_mutexAdapterServerContext);
536 return CA_MEMORY_ALLOC_FAILED;
539 g_adapterEthServerContext->threadPool = threadPool;
541 ca_mutex_unlock(g_mutexAdapterServerContext);
543 ca_mutex_lock(g_mutexServerInfoList);
545 g_serverInfoList = u_arraylist_create();
546 if (!g_serverInfoList)
548 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_create failed");
549 ca_mutex_unlock(g_mutexServerInfoList);
550 return CA_MEMORY_ALLOC_FAILED;
552 ca_mutex_unlock(g_mutexServerInfoList);
553 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
557 void CAIPTerminateServer()
559 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
560 ca_mutex_lock(g_mutexAdapterServerContext);
561 if (!g_adapterEthServerContext)
563 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
564 ca_mutex_unlock(g_mutexAdapterServerContext);
568 OICFree(g_adapterEthServerContext);
569 g_adapterEthServerContext = NULL;
571 ca_mutex_unlock(g_mutexAdapterServerContext);
573 ca_mutex_lock(g_mutexServerInfoList);
575 CAClearServerInfoList(g_serverInfoList);
576 g_serverInfoList = NULL;
578 ca_mutex_unlock(g_mutexServerInfoList);
580 CAIPServerDestroyMutex();
582 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
586 CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
587 bool forceBindStart, bool isSecured)
589 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
592 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
593 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
597 OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: port is invalid!");
598 return CA_STATUS_INVALID_PARAM;
601 ca_mutex_lock(g_mutexServerInfoList);
602 bool isUnicastServerStarted = CAIsUnicastServerStarted(g_serverInfoList, localAddress, *port);
603 if (!isUnicastServerStarted)
605 int unicastServerFd = -1;
606 if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceBindStart, isSecured,
609 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to start unicast server!");
610 ca_mutex_unlock(g_mutexServerInfoList);
611 return CA_STATUS_FAILED;
614 CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
617 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
618 close(unicastServerFd);
619 ca_mutex_unlock(g_mutexServerInfoList);
620 return CA_MEMORY_ALLOC_FAILED;
623 char *netMask = NULL;
624 if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
626 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
630 strncpy(info->subNetMask, netMask, strlen(netMask));
633 strncpy(info->ipAddress, localAddress, strlen(localAddress));
635 info->socketFd = unicastServerFd;
636 info->isSecured = isSecured;
637 info->isServerStarted = true;
638 info->isMulticastServer = false;
639 strncpy(info->ifAddr, localAddress, strlen(localAddress));
641 CAResult_t res = CAAddServerInfo(g_serverInfoList, info);
642 if (CA_STATUS_OK != res)
644 OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
645 close(unicastServerFd);
646 ca_mutex_unlock(g_mutexServerInfoList);
649 ca_mutex_unlock(g_mutexServerInfoList);
651 res = CAIPStartPacketReceiverHandler();
652 if (CA_STATUS_OK != res)
654 OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
655 close(unicastServerFd);
661 OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Already Unicast Server Started ip [%s] port [%d]",
662 localAddress, *port);
663 ca_mutex_unlock(g_mutexServerInfoList);
666 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
670 CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
671 uint16_t multicastPort)
673 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
676 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
677 VERIFY_NON_NULL(multicastAddress, IP_SERVER_TAG, "port");
679 uint16_t port = multicastPort;
682 OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: Multicast port is invalid!");
683 return CA_STATUS_INVALID_PARAM;
686 ca_mutex_lock(g_mutexServerInfoList);
687 bool isMulticastServerStarted = CAIsMulticastServerStarted(g_serverInfoList, localAddress,
688 multicastAddress, port);
689 if (!isMulticastServerStarted)
691 int mulicastServerFd = -1;
692 CAResult_t ret = CACreateSocket(&mulicastServerFd, multicastAddress, &port, true);
693 if (ret != CA_STATUS_OK)
695 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create multicast socket");
696 ca_mutex_unlock(g_mutexServerInfoList);
700 struct ip_mreq multicastMemberReq = {.imr_interface.s_addr = inet_addr(localAddress)};
701 inet_aton(multicastAddress, &multicastMemberReq.imr_multiaddr);
703 if (-1 == setsockopt(mulicastServerFd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
704 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
706 OIC_LOG_V(ERROR, IP_SERVER_TAG,
707 "Failed to add to multicast group, Error code: %s\n", strerror(errno));
708 close(mulicastServerFd);
709 ca_mutex_unlock(g_mutexServerInfoList);
710 return CA_STATUS_FAILED;
713 CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
716 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
717 close(mulicastServerFd);
718 ca_mutex_unlock(g_mutexServerInfoList);
719 return CA_MEMORY_ALLOC_FAILED;
722 char *netMask = NULL;
723 if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
725 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
729 strncpy(info->subNetMask, netMask, strlen(netMask));
733 strncpy(info->ipAddress, multicastAddress, strlen(multicastAddress));
734 info->port = multicastPort;
735 info->socketFd = mulicastServerFd;
736 info->isSecured = false;
737 info->isServerStarted = true;
738 info->isMulticastServer = true;
739 strncpy(info->ifAddr, localAddress, strlen(localAddress));
741 ret = CAAddServerInfo(g_serverInfoList, info);
743 if (CA_STATUS_OK != ret)
745 OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
746 close(mulicastServerFd);
747 ca_mutex_unlock(g_mutexServerInfoList);
750 ca_mutex_unlock(g_mutexServerInfoList);
752 ret = CAIPStartPacketReceiverHandler();
753 if (CA_STATUS_OK != ret)
755 OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
756 close(mulicastServerFd);
762 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
763 "Multicast Server is already started on interface addr[%s]", localAddress);
764 ca_mutex_unlock(g_mutexServerInfoList);
767 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
771 CAResult_t CAIPStopServer(const char *interfaceAddress)
773 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
775 VERIFY_NON_NULL(interfaceAddress, IP_SERVER_TAG, "interfaceAddress is NULL");
777 ca_mutex_lock(g_mutexServerInfoList);
778 uint32_t listIndex = 0;
779 uint32_t listLength = u_arraylist_length(g_serverInfoList);
781 for (listIndex = 0; listIndex < listLength;)
783 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
790 if (info->isMulticastServer && strncmp(interfaceAddress, info->ifAddr, strlen(info->ifAddr))
793 if (u_arraylist_remove(g_serverInfoList, listIndex))
795 struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
797 multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
798 inet_aton(info->ipAddress, &multicastMemberReq.imr_multiaddr);
799 if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
800 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
802 OIC_LOG_V(ERROR, IP_SERVER_TAG,
803 "Failed to leave multicast group, Error code: %s", strerror(errno));
805 CACloseSocket(info->socketFd);
807 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
808 "Multicast server is stopped successfully on IF [%s]", info->ifAddr);
809 // Reduce list length by 1 as we removed one element.
814 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
815 ca_mutex_unlock(g_mutexServerInfoList);
816 return CA_STATUS_FAILED;
819 else if (strncmp(interfaceAddress, info->ipAddress, strlen(info->ipAddress)) == 0)
821 if (u_arraylist_remove(g_serverInfoList, listIndex))
823 CACloseSocket(info->socketFd);
825 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
826 "Unicast server is stopped successfully on IF [%s]", info->ifAddr);
827 // Reduce list length by 1 as we removed one element.
832 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
833 ca_mutex_unlock(g_mutexServerInfoList);
834 return CA_STATUS_FAILED;
843 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
844 ca_mutex_unlock(g_mutexServerInfoList);
848 CAResult_t CAIPStopAllServers()
850 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
852 g_packetHandlerStopFlag = true;
854 ca_mutex_lock(g_mutexServerInfoList);
856 uint32_t listIndex = 0;
857 uint32_t listLength = u_arraylist_length(g_serverInfoList);
858 for (listIndex = 0; listIndex < listLength;)
860 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
866 if (u_arraylist_remove(g_serverInfoList, listIndex))
868 if (info->isMulticastServer)
870 struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
872 multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
873 inet_aton(info->ipAddress, &multicastMemberReq.imr_multiaddr);
874 if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
875 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
877 OIC_LOG_V(ERROR, IP_SERVER_TAG,
878 "Failed to leave multicast group, Error code: %s", strerror(errno));
881 CACloseSocket(info->socketFd);
882 //Freeing server info.
884 // Reduce list length by 1 as we removed one element.
889 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
890 ca_mutex_unlock(g_mutexServerInfoList);
891 return CA_STATUS_FAILED;
895 ca_mutex_unlock(g_mutexServerInfoList);
897 OIC_LOG(DEBUG, IP_SERVER_TAG, "All Server stopped successfully. OUT");
901 uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured)
903 ca_mutex_lock(g_mutexServerInfoList);
905 uint16_t port = CAGetServerPort(g_serverInfoList, ipAddress, isSecured);
907 ca_mutex_unlock(g_mutexServerInfoList);
912 CAResult_t CAGetIPServerInfoList(u_arraylist_t **serverInfoList)
914 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
915 ca_mutex_lock(g_mutexServerInfoList);
917 uint32_t list_index = 0;
918 uint32_t list_length = u_arraylist_length(g_serverInfoList);
919 for (list_index = 0; list_index < list_length; list_index++)
921 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, list_index);
927 CAServerInfo_t *newNetinfo = (CAServerInfo_t *) OICMalloc(sizeof(CAServerInfo_t));
930 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed!");
931 ca_mutex_unlock(g_mutexServerInfoList);
932 return CA_MEMORY_ALLOC_FAILED;
935 memcpy(newNetinfo, info, sizeof(*info));
937 CAResult_t result = u_arraylist_add(*serverInfoList, (void *) newNetinfo);
938 if (CA_STATUS_OK != result)
940 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_add failed!");
941 ca_mutex_unlock(g_mutexServerInfoList);
942 return CA_STATUS_FAILED;
945 ca_mutex_unlock(g_mutexServerInfoList);
946 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
950 void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
952 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
954 ca_mutex_lock(g_mutexAdapterServerContext);
956 if (!g_adapterEthServerContext)
958 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
959 ca_mutex_unlock(g_mutexAdapterServerContext);
962 g_adapterEthServerContext->packetReceivedCallback = callback;
964 ca_mutex_unlock(g_mutexAdapterServerContext);
966 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
969 void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
971 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
972 ca_mutex_lock(g_mutexAdapterServerContext);
974 if (!g_adapterEthServerContext)
976 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
977 ca_mutex_unlock(g_mutexAdapterServerContext);
980 g_adapterEthServerContext->exceptionCallback = callback;
982 ca_mutex_unlock(g_mutexAdapterServerContext);
984 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");