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 // Defining _POSIX_C_SOURCE macro with 200809L (or greater) as value
22 // causes header files to expose definitions
23 // corresponding to the POSIX.1-2008 base
24 // specification (excluding the XSI extension).
25 // For POSIX.1-2008 base specification,
26 // Refer http://pubs.opengroup.org/stage7tc1/
28 // For this specific file, see use of strndup,
29 // Refer http://man7.org/linux/man-pages/man3/strdup.3.html
30 #ifndef _POSIX_C_SOURCE
31 #define _POSIX_C_SOURCE 200809L
34 // Defining _BSD_SOURCE or _DEFAULT_SOURCE causes header files to expose
35 // definitions that may otherwise be skipped. Skipping can cause implicit
36 // declaration warnings and/or bugs and subtle problems in code execution.
37 // For glibc information on feature test macros,
38 // Refer http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html
40 // This file requires #define use due to struct ip_mreq
41 #define _DEFAULT_SOURCE
43 #include <netinet/in.h>
45 #include "caethernetinterface.h"
47 #include <sys/types.h>
48 #include <sys/socket.h>
51 #include <sys/select.h>
52 #include <arpa/inet.h>
58 #include "caadapterutils.h"
60 #include "caadapternetdtls.h"
63 #include "oic_malloc.h"
66 * @def ETHERNET_SERVER_TAG
67 * @brief Logging tag for module name
69 #define ETHERNET_SERVER_TAG "ETHERNET_SERVER"
72 * @def CA_UDP_BIND_RETRY_COUNT
73 * @brief Retry count in case of socket bind failure.
75 #define CA_UDP_BIND_RETRY_COUNT 10
79 * @brief max length for ip
84 * @var g_unicastServerSocketFD
85 * @brief Unicast server socket descriptor
87 static int32_t g_unicastServerSocketFD = -1;
90 * @var g_mutexUnicastServer
91 * @brief Mutex to synchronize unicast server
93 static u_mutex g_mutexUnicastServer = NULL;
97 * @brief Flag to control the Receive Unicast Data Thread
99 static bool g_stopUnicast = false;
102 * @var g_multicastServerSocketFD
103 * @brief socket descriptor for multicast server
105 static int32_t g_multicastServerSocketFD = -1;
108 * @var g_mutexMulticastServer
109 * @brief Mutex to synchronize secure multicast server
111 static u_mutex g_mutexMulticastServer = NULL;
114 * @var g_stopMulticast
115 * @brief Flag to control the Receive Multicast Data Thread
117 static bool g_stopMulticast = false;
121 * @var g_secureUnicastServerSocketFD
122 * @brief Secure unicast server socket descriptor
124 static int32_t g_secureUnicastServerSocketFD = -1;
127 * @var g_mutexSecureUnicastServer
128 * @brief Mutex to synchronize secure unicast server
130 static u_mutex g_mutexSecureUnicastServer = NULL;
133 * @var g_stopSecureUnicast
134 * @brief Flag to control the unicast secure data receive thread
136 static bool g_stopSecureUnicast = false;
141 * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
143 static u_thread_pool_t g_threadPool = NULL;
146 * @var g_multicastServerInterface
147 * @brief Local interface on which multicast server is running
149 static char g_multicastServerInterface[IPNAMESIZE];
152 * @var g_multicastMemberReq
153 * @brief ip_mreq structure passed to join a multicast group
155 static struct ip_mreq g_multicastMemberReq;
158 * @var g_packetReceivedCallback
159 * @brief Callback for notifying the upper layer on receival data from remote OIC device
161 static CAEthernetPacketReceivedCallback g_packetReceivedCallback = NULL;
164 * @var g_exceptionCallback
165 * @brief Callback for notifying the upper layer when unicast/multicast server encounters exception
167 static CAEthernetExceptionCallback g_exceptionCallback = NULL;
170 @brief Thread context information for unicast, multicast and secured unicast server
176 CAAdapterServerType_t type;
177 } CAAdapterReceiveThreadContext_t;
179 static void CAReceiveHandler(void *data)
181 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
184 VERIFY_NON_NULL_VOID(data, ETHERNET_SERVER_TAG, "Invalid thread context");
186 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)data;
188 struct timeval timeout;
189 char recvBuffer[COAP_MAX_PDU_SIZE] = {0};
191 while (true != *(ctx->stopFlag))
197 FD_SET(ctx->socket_fd, &reads);
199 int32_t ret = select(ctx->socket_fd + 1, &reads, NULL, NULL, &timeout);
200 if (*(ctx->stopFlag) == true)
202 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG,
203 "Stop request received for [%d] server", ctx->type);
209 OIC_LOG_V(FATAL, ETHERNET_SERVER_TAG, "select returned error %s", strerror(errno));
213 if (!FD_ISSET(ctx->socket_fd, &reads))
218 memset(recvBuffer, 0, sizeof(recvBuffer));
220 // Read data from socket
221 struct sockaddr_in srcSockAddress;
223 socklen_t srcAddressLen = sizeof(srcSockAddress);
225 recvLen = recvfrom(ctx->socket_fd, recvBuffer,
226 sizeof(recvBuffer), 0, (struct sockaddr *) &srcSockAddress,
231 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "%s", strerror(errno));
234 else if (0 == recvLen)
236 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Server socket shutdown [%d]!", ctx->type);
238 // Notify upper layer this exception
239 if (g_exceptionCallback)
241 g_exceptionCallback(ctx->type);
248 char srcIPAddress[CA_IPADDR_SIZE] = {0};
249 inet_ntop(AF_INET, &srcSockAddress.sin_addr.s_addr, srcIPAddress, sizeof(srcIPAddress));
250 uint16_t srcPort = 0;
251 srcPort = ntohs(srcSockAddress.sin_port);
253 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Received packet from %s:%d\n",
254 srcIPAddress, srcPort);
255 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
256 recvBuffer, recvLen);
258 char *netMask = NULL;
259 if (CA_STATUS_OK != CAEthernetGetInterfaceSubnetMask(&netMask))
261 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to get ethernet subnet");
265 if (!CAAdapterIsSameSubnet(g_multicastServerInterface, srcIPAddress, netMask))
267 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "Packet received from different subnet, Ignore!");
279 case CA_UNICAST_SERVER:
280 case CA_MULTICAST_SERVER:
281 // Notify data to upper layer
282 if (g_packetReceivedCallback)
284 g_packetReceivedCallback(srcIPAddress, srcPort, recvBuffer, recvLen, false);
288 case CA_SECURED_UNICAST_SERVER:
290 CAResult_t ret = CAAdapterNetDtlsDecrypt(srcIPAddress,
292 (uint8_t *)recvBuffer,
293 recvLen, DTLS_ETHERNET);
294 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG,
295 "CAAdapterNetDtlsDecrypt returns [%d]", ret);
298 #endif //__WITH_DTLS__
300 // Should never occur
301 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Invalid server type");
311 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
314 static CAResult_t CACreateSocket(int32_t *socketFD, const char *localIp, uint16_t *port,
318 // Create a UDP socket
319 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
322 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to create Socket, Error code: %s",
324 return CA_STATUS_FAILED;
327 // Make the socket non-blocking
328 if (-1 == fcntl(sock, F_SETFL, O_NONBLOCK))
330 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
334 return CA_STATUS_FAILED;
337 if (true == forceStart)
339 int32_t setOptionOn = 1;
340 if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
341 (char *) &setOptionOn,
342 sizeof(setOptionOn)))
344 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
348 return CA_STATUS_FAILED;
352 struct sockaddr_in sockAddr;
353 bool isBound = false;
354 uint16_t serverPort = *port;
356 memset(&sockAddr, 0, sizeof(sockAddr));
357 sockAddr.sin_family = AF_INET;
358 sockAddr.sin_port = htons(serverPort);
361 sockAddr.sin_addr.s_addr = inet_addr(localIp);
365 sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
369 for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
371 if (-1 == bind(sock, (struct sockaddr *) &sockAddr,
374 if (false == forceStart)
376 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind socket[%s]. Trying again..",
379 //Set the port to next one
381 sockAddr.sin_port = htons(serverPort);
386 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind socket[%s]!",
396 if (false == isBound)
399 return CA_STATUS_FAILED;
407 static CAResult_t CACloseSocket(int32_t *socketFD)
409 if (socketFD == NULL)
411 return CA_STATUS_INVALID_PARAM;
416 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Server not running");
417 return CA_SERVER_NOT_STARTED;
421 if (-1 == close(*socketFD))
423 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
425 return CA_STATUS_FAILED;
432 static CAResult_t CAStartUnicastServer(const char *localAddress, uint16_t *port,
433 const bool forceStart, bool isSecured, int32_t *serverFD)
435 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
437 if (serverFD == NULL)
439 return CA_STATUS_INVALID_PARAM;
442 CAResult_t ret = CACreateSocket(serverFD, localAddress, port, forceStart);
443 if (CA_STATUS_OK != ret)
445 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create unicast socket");
450 * The task to listen for data from unicast socket is added to the thread pool.
451 * This is a blocking call is made where we try to receive some data..
452 * We will keep waiting until some data is received.
453 * This task will be terminated when thread pool is freed on stopping the adapters.
454 * Thread context will be freed by thread on exit.
456 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
457 OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
460 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Out of memory!");
462 return CA_MEMORY_ALLOC_FAILED;
465 ctx->stopFlag = &g_stopUnicast;
466 ctx->socket_fd = *serverFD;
467 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
468 if (CA_STATUS_OK != u_thread_pool_add_task(g_threadPool, CAReceiveHandler, (void *)ctx))
470 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create read thread!");
474 return CA_STATUS_FAILED;
477 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
481 static void CAEthernetServerDestroyMutex(void)
483 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
485 if (g_mutexUnicastServer)
487 u_mutex_free(g_mutexUnicastServer);
488 g_mutexUnicastServer = NULL;
492 if (g_mutexSecureUnicastServer)
494 u_mutex_free(g_mutexSecureUnicastServer);
495 g_mutexSecureUnicastServer = NULL;
499 if (g_mutexMulticastServer)
501 u_mutex_free(g_mutexMulticastServer);
502 g_mutexMulticastServer = NULL;
505 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
508 static CAResult_t CAEthernetServerCreateMutex(void)
510 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
512 if(g_mutexUnicastServer) {
513 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "mutex is already created!");
515 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
516 return CA_STATUS_FAILED;
519 g_mutexUnicastServer = u_mutex_new();
520 if (!g_mutexUnicastServer)
522 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
523 return CA_STATUS_FAILED;
527 g_mutexSecureUnicastServer = u_mutex_new();
528 if (!g_mutexSecureUnicastServer)
530 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
532 CAEthernetServerDestroyMutex();
533 return CA_STATUS_FAILED;
537 g_mutexMulticastServer = u_mutex_new();
538 if (!g_mutexMulticastServer)
540 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
542 CAEthernetServerDestroyMutex();
543 return CA_STATUS_FAILED;
546 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
550 CAResult_t CAEthernetInitializeServer(const u_thread_pool_t threadPool)
552 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
555 VERIFY_NON_NULL(threadPool, ETHERNET_SERVER_TAG, "Thread pool handle is NULL");
558 if (CA_STATUS_OK != CAEthernetServerCreateMutex())
560 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create mutex!");
561 return CA_STATUS_FAILED;
564 g_threadPool = threadPool;
566 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
570 void CAEthernetTerminateServer(void)
572 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
577 CAEthernetServerDestroyMutex();
579 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
582 CAResult_t CAEthernetStartUnicastServer(const char *localAddress, uint16_t *port,
583 bool forceStart, bool isSecured, int32_t *serverFD)
585 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
588 VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "localAddress");
589 VERIFY_NON_NULL(port, ETHERNET_SERVER_TAG, "port");
590 VERIFY_NON_NULL(serverFD, ETHERNET_SERVER_TAG, "server socket FD");
594 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Invalid input: port is invalid!");
595 return CA_STATUS_INVALID_PARAM;
599 if (false == isSecured)
601 u_mutex_lock(g_mutexUnicastServer);
602 if (-1 != g_unicastServerSocketFD)
604 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Unicast Server is Started Already!",
605 CA_SERVER_STARTED_ALREADY);
607 *serverFD = g_unicastServerSocketFD;
608 u_mutex_unlock(g_mutexUnicastServer);
609 return CA_SERVER_STARTED_ALREADY;
612 g_stopUnicast = false;
613 if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart, isSecured,
614 &g_unicastServerSocketFD))
616 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to start unicast server!");
617 g_unicastServerSocketFD = -1;
618 u_mutex_unlock(g_mutexUnicastServer);
619 return CA_STATUS_FAILED;
622 *serverFD = g_unicastServerSocketFD;
623 u_mutex_unlock(g_mutexUnicastServer);
626 else // Start unicast server for secured communication
628 u_mutex_lock(g_mutexSecureUnicastServer);
629 if (-1 != g_secureUnicastServerSocketFD)
631 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Unicast Server is Started Already!",
632 CA_SERVER_STARTED_ALREADY);
634 *serverFD = g_secureUnicastServerSocketFD;
635 u_mutex_unlock(g_mutexSecureUnicastServer);
636 return CA_SERVER_STARTED_ALREADY;
639 g_stopSecureUnicast = false;
640 if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart, isSecured,
641 &g_secureUnicastServerSocketFD))
643 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to start unicast server!");
644 g_secureUnicastServerSocketFD = -1;
645 u_mutex_unlock(g_mutexSecureUnicastServer);
646 return CA_STATUS_FAILED;
649 *serverFD = g_secureUnicastServerSocketFD;
650 u_mutex_unlock(g_mutexSecureUnicastServer);
653 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
657 CAResult_t CAEthernetStartMulticastServer(const char *localAddress,
658 const char *multicastAddress, const uint16_t multicastPort, int32_t *serverFD)
660 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
663 VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "localAddress");
664 VERIFY_NON_NULL(multicastAddress, ETHERNET_SERVER_TAG, "port");
665 VERIFY_NON_NULL(serverFD, ETHERNET_SERVER_TAG, "server socket FD");
667 uint16_t port = multicastPort;
670 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Invalid input: Multicast port is invalid!");
671 return CA_STATUS_INVALID_PARAM;
674 u_mutex_lock(g_mutexMulticastServer);
676 if (g_multicastServerSocketFD != -1)
678 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast Server is already running!");
679 u_mutex_unlock(g_mutexMulticastServer);
680 return CA_SERVER_STARTED_ALREADY;
683 CAResult_t ret = CACreateSocket(&g_multicastServerSocketFD, multicastAddress, &port, true);
684 if (ret != CA_STATUS_OK)
686 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create multicast socket");
687 u_mutex_unlock(g_mutexMulticastServer);
691 // Add membership to receiving socket (join group)
692 memset(&g_multicastMemberReq, 0, sizeof(struct ip_mreq));
693 g_multicastMemberReq.imr_interface.s_addr = inet_addr(localAddress);
694 inet_aton(multicastAddress, &g_multicastMemberReq.imr_multiaddr);
696 if (-1 == setsockopt(g_multicastServerSocketFD, IPPROTO_IP, IP_ADD_MEMBERSHIP,
697 (char *) &g_multicastMemberReq,
698 sizeof(struct ip_mreq)))
700 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
702 close(g_multicastServerSocketFD);
703 g_multicastServerSocketFD = -1;
704 u_mutex_unlock(g_mutexMulticastServer);
705 return CA_STATUS_FAILED;
709 * The task to listen to data from multicastcast socket is added to the thread pool.
710 * This is a blocking call is made where we try to receive some data.
711 * We will keep waiting until some data is received.
712 * This task will be terminated when thread pool is freed on stopping the adapters.
713 * Thread context will be freed by thread on exit.
715 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
716 OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
719 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Out of memory!");
720 close(g_multicastServerSocketFD);
721 g_multicastServerSocketFD = -1;
722 return CA_MEMORY_ALLOC_FAILED;
725 ctx->stopFlag = &g_stopMulticast;
726 ctx->socket_fd = g_multicastServerSocketFD;
727 ctx->type = CA_MULTICAST_SERVER;
729 g_stopMulticast = false;
730 if (CA_STATUS_OK != u_thread_pool_add_task(g_threadPool, CAReceiveHandler, (void *)ctx))
732 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "thread_pool_add_task failed!");
734 close(g_multicastServerSocketFD);
735 g_multicastServerSocketFD = -1;
736 g_stopMulticast = true;
737 u_mutex_unlock(g_mutexMulticastServer);
738 return CA_STATUS_FAILED;
741 *serverFD = g_multicastServerSocketFD;
742 strncpy(g_multicastServerInterface, localAddress, IPNAMESIZE);
743 u_mutex_unlock(g_mutexMulticastServer);
745 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
749 CAResult_t CAEthernetStopUnicastServer()
751 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
753 u_mutex_lock(g_mutexUnicastServer);
754 g_stopUnicast = true;
755 CAResult_t ret = CACloseSocket(&g_unicastServerSocketFD);
756 u_mutex_unlock(g_mutexUnicastServer);
758 OIC_LOG_V(INFO, ETHERNET_SERVER_TAG, "Unicast server stopped [%d]", ret);
763 CAResult_t CAEthernetStopSecureUnicastServer()
765 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
767 u_mutex_lock(g_mutexSecureUnicastServer);
768 g_stopSecureUnicast = true;
769 CAResult_t ret = CACloseSocket(&g_secureUnicastServerSocketFD);
770 u_mutex_unlock(g_mutexSecureUnicastServer);
772 OIC_LOG_V(INFO, ETHERNET_SERVER_TAG, "Secured unicast server stopped [%d]", ret);
777 CAResult_t CAEthernetStopMulticastServer(void)
779 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
781 u_mutex_lock(g_mutexMulticastServer);
783 if (g_multicastServerSocketFD == -1)
785 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast server is not yet started");
786 u_mutex_unlock(g_mutexMulticastServer);
787 return CA_SERVER_NOT_STARTED;
790 g_stopMulticast = true;
792 // leave the group after you are done
793 if (-1 == setsockopt(g_multicastServerSocketFD, IPPROTO_IP, IP_DROP_MEMBERSHIP,
794 (char *)&g_multicastMemberReq,
795 sizeof(struct ip_mreq)))
797 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to leave multicast group, Error code: %s\n",
801 CAResult_t ret = CACloseSocket(&g_multicastServerSocketFD);
802 u_mutex_unlock(g_mutexMulticastServer);
804 OIC_LOG_V(INFO, ETHERNET_SERVER_TAG, "Multicast server stopped [%d]", ret);
808 CAResult_t CAEthernetGetUnicastServerInfo(bool isSecured,
809 char **ipAddress, uint16_t *port, int32_t *serverFD)
811 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
814 VERIFY_NON_NULL(ipAddress, ETHERNET_SERVER_TAG, "IP address");
815 VERIFY_NON_NULL(port, ETHERNET_SERVER_TAG, "Port");
816 VERIFY_NON_NULL(serverFD, ETHERNET_SERVER_TAG, "Server ID");
818 struct sockaddr_in sockAddr;
819 socklen_t len = sizeof(struct sockaddr_in);
820 if (-1 == getsockname(g_unicastServerSocketFD, (struct sockaddr *)&sockAddr, &len))
822 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed in getsockname [%s]!", strerror(errno));
823 return CA_STATUS_FAILED;
827 const char *serverAddress = inet_ntoa(sockAddr.sin_addr);
828 *ipAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) : NULL;
829 *port = ntohs(sockAddr.sin_port);
831 *serverFD = (true == isSecured) ? g_secureUnicastServerSocketFD : g_unicastServerSocketFD;
833 *serverFD = g_unicastServerSocketFD;
836 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
840 void CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCallback callback)
842 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
843 g_packetReceivedCallback = callback;
844 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
847 void CAEthernetSetExceptionCallback(CAEthernetExceptionCallback callback)
849 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
850 g_exceptionCallback = callback;
851 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");