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 CAIPErrorHandleCallback IPErrorCallback;
81 } CAAdapterIPServerContext_t;
84 * @var g_serverInfoList
85 * @brief Mutex to synchronize ethenet adapter context.
87 static u_arraylist_t *g_serverInfoList = NULL;
90 * @var g_mutexServerInfoList
91 * @brief Mutex to synchronize Server Information.
93 static ca_mutex g_mutexServerInfoList = NULL;
96 * @var g_adapterIPServerContext
97 * @brief Mutex to synchronize ethenet adapter context.
99 static CAAdapterIPServerContext_t *g_adapterIPServerContext = NULL;
102 * @var g_mutexAdapterServerContext
103 * @brief Mutex to synchronize unicast server
105 static ca_mutex g_mutexAdapterServerContext = NULL;
107 static void CAReceiveHandler(void *data)
109 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
113 struct timeval timeout;
114 char recvBuffer[COAP_MAX_PDU_SIZE] = { 0 };
116 while (true != g_packetHandlerStopFlag)
122 ca_mutex_lock(g_mutexServerInfoList);
123 uint32_t listIndex = 0;
124 uint32_t listLength = u_arraylist_length(g_serverInfoList);
126 u_arraylist_t *tempServerInfoList = u_arraylist_create();
127 if (!tempServerInfoList)
129 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_create failed");
130 ca_mutex_unlock(g_mutexServerInfoList);
134 for (listIndex = 0; listIndex < listLength; listIndex++)
136 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
143 int sd = info->socketFd;
144 //if valid socket descriptor then add to read list
147 FD_SET(sd, &readFds);
150 //highest file descriptor number, need it for the select function
156 CAServerInfo_t *newInfo = (CAServerInfo_t *) OICMalloc(sizeof(CAServerInfo_t));
159 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
160 CAClearServerInfoList(tempServerInfoList);
161 ca_mutex_unlock(g_mutexServerInfoList);
167 CAResult_t result = u_arraylist_add(tempServerInfoList, (void *) newInfo);
168 if (CA_STATUS_OK != result)
170 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_add failed!Thread exit");
171 CAClearServerInfoList(tempServerInfoList);
172 ca_mutex_unlock(g_mutexServerInfoList);
177 ca_mutex_unlock(g_mutexServerInfoList);
179 int ret = select(maxSd + 1, &readFds, NULL, NULL, &timeout);
180 if (g_packetHandlerStopFlag)
182 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
183 "Packet receiver handler Stop request received. Thread exited");
184 CAClearServerInfoList(tempServerInfoList);
189 OIC_LOG_V(FATAL, IP_SERVER_TAG, "select returned error %s", strerror(errno));
190 CAClearServerInfoList(tempServerInfoList);
194 listLength = u_arraylist_length(tempServerInfoList);
195 for (listIndex = 0; listIndex < listLength; listIndex++)
197 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(tempServerInfoList,
204 int sd = info->socketFd;
205 if (FD_ISSET(sd , &readFds))
207 OIC_LOG_V(ERROR, IP_SERVER_TAG,
208 "data Received server information ip %s, port %d socket %d",
209 info->endpoint.addr, info->endpoint.port, sd);
210 memset(recvBuffer, 0, sizeof(recvBuffer));
212 struct sockaddr_in srcSockAddress = { 0 };
213 socklen_t srcAddressLen = sizeof(srcSockAddress);
215 //Reading from socket
216 ssize_t recvLen = recvfrom(sd, recvBuffer, sizeof(recvBuffer), 0,
217 (struct sockaddr *) &srcSockAddress, &srcAddressLen);
220 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Recvfrom failed %s", strerror(errno));
223 else if (0 == recvLen)
225 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Server socket shutdown sock fd[%d]", sd);
226 ca_mutex_lock(g_mutexAdapterServerContext);
227 // Notify upper layer this exception
228 if (g_adapterIPServerContext->exceptionCallback)
230 // need to make proper exception callback.
231 //g_adapterIPServerContext->exceptionCallback(ctx->type);
233 ca_mutex_unlock(g_mutexAdapterServerContext);
236 char srcIPAddress[CA_IPADDR_SIZE] = { 0 };
237 if (!inet_ntop(AF_INET, &srcSockAddress.sin_addr.s_addr, srcIPAddress,
238 sizeof(srcIPAddress)))
241 OIC_LOG(ERROR, IP_SERVER_TAG, "inet_ntop is failed!");
245 uint16_t srcPort = ntohs(srcSockAddress.sin_port);
247 OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Received packet from %s:%d len %d",
248 srcIPAddress, srcPort, recvLen);
250 char *netMask = NULL;
251 if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(info->ifAddr, &netMask))
253 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
257 if (!CAAdapterIsSameSubnet(info->ifAddr, srcIPAddress, netMask))
259 OIC_LOG(DEBUG, IP_SERVER_TAG,
260 "Packet received from different subnet, Ignore!");
267 strncpy(ep.addr, srcIPAddress, MAX_ADDR_STR_SIZE_CA);
270 ep.adapter = CA_ADAPTER_IP;
272 if (info->endpoint.flags & CA_SECURE)
275 ep.flags |= CA_SECURE;
276 (void)CAAdapterNetDtlsDecrypt(&ep, (uint8_t *)recvBuffer, recvLen);
277 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
278 "CAAdapterNetDtlsDecrypt returns [%d]", ret);
281 else //both multicast and unicast
283 ca_mutex_lock(g_mutexAdapterServerContext);
285 if (g_adapterIPServerContext->packetReceivedCallback)
287 g_adapterIPServerContext->packetReceivedCallback(&ep,
288 recvBuffer, recvLen);
291 ca_mutex_unlock(g_mutexAdapterServerContext);
295 CAClearServerInfoList(tempServerInfoList);
297 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
300 static CAResult_t CACreateSocket(int *socketFD, const char *localIp, uint16_t *port)
302 VERIFY_NON_NULL(socketFD, IP_SERVER_TAG, "socketFD is NULL");
303 VERIFY_NON_NULL(localIp, IP_SERVER_TAG, "localIp is NULL");
304 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port is NULL");
305 // Create a UDP socket
309 sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
314 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
319 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to create Socket, Error code: %s",
321 return CA_STATUS_FAILED;
324 // Make the socket non-blocking
325 if (-1 == fcntl(sock, F_SETFL, O_NONBLOCK))
327 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
331 return CA_STATUS_FAILED;
336 int setOptionOn = SOCKETOPTION;
337 if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &setOptionOn,
338 sizeof(setOptionOn)))
340 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
343 return CA_STATUS_FAILED;
347 struct sockaddr_in sockAddr = { 0 };
348 uint16_t serverPort = *port;
349 sockAddr.sin_family = AF_INET;
350 sockAddr.sin_port = htons(serverPort);
353 sockAddr.sin_addr.s_addr = inet_addr(localIp);
356 if (-1 != bind(sock, (struct sockaddr *) &sockAddr, sizeof(sockAddr)))
358 struct sockaddr_in sin;
359 socklen_t len = sizeof(sin);
361 if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
363 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to get socket[%s]!",
366 return CA_STATUS_FAILED;
370 serverPort = (uint16_t) ntohs(sin.sin_port);
375 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to bind socket[%s]!",
378 return CA_STATUS_FAILED;
386 static void CACloseSocket(int socketFD)
390 OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid Socket Fd");
395 if (-1 == close(socketFD))
397 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
402 static CAResult_t CAStartUnicastServer(const char *localAddress, uint16_t *port,
403 bool isSecured, int *serverFD)
405 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
407 VERIFY_NON_NULL(serverFD, IP_SERVER_TAG, "serverFD");
408 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
409 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
411 CAResult_t ret = CACreateSocket(serverFD, localAddress, port);
412 if (CA_STATUS_OK != ret)
414 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create unicast socket");
417 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
421 static CAResult_t CAIPStartPacketReceiverHandler()
423 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
425 ca_mutex_lock(g_mutexServerInfoList);
427 uint32_t listLength = u_arraylist_length(g_serverInfoList);
429 ca_mutex_unlock(g_mutexServerInfoList);
431 ca_mutex_lock(g_mutexAdapterServerContext);
433 if (!g_adapterIPServerContext)
435 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
436 ca_mutex_unlock(g_mutexAdapterServerContext);
437 return CA_STATUS_FAILED;
440 if (1 == listLength) //Its first time.
442 g_packetHandlerStopFlag = false;
443 if (CA_STATUS_OK != ca_thread_pool_add_task(g_adapterIPServerContext->threadPool,
444 CAReceiveHandler, NULL ))
446 OIC_LOG(ERROR, IP_SERVER_TAG, "thread_pool_add_task failed!");
447 ca_mutex_unlock(g_mutexAdapterServerContext);
448 return CA_STATUS_FAILED;
450 OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread started successfully.");
454 OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread already is running");
456 ca_mutex_unlock(g_mutexAdapterServerContext);
458 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
463 static void CAIPServerDestroyMutex(void)
465 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
467 if (g_mutexServerInfoList)
469 ca_mutex_free(g_mutexServerInfoList);
470 g_mutexServerInfoList = NULL;
473 if (g_mutexAdapterServerContext)
475 ca_mutex_free(g_mutexAdapterServerContext);
476 g_mutexAdapterServerContext = NULL;
479 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
482 static CAResult_t CAIPServerCreateMutex(void)
484 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
486 g_mutexServerInfoList = ca_mutex_new();
487 if (!g_mutexServerInfoList)
489 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
490 return CA_MEMORY_ALLOC_FAILED;
493 g_mutexAdapterServerContext = ca_mutex_new();
494 if (!g_mutexAdapterServerContext)
496 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to created mutex!");
497 ca_mutex_free(g_mutexServerInfoList);
498 g_mutexServerInfoList = NULL;
499 return CA_MEMORY_ALLOC_FAILED;
502 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
506 CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool)
508 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
511 VERIFY_NON_NULL(threadPool, IP_SERVER_TAG, "Thread pool handle is NULL");
514 if (CA_STATUS_OK != CAIPServerCreateMutex())
516 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create mutex!");
517 return CA_STATUS_FAILED;
520 ca_mutex_lock(g_mutexAdapterServerContext);
521 g_adapterIPServerContext = (CAAdapterIPServerContext_t *) OICCalloc(1,
522 sizeof(CAAdapterIPServerContext_t));
524 if (!g_adapterIPServerContext)
526 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
527 ca_mutex_unlock(g_mutexAdapterServerContext);
528 return CA_MEMORY_ALLOC_FAILED;
531 g_adapterIPServerContext->threadPool = threadPool;
533 ca_mutex_unlock(g_mutexAdapterServerContext);
535 ca_mutex_lock(g_mutexServerInfoList);
537 g_serverInfoList = u_arraylist_create();
538 if (!g_serverInfoList)
540 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_create failed");
541 ca_mutex_unlock(g_mutexServerInfoList);
542 return CA_MEMORY_ALLOC_FAILED;
544 ca_mutex_unlock(g_mutexServerInfoList);
545 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
549 void CAIPTerminateServer()
551 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
552 ca_mutex_lock(g_mutexAdapterServerContext);
553 if (!g_adapterIPServerContext)
555 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
556 ca_mutex_unlock(g_mutexAdapterServerContext);
560 OICFree(g_adapterIPServerContext);
561 g_adapterIPServerContext = NULL;
563 ca_mutex_unlock(g_mutexAdapterServerContext);
565 ca_mutex_lock(g_mutexServerInfoList);
567 CAClearServerInfoList(g_serverInfoList);
568 g_serverInfoList = NULL;
570 ca_mutex_unlock(g_mutexServerInfoList);
572 CAIPServerDestroyMutex();
574 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
578 CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, bool isSecured)
580 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
583 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
584 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
586 ca_mutex_lock(g_mutexServerInfoList);
587 bool isUnicastServerStarted = CAIsUnicastServerStarted(g_serverInfoList, localAddress, *port);
588 if (!isUnicastServerStarted)
590 int unicastServerFd = -1;
591 if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, isSecured,
594 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to start unicast server!");
595 ca_mutex_unlock(g_mutexServerInfoList);
596 return CA_STATUS_FAILED;
599 CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
602 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
603 close(unicastServerFd);
604 ca_mutex_unlock(g_mutexServerInfoList);
605 return CA_MEMORY_ALLOC_FAILED;
608 char *netMask = NULL;
609 if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
611 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
615 OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask);
618 OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), localAddress);
619 info->endpoint.port = *port;
620 info->endpoint.flags = isSecured ? CA_SECURE : 0;
621 info->endpoint.adapter = CA_ADAPTER_IP;
622 info->socketFd = unicastServerFd;
623 info->isServerStarted = true;
624 info->isMulticastServer = false;
625 OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress);
627 CAResult_t res = CAAddServerInfo(g_serverInfoList, info);
628 if (CA_STATUS_OK != res)
630 OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
631 close(unicastServerFd);
632 ca_mutex_unlock(g_mutexServerInfoList);
635 ca_mutex_unlock(g_mutexServerInfoList);
637 res = CAIPStartPacketReceiverHandler();
638 if (CA_STATUS_OK != res)
640 OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
641 close(unicastServerFd);
647 OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Already Unicast Server Started ip [%s] port [%d]",
648 localAddress, *port);
649 ca_mutex_unlock(g_mutexServerInfoList);
652 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
656 CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
657 uint16_t multicastPort)
659 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
662 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
663 VERIFY_NON_NULL(multicastAddress, IP_SERVER_TAG, "port");
665 uint16_t port = multicastPort;
668 OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: Multicast port is invalid!");
669 return CA_STATUS_INVALID_PARAM;
672 ca_mutex_lock(g_mutexServerInfoList);
673 bool isMulticastServerStarted = CAIsMulticastServerStarted(g_serverInfoList, localAddress,
674 multicastAddress, port);
675 if (!isMulticastServerStarted)
677 int mulicastServerFd = -1;
678 CAResult_t ret = CACreateSocket(&mulicastServerFd, multicastAddress, &port);
679 if (ret != CA_STATUS_OK)
681 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create multicast socket");
682 ca_mutex_unlock(g_mutexServerInfoList);
686 struct ip_mreq multicastMemberReq = {.imr_interface.s_addr = inet_addr(localAddress)};
687 inet_aton(multicastAddress, &multicastMemberReq.imr_multiaddr);
689 if (-1 == setsockopt(mulicastServerFd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
690 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
692 OIC_LOG_V(ERROR, IP_SERVER_TAG,
693 "Failed to add to multicast group, Error code: %s\n", strerror(errno));
694 close(mulicastServerFd);
695 ca_mutex_unlock(g_mutexServerInfoList);
696 return CA_STATUS_FAILED;
699 CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
702 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
703 close(mulicastServerFd);
704 ca_mutex_unlock(g_mutexServerInfoList);
705 return CA_MEMORY_ALLOC_FAILED;
708 char *netMask = NULL;
709 if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
711 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
715 OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask);
719 OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), multicastAddress);
720 info->endpoint.port = multicastPort;
721 info->endpoint.flags = 0;
722 info->socketFd = mulicastServerFd;
723 info->isServerStarted = true;
724 info->isMulticastServer = true;
725 OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress);
727 ret = CAAddServerInfo(g_serverInfoList, info);
729 if (CA_STATUS_OK != ret)
731 OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
732 close(mulicastServerFd);
733 ca_mutex_unlock(g_mutexServerInfoList);
736 ca_mutex_unlock(g_mutexServerInfoList);
738 ret = CAIPStartPacketReceiverHandler();
739 if (CA_STATUS_OK != ret)
741 OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
742 close(mulicastServerFd);
748 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
749 "Multicast Server is already started on interface addr[%s]", localAddress);
750 ca_mutex_unlock(g_mutexServerInfoList);
753 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
757 CAResult_t CAIPStopServer(const char *interfaceAddress)
759 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
761 VERIFY_NON_NULL(interfaceAddress, IP_SERVER_TAG, "interfaceAddress is NULL");
763 ca_mutex_lock(g_mutexServerInfoList);
764 uint32_t listIndex = 0;
765 uint32_t listLength = u_arraylist_length(g_serverInfoList);
767 for (listIndex = 0; listIndex < listLength;)
769 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
776 if (info->isMulticastServer && strncmp(interfaceAddress, info->ifAddr, strlen(info->ifAddr))
779 if (u_arraylist_remove(g_serverInfoList, listIndex))
781 struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
783 multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
784 inet_aton(info->endpoint.addr, &multicastMemberReq.imr_multiaddr);
785 if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
786 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
788 OIC_LOG_V(ERROR, IP_SERVER_TAG,
789 "Failed to leave multicast group, Error code: %s", strerror(errno));
791 CACloseSocket(info->socketFd);
793 OIC_LOG(DEBUG, IP_SERVER_TAG, "Multicast server is stopped successfully.");
794 // Reduce list length by 1 as we removed one element.
799 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
800 ca_mutex_unlock(g_mutexServerInfoList);
801 return CA_STATUS_FAILED;
804 else if (strncmp(interfaceAddress, info->endpoint.addr, strlen(info->endpoint.addr)) == 0)
806 if (u_arraylist_remove(g_serverInfoList, listIndex))
808 CACloseSocket(info->socketFd);
810 OIC_LOG(DEBUG, IP_SERVER_TAG, "Unicast server is stopped successfully.");
811 // Reduce list length by 1 as we removed one element.
816 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
817 ca_mutex_unlock(g_mutexServerInfoList);
818 return CA_STATUS_FAILED;
827 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
828 ca_mutex_unlock(g_mutexServerInfoList);
832 CAResult_t CAIPStopAllServers()
834 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
836 g_packetHandlerStopFlag = true;
838 ca_mutex_lock(g_mutexServerInfoList);
840 uint32_t listIndex = 0;
841 uint32_t listLength = u_arraylist_length(g_serverInfoList);
842 for (listIndex = 0; listIndex < listLength;)
844 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
850 if (u_arraylist_remove(g_serverInfoList, listIndex))
852 if (info->isMulticastServer)
854 struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
856 multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
857 inet_aton(info->endpoint.addr, &multicastMemberReq.imr_multiaddr);
858 if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
859 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
861 OIC_LOG_V(ERROR, IP_SERVER_TAG,
862 "Failed to leave multicast group, Error code: %s", strerror(errno));
865 CACloseSocket(info->socketFd);
866 //Freeing server info.
868 // Reduce list length by 1 as we removed one element.
873 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
874 ca_mutex_unlock(g_mutexServerInfoList);
875 return CA_STATUS_FAILED;
879 ca_mutex_unlock(g_mutexServerInfoList);
881 OIC_LOG(DEBUG, IP_SERVER_TAG, "All Server stopped successfully. OUT");
885 uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured)
887 ca_mutex_lock(g_mutexServerInfoList);
889 uint16_t port = CAGetServerPort(g_serverInfoList, ipAddress, isSecured);
891 ca_mutex_unlock(g_mutexServerInfoList);
896 CAResult_t CAGetIPServerInfoList(u_arraylist_t **serverInfoList)
898 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
899 ca_mutex_lock(g_mutexServerInfoList);
901 uint32_t list_index = 0;
902 uint32_t list_length = u_arraylist_length(g_serverInfoList);
903 for (list_index = 0; list_index < list_length; list_index++)
905 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, list_index);
911 CAServerInfo_t *newNetinfo = (CAServerInfo_t *) OICMalloc(sizeof(CAServerInfo_t));
914 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed!");
915 ca_mutex_unlock(g_mutexServerInfoList);
916 return CA_MEMORY_ALLOC_FAILED;
921 CAResult_t result = u_arraylist_add(*serverInfoList, (void *) newNetinfo);
922 if (CA_STATUS_OK != result)
924 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_add failed!");
925 ca_mutex_unlock(g_mutexServerInfoList);
926 return CA_STATUS_FAILED;
929 ca_mutex_unlock(g_mutexServerInfoList);
930 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
934 void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
936 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
938 ca_mutex_lock(g_mutexAdapterServerContext);
940 if (g_adapterIPServerContext)
942 g_adapterIPServerContext->packetReceivedCallback = callback;
946 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
949 ca_mutex_unlock(g_mutexAdapterServerContext);
951 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
954 void CAIPSetErrorHandleCallback(CAIPErrorHandleCallback ipErrorCallback)
956 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
958 ca_mutex_lock(g_mutexAdapterServerContext);
960 if (g_adapterIPServerContext)
962 g_adapterIPServerContext->IPErrorCallback = ipErrorCallback;
965 ca_mutex_unlock(g_mutexAdapterServerContext);
967 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
970 void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
972 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
973 ca_mutex_lock(g_mutexAdapterServerContext);
975 if (g_adapterIPServerContext)
977 g_adapterIPServerContext->exceptionCallback = callback;
981 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
984 ca_mutex_unlock(g_mutexAdapterServerContext);
986 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");