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);
269 ep.flags = (CATransportFlags_t)CA_IPV4 | CA_IPV6;
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, bool isSecured)
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;
334 if (0 != *port && !isSecured)
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 bool isBound = false;
357 if (-1 != bind(sock, (struct sockaddr *) &sockAddr, sizeof(sockAddr)))
363 //if secure port 5684 is occupied, trying for another port
365 sockAddr.sin_port = htons(serverPort);
366 if (-1 != bind(sock, (struct sockaddr *) &sockAddr, sizeof(sockAddr)))
374 struct sockaddr_in sin;
375 socklen_t len = sizeof(sin);
377 if (-1 == getsockname(sock, (struct sockaddr *)&sin, &len))
379 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to get socket[%s]!",
382 return CA_STATUS_FAILED;
386 serverPort = (uint16_t) ntohs(sin.sin_port);
391 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to bind socket[%s]!", strerror(errno));
393 return CA_STATUS_FAILED;
401 static void CACloseSocket(int socketFD)
405 OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid Socket Fd");
410 if (-1 == close(socketFD))
412 OIC_LOG_V(ERROR, IP_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
417 static CAResult_t CAStartUnicastServer(const char *localAddress, uint16_t *port,
418 bool isSecured, int *serverFD)
420 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
422 VERIFY_NON_NULL(serverFD, IP_SERVER_TAG, "serverFD");
423 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
424 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
426 CAResult_t ret = CACreateSocket(serverFD, localAddress, port, isSecured);
427 if (CA_STATUS_OK != ret)
429 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create unicast socket");
432 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
436 static CAResult_t CAIPStartPacketReceiverHandler()
438 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
440 ca_mutex_lock(g_mutexServerInfoList);
442 uint32_t listLength = u_arraylist_length(g_serverInfoList);
444 ca_mutex_unlock(g_mutexServerInfoList);
446 ca_mutex_lock(g_mutexAdapterServerContext);
448 if (!g_adapterIPServerContext)
450 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
451 ca_mutex_unlock(g_mutexAdapterServerContext);
452 return CA_STATUS_FAILED;
455 if (1 == listLength) //Its first time.
457 g_packetHandlerStopFlag = false;
458 if (CA_STATUS_OK != ca_thread_pool_add_task(g_adapterIPServerContext->threadPool,
459 CAReceiveHandler, NULL ))
461 OIC_LOG(ERROR, IP_SERVER_TAG, "thread_pool_add_task failed!");
462 ca_mutex_unlock(g_mutexAdapterServerContext);
463 return CA_STATUS_FAILED;
465 OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread started successfully.");
469 OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread already is running");
471 ca_mutex_unlock(g_mutexAdapterServerContext);
473 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
478 static void CAIPServerDestroyMutex(void)
480 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
482 if (g_mutexServerInfoList)
484 ca_mutex_free(g_mutexServerInfoList);
485 g_mutexServerInfoList = NULL;
488 if (g_mutexAdapterServerContext)
490 ca_mutex_free(g_mutexAdapterServerContext);
491 g_mutexAdapterServerContext = NULL;
494 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
497 static CAResult_t CAIPServerCreateMutex(void)
499 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
501 g_mutexServerInfoList = ca_mutex_new();
502 if (!g_mutexServerInfoList)
504 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
505 return CA_MEMORY_ALLOC_FAILED;
508 g_mutexAdapterServerContext = ca_mutex_new();
509 if (!g_mutexAdapterServerContext)
511 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to created mutex!");
512 ca_mutex_free(g_mutexServerInfoList);
513 g_mutexServerInfoList = NULL;
514 return CA_MEMORY_ALLOC_FAILED;
517 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
521 CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool)
523 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
526 VERIFY_NON_NULL(threadPool, IP_SERVER_TAG, "Thread pool handle is NULL");
529 if (CA_STATUS_OK != CAIPServerCreateMutex())
531 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create mutex!");
532 return CA_STATUS_FAILED;
535 ca_mutex_lock(g_mutexAdapterServerContext);
536 g_adapterIPServerContext = (CAAdapterIPServerContext_t *) OICCalloc(1,
537 sizeof(CAAdapterIPServerContext_t));
539 if (!g_adapterIPServerContext)
541 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
542 ca_mutex_unlock(g_mutexAdapterServerContext);
543 return CA_MEMORY_ALLOC_FAILED;
546 g_adapterIPServerContext->threadPool = threadPool;
548 ca_mutex_unlock(g_mutexAdapterServerContext);
550 ca_mutex_lock(g_mutexServerInfoList);
552 g_serverInfoList = u_arraylist_create();
553 if (!g_serverInfoList)
555 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_create failed");
556 ca_mutex_unlock(g_mutexServerInfoList);
557 return CA_MEMORY_ALLOC_FAILED;
559 ca_mutex_unlock(g_mutexServerInfoList);
560 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
564 void CAIPTerminateServer()
566 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
567 ca_mutex_lock(g_mutexAdapterServerContext);
568 if (!g_adapterIPServerContext)
570 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
571 ca_mutex_unlock(g_mutexAdapterServerContext);
575 OICFree(g_adapterIPServerContext);
576 g_adapterIPServerContext = NULL;
578 ca_mutex_unlock(g_mutexAdapterServerContext);
580 ca_mutex_lock(g_mutexServerInfoList);
582 CAClearServerInfoList(g_serverInfoList);
583 g_serverInfoList = NULL;
585 ca_mutex_unlock(g_mutexServerInfoList);
587 CAIPServerDestroyMutex();
589 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
593 CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, bool isSecured)
595 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
598 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
599 VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");
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, 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 OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask);
633 OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), localAddress);
634 info->endpoint.port = *port;
635 info->endpoint.flags = isSecured ? CA_SECURE : 0;
636 info->endpoint.adapter = CA_ADAPTER_IP;
637 info->socketFd = unicastServerFd;
638 info->isServerStarted = true;
639 info->isMulticastServer = false;
640 OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress);
642 CAResult_t res = CAAddServerInfo(g_serverInfoList, info);
643 if (CA_STATUS_OK != res)
645 OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
646 close(unicastServerFd);
647 ca_mutex_unlock(g_mutexServerInfoList);
650 ca_mutex_unlock(g_mutexServerInfoList);
652 res = CAIPStartPacketReceiverHandler();
653 if (CA_STATUS_OK != res)
655 OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
656 close(unicastServerFd);
662 OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Already Unicast Server Started ip [%s] port [%d]",
663 localAddress, *port);
664 ca_mutex_unlock(g_mutexServerInfoList);
667 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
671 CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
672 uint16_t multicastPort)
674 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
677 VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
678 VERIFY_NON_NULL(multicastAddress, IP_SERVER_TAG, "port");
680 uint16_t port = multicastPort;
683 OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: Multicast port is invalid!");
684 return CA_STATUS_INVALID_PARAM;
687 ca_mutex_lock(g_mutexServerInfoList);
688 bool isMulticastServerStarted = CAIsMulticastServerStarted(g_serverInfoList, localAddress,
689 multicastAddress, port);
690 if (!isMulticastServerStarted)
692 int mulicastServerFd = -1;
693 CAResult_t ret = CACreateSocket(&mulicastServerFd, multicastAddress, &port, false);
694 if (ret != CA_STATUS_OK)
696 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create multicast socket");
697 ca_mutex_unlock(g_mutexServerInfoList);
701 struct ip_mreq multicastMemberReq = {.imr_interface.s_addr = inet_addr(localAddress)};
702 inet_aton(multicastAddress, &multicastMemberReq.imr_multiaddr);
704 if (-1 == setsockopt(mulicastServerFd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
705 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
707 OIC_LOG_V(ERROR, IP_SERVER_TAG,
708 "Failed to add to multicast group, Error code: %s\n", strerror(errno));
709 close(mulicastServerFd);
710 ca_mutex_unlock(g_mutexServerInfoList);
711 return CA_STATUS_FAILED;
714 CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
717 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
718 close(mulicastServerFd);
719 ca_mutex_unlock(g_mutexServerInfoList);
720 return CA_MEMORY_ALLOC_FAILED;
723 char *netMask = NULL;
724 if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
726 OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
730 OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask);
734 OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), multicastAddress);
735 info->endpoint.port = multicastPort;
736 info->endpoint.flags = 0;
737 info->socketFd = mulicastServerFd;
738 info->isServerStarted = true;
739 info->isMulticastServer = true;
740 OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress);
742 ret = CAAddServerInfo(g_serverInfoList, info);
744 if (CA_STATUS_OK != ret)
746 OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
747 close(mulicastServerFd);
748 ca_mutex_unlock(g_mutexServerInfoList);
751 ca_mutex_unlock(g_mutexServerInfoList);
753 ret = CAIPStartPacketReceiverHandler();
754 if (CA_STATUS_OK != ret)
756 OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
757 close(mulicastServerFd);
763 OIC_LOG_V(DEBUG, IP_SERVER_TAG,
764 "Multicast Server is already started on interface addr[%s]", localAddress);
765 ca_mutex_unlock(g_mutexServerInfoList);
768 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
772 CAResult_t CAIPStopServer(const char *interfaceAddress)
774 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
776 VERIFY_NON_NULL(interfaceAddress, IP_SERVER_TAG, "interfaceAddress is NULL");
778 ca_mutex_lock(g_mutexServerInfoList);
779 uint32_t listIndex = 0;
780 uint32_t listLength = u_arraylist_length(g_serverInfoList);
782 for (listIndex = 0; listIndex < listLength;)
784 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
791 if (info->isMulticastServer && strncmp(interfaceAddress, info->ifAddr, strlen(info->ifAddr))
794 if (u_arraylist_remove(g_serverInfoList, listIndex))
796 struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
798 multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
799 inet_aton(info->endpoint.addr, &multicastMemberReq.imr_multiaddr);
800 if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
801 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
803 OIC_LOG_V(ERROR, IP_SERVER_TAG,
804 "Failed to leave multicast group, Error code: %s", strerror(errno));
806 CACloseSocket(info->socketFd);
808 OIC_LOG(DEBUG, IP_SERVER_TAG, "Multicast server is stopped successfully.");
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->endpoint.addr, strlen(info->endpoint.addr)) == 0)
821 if (u_arraylist_remove(g_serverInfoList, listIndex))
823 CACloseSocket(info->socketFd);
825 OIC_LOG(DEBUG, IP_SERVER_TAG, "Unicast server is stopped successfully.");
826 // Reduce list length by 1 as we removed one element.
831 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
832 ca_mutex_unlock(g_mutexServerInfoList);
833 return CA_STATUS_FAILED;
842 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
843 ca_mutex_unlock(g_mutexServerInfoList);
847 CAResult_t CAIPStopAllServers()
849 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
851 g_packetHandlerStopFlag = true;
853 ca_mutex_lock(g_mutexServerInfoList);
855 uint32_t listIndex = 0;
856 uint32_t listLength = u_arraylist_length(g_serverInfoList);
857 for (listIndex = 0; listIndex < listLength;)
859 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
865 if (u_arraylist_remove(g_serverInfoList, listIndex))
867 if (info->isMulticastServer)
869 struct ip_mreq multicastMemberReq = { { 0 }, { 0 } };
871 multicastMemberReq.imr_interface.s_addr = inet_addr(info->ifAddr);
872 inet_aton(info->endpoint.addr, &multicastMemberReq.imr_multiaddr);
873 if (-1 == setsockopt(info->socketFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
874 (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
876 OIC_LOG_V(ERROR, IP_SERVER_TAG,
877 "Failed to leave multicast group, Error code: %s", strerror(errno));
880 CACloseSocket(info->socketFd);
881 //Freeing server info.
883 // Reduce list length by 1 as we removed one element.
888 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_remove failed.");
889 ca_mutex_unlock(g_mutexServerInfoList);
890 return CA_STATUS_FAILED;
894 ca_mutex_unlock(g_mutexServerInfoList);
896 OIC_LOG(DEBUG, IP_SERVER_TAG, "All Server stopped successfully. OUT");
902 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
903 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
906 uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured)
908 ca_mutex_lock(g_mutexServerInfoList);
910 uint16_t port = CAGetServerPort(g_serverInfoList, ipAddress, isSecured);
912 ca_mutex_unlock(g_mutexServerInfoList);
917 CAResult_t CAGetIPServerInfoList(u_arraylist_t **serverInfoList)
919 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
920 ca_mutex_lock(g_mutexServerInfoList);
922 uint32_t list_index = 0;
923 uint32_t list_length = u_arraylist_length(g_serverInfoList);
924 for (list_index = 0; list_index < list_length; list_index++)
926 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, list_index);
932 CAServerInfo_t *newNetinfo = (CAServerInfo_t *) OICMalloc(sizeof(CAServerInfo_t));
935 OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed!");
936 ca_mutex_unlock(g_mutexServerInfoList);
937 return CA_MEMORY_ALLOC_FAILED;
942 CAResult_t result = u_arraylist_add(*serverInfoList, (void *) newNetinfo);
943 if (CA_STATUS_OK != result)
945 OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_add failed!");
946 ca_mutex_unlock(g_mutexServerInfoList);
947 return CA_STATUS_FAILED;
950 ca_mutex_unlock(g_mutexServerInfoList);
951 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
955 void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
957 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
959 ca_mutex_lock(g_mutexAdapterServerContext);
961 if (g_adapterIPServerContext)
963 g_adapterIPServerContext->packetReceivedCallback = callback;
967 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
970 ca_mutex_unlock(g_mutexAdapterServerContext);
972 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
975 void CAIPSetErrorHandleCallback(CAIPErrorHandleCallback ipErrorCallback)
977 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
979 ca_mutex_lock(g_mutexAdapterServerContext);
981 if (g_adapterIPServerContext)
983 g_adapterIPServerContext->IPErrorCallback = ipErrorCallback;
986 ca_mutex_unlock(g_mutexAdapterServerContext);
988 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
991 void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
993 OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");
994 ca_mutex_lock(g_mutexAdapterServerContext);
996 if (g_adapterIPServerContext)
998 g_adapterIPServerContext->exceptionCallback = callback;
1002 OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
1005 ca_mutex_unlock(g_mutexAdapterServerContext);
1007 OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");