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"
39 #include "oic_string.h"
43 * @brief Logging tag for module name
45 #define IP_SERVER_TAG "IP_SERVER"
48 * @def CA_UDP_BIND_RETRY_COUNT
49 * @brief Retry count in case of socket bind failure.
51 #define CA_UDP_BIND_RETRY_COUNT 10
55 * @brief Max length for ip address.
61 * @brief Socket option.
63 #define SOCKETOPTION 1
66 * @var g_packetHandlerStopFlag
67 * @brief Flag for stopping packet handler thread.
69 static bool g_packetHandlerStopFlag = false;
72 * @var CAAdapterIPServerContext_t
73 * @brief Thread context information for callbacks and threadpool.
77 ca_thread_pool_t threadPool;
78 CAIPPacketReceivedCallback packetReceivedCallback;
79 CAIPExceptionCallback exceptionCallback;
80 } CAAdapterIPServerContext_t;
83 * @var g_serverInfoList
84 * @brief Mutex to synchronize ethenet adapter context.
86 static u_arraylist_t *g_serverInfoList = NULL;
89 * @var g_mutexServerInfoList
90 * @brief Mutex to synchronize Server Information.
92 static ca_mutex g_mutexServerInfoList = NULL;
95 * @var g_adapterEthServerContext
96 * @brief Mutex to synchronize ethenet adapter context.
98 static CAAdapterIPServerContext_t *g_adapterEthServerContext = NULL;
101 * @var g_mutexAdapterServerContext
102 * @brief Mutex to synchronize unicast server
104 static ca_mutex g_mutexAdapterServerContext = NULL;
106 static void CAReceiveHandler(void *data)
108 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
112 struct timeval timeout;
113 char recvBuffer[COAP_MAX_PDU_SIZE] = { 0 };
115 while (true != g_packetHandlerStopFlag)
121 ca_mutex_lock(g_mutexServerInfoList);
122 uint32_t listIndex = 0;
123 uint32_t listLength = u_arraylist_length(g_serverInfoList);
125 u_arraylist_t *tempServerInfoList = u_arraylist_create();
126 if (!tempServerInfoList)
128 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_create failed");
129 ca_mutex_unlock(g_mutexServerInfoList);
133 for (listIndex = 0; listIndex < listLength; listIndex++)
135 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
142 int sd = info->socketFd;
143 //if valid socket descriptor then add to read list
146 FD_SET(sd, &readFds);
149 //highest file descriptor number, need it for the select function
155 CAServerInfo_t *newInfo = (CAServerInfo_t *) OICMalloc(sizeof(CAServerInfo_t));
158 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
159 CAClearServerInfoList(tempServerInfoList);
160 ca_mutex_unlock(g_mutexServerInfoList);
166 CAResult_t result = u_arraylist_add(tempServerInfoList, (void *) newInfo);
167 if (CA_STATUS_OK != result)
169 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_add failed!Thread exit");
170 CAClearServerInfoList(tempServerInfoList);
171 ca_mutex_unlock(g_mutexServerInfoList);
176 ca_mutex_unlock(g_mutexServerInfoList);
178 int ret = select(maxSd + 1, &readFds, NULL, NULL, &timeout);
179 if (g_packetHandlerStopFlag)
181 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
182 "Packet receiver handler Stop request received. Thread exited");
183 CAClearServerInfoList(tempServerInfoList);
188 OIC_LOG_V(FATAL, IP_SERVER_TAG, "select returned error %s", strerror(errno));
189 CAClearServerInfoList(tempServerInfoList);
193 listLength = u_arraylist_length(tempServerInfoList);
194 for (listIndex = 0; listIndex < listLength; listIndex++)
196 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(tempServerInfoList,
203 int sd = info->socketFd;
204 if (FD_ISSET(sd , &readFds))
206 OIC_LOG_V(ERROR, IP_SERVER_TAG,
207 "data Received server information ip %s, port %d socket %d",
208 info->endpoint.addr, info->endpoint.port, sd);
209 memset(recvBuffer, 0, sizeof(recvBuffer));
211 struct sockaddr_in srcSockAddress = { 0 };
212 socklen_t srcAddressLen = sizeof(srcSockAddress);
214 //Reading from socket
215 ssize_t recvLen = recvfrom(sd, recvBuffer, sizeof(recvBuffer), 0,
216 (struct sockaddr *) &srcSockAddress, &srcAddressLen);
219 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Recvfrom failed %s", strerror(errno));
222 else if (0 == recvLen)
224 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Server socket shutdown sock fd[%d]", sd);
225 ca_mutex_lock(g_mutexAdapterServerContext);
226 // Notify upper layer this exception
227 if (g_adapterEthServerContext->exceptionCallback)
229 // need to make proper exception callback.
230 //g_adapterEthServerContext->exceptionCallback(ctx->type);
232 ca_mutex_unlock(g_mutexAdapterServerContext);
235 char srcIPAddress[CA_IPADDR_SIZE] = { 0 };
236 if (!inet_ntop(AF_INET, &srcSockAddress.sin_addr.s_addr, srcIPAddress,
237 sizeof(srcIPAddress)))
240 OIC_LOG(ERROR, IP_SERVER_TAG, "inet_ntop is failed!");
244 uint16_t srcPort = ntohs(srcSockAddress.sin_port);
246 OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Received packet from %s:%d len %d",
247 srcIPAddress, srcPort, recvLen);
249 char *netMask = NULL;
250 if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(info->ifAddr, &netMask))
252 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
256 if (!CAAdapterIsSameSubnet(info->ifAddr, srcIPAddress, netMask))
258 OIC_LOG(DEBUG, IP_SERVER_TAG,
259 "Packet received from different subnet, Ignore!");
266 strncpy(ep.addr, srcIPAddress, MAX_ADDR_STR_SIZE_CA);
269 ep.adapter = CA_ADAPTER_IP;
271 if (info->endpoint.flags & CA_SECURE)
274 ep.flags |= CA_SECURE;
275 (void)CAAdapterNetDtlsDecrypt(&ep, (uint8_t *)recvBuffer, recvLen);
276 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
277 "CAAdapterNetDtlsDecrypt returns [%d]", ret);
280 else //both multicast and unicast
282 ca_mutex_lock(g_mutexAdapterServerContext);
284 if (g_adapterEthServerContext->packetReceivedCallback)
286 g_adapterEthServerContext->packetReceivedCallback(&ep,
287 recvBuffer, recvLen);
290 ca_mutex_unlock(g_mutexAdapterServerContext);
294 CAClearServerInfoList(tempServerInfoList);
296 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
299 static CAResult_t CACreateSocket(int *socketFD, const char *localIp, uint16_t *port)
301 VERIFY_NON_NULL(socketFD, IP_SERVER_TAG, "socketFD is NULL");
302 VERIFY_NON_NULL(localIp, IP_SERVER_TAG, "localIp is NULL");
303 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port is NULL");
304 // Create a UDP socket
308 sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
313 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
318 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to create Socket, Error code: %s",
320 return CA_STATUS_FAILED;
323 // Make the socket non-blocking
324 if (-1 == fcntl(sock, F_SETFL, O_NONBLOCK))
326 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
330 return CA_STATUS_FAILED;
335 int setOptionOn = SOCKETOPTION;
336 if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &setOptionOn,
337 sizeof(setOptionOn)))
339 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
342 return CA_STATUS_FAILED;
346 struct sockaddr_in sockAddr = { 0 };
347 uint16_t serverPort = *port;
348 sockAddr.sin_family = AF_INET;
349 sockAddr.sin_port = htons(serverPort);
352 sockAddr.sin_addr.s_addr = inet_addr(localIp);
355 if (-1 != bind(sock, (struct sockaddr *) &sockAddr, sizeof(sockAddr)))
357 struct sockaddr_in sin;
358 socklen_t len = sizeof(sin);
360 if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
362 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to get socket[%s]!",
365 return CA_STATUS_FAILED;
369 serverPort = (uint16_t) ntohs(sin.sin_port);
374 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to bind socket[%s]!",
377 return CA_STATUS_FAILED;
385 static void CACloseSocket(int socketFD)
389 OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid Socket Fd");
394 if (-1 == close(socketFD))
396 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
401 static CAResult_t CAStartUnicastServer(const char *localAddress, uint16_t *port,
402 bool isSecured, int *serverFD)
404 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
406 VERIFY_NON_NULL(serverFD, IP_SERVER_TAG, "serverFD");
407 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
408 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
410 CAResult_t ret = CACreateSocket(serverFD, localAddress, port);
411 if (CA_STATUS_OK != ret)
413 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create unicast socket");
416 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
420 static CAResult_t CAIPStartPacketReceiverHandler()
422 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
424 ca_mutex_lock(g_mutexServerInfoList);
426 uint32_t listLength = u_arraylist_length(g_serverInfoList);
428 ca_mutex_unlock(g_mutexServerInfoList);
430 ca_mutex_lock(g_mutexAdapterServerContext);
432 if (!g_adapterEthServerContext)
434 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
435 ca_mutex_unlock(g_mutexAdapterServerContext);
436 return CA_STATUS_FAILED;
439 if (1 == listLength) //Its first time.
441 g_packetHandlerStopFlag = false;
442 if (CA_STATUS_OK != ca_thread_pool_add_task(g_adapterEthServerContext->threadPool,
443 CAReceiveHandler, NULL ))
445 OIC_LOG(ERROR, IP_SERVER_TAG, "thread_pool_add_task failed!");
446 ca_mutex_unlock(g_mutexAdapterServerContext);
447 return CA_STATUS_FAILED;
449 OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread started successfully.");
453 OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread already is running");
455 ca_mutex_unlock(g_mutexAdapterServerContext);
457 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
462 static void CAIPServerDestroyMutex(void)
464 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
466 if (g_mutexServerInfoList)
468 ca_mutex_free(g_mutexServerInfoList);
469 g_mutexServerInfoList = NULL;
472 if (g_mutexAdapterServerContext)
474 ca_mutex_free(g_mutexAdapterServerContext);
475 g_mutexAdapterServerContext = NULL;
478 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
481 static CAResult_t CAIPServerCreateMutex(void)
483 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
485 g_mutexServerInfoList = ca_mutex_new();
486 if (!g_mutexServerInfoList)
488 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
489 return CA_MEMORY_ALLOC_FAILED;
492 g_mutexAdapterServerContext = ca_mutex_new();
493 if (!g_mutexAdapterServerContext)
495 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to created mutex!");
496 ca_mutex_free(g_mutexServerInfoList);
497 g_mutexServerInfoList = NULL;
498 return CA_MEMORY_ALLOC_FAILED;
501 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
505 CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool)
507 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
510 VERIFY_NON_NULL(threadPool, IP_SERVER_TAG, "Thread pool handle is NULL");
513 if (CA_STATUS_OK != CAIPServerCreateMutex())
515 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create mutex!");
516 return CA_STATUS_FAILED;
519 ca_mutex_lock(g_mutexAdapterServerContext);
520 g_adapterEthServerContext = (CAAdapterIPServerContext_t *) OICCalloc(1,
521 sizeof(CAAdapterIPServerContext_t));
523 if (!g_adapterEthServerContext)
525 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
526 ca_mutex_unlock(g_mutexAdapterServerContext);
527 return CA_MEMORY_ALLOC_FAILED;
530 g_adapterEthServerContext->threadPool = threadPool;
532 ca_mutex_unlock(g_mutexAdapterServerContext);
534 ca_mutex_lock(g_mutexServerInfoList);
536 g_serverInfoList = u_arraylist_create();
537 if (!g_serverInfoList)
539 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_create failed");
540 ca_mutex_unlock(g_mutexServerInfoList);
541 return CA_MEMORY_ALLOC_FAILED;
543 ca_mutex_unlock(g_mutexServerInfoList);
544 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
548 void CAIPTerminateServer()
550 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
551 ca_mutex_lock(g_mutexAdapterServerContext);
552 if (!g_adapterEthServerContext)
554 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
555 ca_mutex_unlock(g_mutexAdapterServerContext);
559 OICFree(g_adapterEthServerContext);
560 g_adapterEthServerContext = NULL;
562 ca_mutex_unlock(g_mutexAdapterServerContext);
564 ca_mutex_lock(g_mutexServerInfoList);
566 CAClearServerInfoList(g_serverInfoList);
567 g_serverInfoList = NULL;
569 ca_mutex_unlock(g_mutexServerInfoList);
571 CAIPServerDestroyMutex();
573 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
577 CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, bool isSecured)
579 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
582 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
583 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
587 OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: port is invalid!");
588 return CA_STATUS_INVALID_PARAM;
591 ca_mutex_lock(g_mutexServerInfoList);
592 bool isUnicastServerStarted = CAIsUnicastServerStarted(g_serverInfoList, localAddress, *port);
593 if (!isUnicastServerStarted)
595 int unicastServerFd = -1;
596 if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, isSecured,
599 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to start unicast server!");
600 ca_mutex_unlock(g_mutexServerInfoList);
601 return CA_STATUS_FAILED;
604 CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
607 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
608 close(unicastServerFd);
609 ca_mutex_unlock(g_mutexServerInfoList);
610 return CA_MEMORY_ALLOC_FAILED;
613 char *netMask = NULL;
614 if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
616 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
620 OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask);
623 OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), localAddress);
624 info->endpoint.port = *port;
625 info->endpoint.flags = isSecured ? CA_SECURE : 0;
626 info->endpoint.adapter = CA_ADAPTER_IP;
627 info->socketFd = unicastServerFd;
628 info->isServerStarted = true;
629 info->isMulticastServer = false;
630 OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress);
632 CAResult_t res = CAAddServerInfo(g_serverInfoList, info);
633 if (CA_STATUS_OK != res)
635 OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
636 close(unicastServerFd);
637 ca_mutex_unlock(g_mutexServerInfoList);
640 ca_mutex_unlock(g_mutexServerInfoList);
642 res = CAIPStartPacketReceiverHandler();
643 if (CA_STATUS_OK != res)
645 OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
646 close(unicastServerFd);
652 OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Already Unicast Server Started ip [%s] port [%d]",
653 localAddress, *port);
654 ca_mutex_unlock(g_mutexServerInfoList);
657 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
661 CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
662 uint16_t multicastPort)
664 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
667 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
668 VERIFY_NON_NULL(multicastAddress, IP_SERVER_TAG, "port");
670 uint16_t port = multicastPort;
673 OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: Multicast port is invalid!");
674 return CA_STATUS_INVALID_PARAM;
677 ca_mutex_lock(g_mutexServerInfoList);
678 bool isMulticastServerStarted = CAIsMulticastServerStarted(g_serverInfoList, localAddress,
679 multicastAddress, port);
680 if (!isMulticastServerStarted)
682 int mulicastServerFd = -1;
683 CAResult_t ret = CACreateSocket(&mulicastServerFd, multicastAddress, &port);
684 if (ret != CA_STATUS_OK)
686 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create multicast socket");
687 ca_mutex_unlock(g_mutexServerInfoList);
691 struct ip_mreq multicastMemberReq = {.imr_interface.s_addr = inet_addr(localAddress)};
692 inet_aton(multicastAddress, &multicastMemberReq.imr_multiaddr);
694 if (-1 == setsockopt(mulicastServerFd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
695 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
697 OIC_LOG_V(ERROR, IP_SERVER_TAG,
698 "Failed to add to multicast group, Error code: %s\n", strerror(errno));
699 close(mulicastServerFd);
700 ca_mutex_unlock(g_mutexServerInfoList);
701 return CA_STATUS_FAILED;
704 CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
707 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
708 close(mulicastServerFd);
709 ca_mutex_unlock(g_mutexServerInfoList);
710 return CA_MEMORY_ALLOC_FAILED;
713 char *netMask = NULL;
714 if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
716 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
720 OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask);
724 OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), multicastAddress);
725 info->endpoint.port = multicastPort;
726 info->endpoint.flags = 0;
727 info->socketFd = mulicastServerFd;
728 info->isServerStarted = true;
729 info->isMulticastServer = true;
730 OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress);
732 ret = CAAddServerInfo(g_serverInfoList, info);
734 if (CA_STATUS_OK != ret)
736 OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
737 close(mulicastServerFd);
738 ca_mutex_unlock(g_mutexServerInfoList);
741 ca_mutex_unlock(g_mutexServerInfoList);
743 ret = CAIPStartPacketReceiverHandler();
744 if (CA_STATUS_OK != ret)
746 OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
747 close(mulicastServerFd);
753 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
754 "Multicast Server is already started on interface addr[%s]", localAddress);
755 ca_mutex_unlock(g_mutexServerInfoList);
758 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
762 CAResult_t CAIPStopServer(const char *interfaceAddress)
764 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
766 VERIFY_NON_NULL(interfaceAddress, IP_SERVER_TAG, "interfaceAddress is NULL");
768 ca_mutex_lock(g_mutexServerInfoList);
769 uint32_t listIndex = 0;
770 uint32_t listLength = u_arraylist_length(g_serverInfoList);
772 for (listIndex = 0; listIndex < listLength;)
774 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
781 if (info->isMulticastServer && strncmp(interfaceAddress, info->ifAddr, strlen(info->ifAddr))
784 if (u_arraylist_remove(g_serverInfoList, listIndex))
786 struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
788 multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
789 inet_aton(info->endpoint.addr, &multicastMemberReq.imr_multiaddr);
790 if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
791 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
793 OIC_LOG_V(ERROR, IP_SERVER_TAG,
794 "Failed to leave multicast group, Error code: %s", strerror(errno));
796 CACloseSocket(info->socketFd);
798 OIC_LOG(DEBUG, IP_SERVER_TAG, "Multicast server is stopped successfully.");
799 // Reduce list length by 1 as we removed one element.
804 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
805 ca_mutex_unlock(g_mutexServerInfoList);
806 return CA_STATUS_FAILED;
809 else if (strncmp(interfaceAddress, info->endpoint.addr, strlen(info->endpoint.addr)) == 0)
811 if (u_arraylist_remove(g_serverInfoList, listIndex))
813 CACloseSocket(info->socketFd);
815 OIC_LOG(DEBUG, IP_SERVER_TAG, "Unicast server is stopped successfully.");
816 // Reduce list length by 1 as we removed one element.
821 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
822 ca_mutex_unlock(g_mutexServerInfoList);
823 return CA_STATUS_FAILED;
832 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
833 ca_mutex_unlock(g_mutexServerInfoList);
837 CAResult_t CAIPStopAllServers()
839 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
841 g_packetHandlerStopFlag = true;
843 ca_mutex_lock(g_mutexServerInfoList);
845 uint32_t listIndex = 0;
846 uint32_t listLength = u_arraylist_length(g_serverInfoList);
847 for (listIndex = 0; listIndex < listLength;)
849 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
855 if (u_arraylist_remove(g_serverInfoList, listIndex))
857 if (info->isMulticastServer)
859 struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
861 multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
862 inet_aton(info->endpoint.addr, &multicastMemberReq.imr_multiaddr);
863 if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
864 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
866 OIC_LOG_V(ERROR, IP_SERVER_TAG,
867 "Failed to leave multicast group, Error code: %s", strerror(errno));
870 CACloseSocket(info->socketFd);
871 //Freeing server info.
873 // Reduce list length by 1 as we removed one element.
878 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
879 ca_mutex_unlock(g_mutexServerInfoList);
880 return CA_STATUS_FAILED;
884 ca_mutex_unlock(g_mutexServerInfoList);
886 OIC_LOG(DEBUG, IP_SERVER_TAG, "All Server stopped successfully. OUT");
890 uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured)
892 ca_mutex_lock(g_mutexServerInfoList);
894 uint16_t port = CAGetServerPort(g_serverInfoList, ipAddress, isSecured);
896 ca_mutex_unlock(g_mutexServerInfoList);
901 CAResult_t CAGetIPServerInfoList(u_arraylist_t **serverInfoList)
903 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
904 ca_mutex_lock(g_mutexServerInfoList);
906 uint32_t list_index = 0;
907 uint32_t list_length = u_arraylist_length(g_serverInfoList);
908 for (list_index = 0; list_index < list_length; list_index++)
910 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, list_index);
916 CAServerInfo_t *newNetinfo = (CAServerInfo_t *) OICMalloc(sizeof(CAServerInfo_t));
919 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed!");
920 ca_mutex_unlock(g_mutexServerInfoList);
921 return CA_MEMORY_ALLOC_FAILED;
926 CAResult_t result = u_arraylist_add(*serverInfoList, (void *) newNetinfo);
927 if (CA_STATUS_OK != result)
929 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_add failed!");
930 ca_mutex_unlock(g_mutexServerInfoList);
931 return CA_STATUS_FAILED;
934 ca_mutex_unlock(g_mutexServerInfoList);
935 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
939 void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
941 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
943 ca_mutex_lock(g_mutexAdapterServerContext);
945 if (!g_adapterEthServerContext)
947 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
948 ca_mutex_unlock(g_mutexAdapterServerContext);
951 g_adapterEthServerContext->packetReceivedCallback = callback;
953 ca_mutex_unlock(g_mutexAdapterServerContext);
955 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
958 void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
960 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
961 ca_mutex_lock(g_mutexAdapterServerContext);
963 if (!g_adapterEthServerContext)
965 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterEthServerContext NULL");
966 ca_mutex_unlock(g_mutexAdapterServerContext);
969 g_adapterEthServerContext->exceptionCallback = callback;
971 ca_mutex_unlock(g_mutexAdapterServerContext);
973 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");