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 ******************************************************************/
20 #include "caethernetinterface.h"
22 #include <sys/types.h>
23 #include <sys/socket.h>
26 #include <sys/select.h>
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
32 #include "caadapterutils.h"
36 * @def ETHERNET_SERVER_TAG
37 * @brief Logging tag for module name
39 #define ETHERNET_SERVER_TAG "ETHERNET_SERVER"
42 * @def CA_UDP_BIND_RETRY_COUNT
43 * @brief Retry count in case of socket bind failure.
45 #define CA_UDP_BIND_RETRY_COUNT 10
48 * @var gUnicastServerSocketDescriptor
49 * @brief socket descriptor for unicast server
51 static int32_t gUnicastServerSocketDescriptor = -1;
54 * @var gUnicastServerSocketDescriptor
55 * @brief socket descriptor for unicast server
57 static char *gUnicastServerAddress = NULL;
60 * @var gUnicastServerSocketDescriptor
61 * @brief socket descriptor for unicast server
63 static int16_t gUnicastServerPort = -1;
66 * @var gMutexUnicastServerSocketDescriptor
67 * @brief Mutex for socket descriptor for unicast server
69 static u_mutex gMutexUnicastServerSocketDescriptor = NULL;
71 * @var gMulticastServerSocketDescriptor
72 * @brief socket descriptor for multicast server
74 static int32_t gMulticastServerSocketDescriptor = -1;
77 * @var gMutexMulticastServerSocketDescriptor
78 * @brief Mutex for socket descriptor for Multicast server
80 static u_mutex gMutexMulticastServerSocketDescriptor = NULL;
84 * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
86 static u_thread_pool_t gThreadPool = NULL;
90 * @brief ip_mreq structure passed to join a multicast group
92 static struct ip_mreq gMReq;
96 * @brief Flag to control the Receive Unicast Data Thread
98 static bool gStopUnicast = false;
101 * @var gMutexStopUnicast
102 * @brief Mutex for gStopUnicast
104 static u_mutex gMutexStopUnicast = NULL;
107 * @var gStopMulticast
108 * @brief Flag to control the Receive Multicast Data Thread
110 static bool gStopMulticast = false;
113 * @var gMutexStopMulticast
114 * @brief Mutex for gStopMulticast
116 static u_mutex gMutexStopMulticast = NULL;
119 * @var gPacketReceivedCallback
120 * @brief Callback for notifying the upper layer on receival data from remote OIC device
122 static CAEthernetPacketReceivedCallback gPacketReceivedCallback = NULL;
125 * @var gExceptionCallback
126 * @brief Callback for notifying the upper layer when unicast/multicast server encounters exception
128 static CAEthernetExceptionCallback gExceptionCallback = NULL;
131 * @var gUnicastRecvBuffer
132 * @brief Character buffer used for receiving unicast data from network
134 static char gUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
137 * @var gMulticastRecvBuffer
138 * @brief Character buffer used for receiving multicast data from network
140 static char gMulticastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
143 * @fn CAEthernetServerCreateMutex
144 * @brief Creates and initializes mutex
146 static CAResult_t CAEthernetServerCreateMutex(void);
149 * @fn CAEthernetServerDestroyMutex
150 * @brief Releases all created mutex
152 static void CAEthernetServerDestroyMutex(void);
155 * @fn CAReceiveThreadForMulticast
156 * @brief Handler thread for receiving data on multicast server
158 static void *CAReceiveThreadForMulticast(void *data);
161 * @fn CAEthernetReceiveThreadForUnicast
162 * @brief Handler thread for receiving data on unicast server
164 static void *CAEthernetReceiveThreadForUnicast(void *data);
166 CAResult_t CAEthernetInitializeServer(const u_thread_pool_t threadPool)
168 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
171 VERIFY_NON_NULL(threadPool, ETHERNET_SERVER_TAG, "Thread pool handle is NULL");
174 if (CA_STATUS_OK != CAEthernetServerCreateMutex())
176 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create mutex!");
177 return CA_STATUS_FAILED;
180 gThreadPool = threadPool;
182 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
186 void CAEthernetTerminateServer(void)
188 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
193 CAEthernetServerDestroyMutex();
195 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
198 CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
199 const int16_t multicastPort, int32_t *serverFD)
201 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
203 if (gMulticastServerSocketDescriptor != -1)
205 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast Server is already running!");
206 return CA_SERVER_STARTED_ALREADY;
209 VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "Local address is NULL");
210 VERIFY_NON_NULL(multicastAddress, ETHERNET_SERVER_TAG, "Multicast address is NULL");
212 if (0 >= multicastPort)
214 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Invalid input: Multicast port is invalid!");
215 return CA_STATUS_INVALID_PARAM;
218 // Create a datagram socket on which to recv/send.
219 u_mutex_lock(gMutexStopMulticast);
220 gStopMulticast = false;
221 u_mutex_unlock(gMutexStopMulticast);
223 u_mutex_lock(gMutexMulticastServerSocketDescriptor);
225 // create a UDP socket
226 if ((gMulticastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
228 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to Create Socket, Error code: %s",
230 u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
231 return CA_SOCKET_OPERATION_FAILED;
234 // Make the socket non-blocking
235 if (-1 == fcntl(gMulticastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
237 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
239 close(gMulticastServerSocketDescriptor);
240 gMulticastServerSocketDescriptor = -1;
241 u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
242 return CA_STATUS_FAILED;
245 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket creation success");
247 int32_t setOptionOn = 1;
248 if (-1 == setsockopt(gMulticastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
249 (char *) &setOptionOn,
250 sizeof(setOptionOn)))
252 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
254 close(gMulticastServerSocketDescriptor);
255 gMulticastServerSocketDescriptor = -1;
256 u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
257 return CA_SOCKET_OPERATION_FAILED;
260 struct sockaddr_in sockAddr;
261 memset((char *) &sockAddr, 0, sizeof(sockAddr));
263 sockAddr.sin_family = AF_INET;
264 sockAddr.sin_port = htons(multicastPort);
265 sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
267 //bind socket to multicast port
268 if (-1 == bind(gMulticastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
271 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to Bind Socket! Return Code[%d]",
272 CA_SOCKET_OPERATION_FAILED);
273 close(gMulticastServerSocketDescriptor);
274 gMulticastServerSocketDescriptor = -1;
275 u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
276 return CA_SOCKET_OPERATION_FAILED;
279 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket bind success");
281 //Add membership to receiving socket (join group)
282 memset(&gMReq, 0, sizeof(struct ip_mreq));
283 gMReq.imr_interface.s_addr = htonl(INADDR_ANY);
284 inet_aton(multicastAddress, &gMReq.imr_multiaddr);
286 if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
288 sizeof(struct ip_mreq)))
290 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
292 close(gMulticastServerSocketDescriptor);
293 gMulticastServerSocketDescriptor = -1;
294 u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
295 return CA_SOCKET_OPERATION_FAILED;
299 * The task to listen to data from multicastcast socket is added to the thread pool.
300 * This is a blocking call is made where we try to receive some data.. We will keep waiting until some data is received.
301 * This task will be terminated when thread pool is freed on stopping the adapters.
303 if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAReceiveThreadForMulticast,
306 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
308 close(gMulticastServerSocketDescriptor);
309 gMulticastServerSocketDescriptor = -1;
310 u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
311 return CA_STATUS_FAILED;
314 *serverFD = gMulticastServerSocketDescriptor;
315 u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
317 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "thread_pool_add_task done");
318 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast Server Started Successfully");
320 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
325 CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
326 const bool forceStart, const bool secured, int32_t *serverFD)
328 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
330 if (gUnicastServerSocketDescriptor != -1)
332 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Unicast Server is Started Already! Return Code[%d]",
333 CA_SERVER_STARTED_ALREADY);
334 return CA_SERVER_STARTED_ALREADY;
337 VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "Invalid argument : localAddress is NULL");
338 VERIFY_NON_NULL(port, ETHERNET_SERVER_TAG, "Invalid argument : port is NULL");
342 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Invalid input: port is invalid!");
343 return CA_STATUS_INVALID_PARAM;
346 u_mutex_lock(gMutexStopUnicast);
347 gStopUnicast = false;
348 u_mutex_unlock(gMutexStopUnicast);
350 u_mutex_lock(gMutexUnicastServerSocketDescriptor);
351 // Create a UDP socket
352 if ((gUnicastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
354 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to Create Socket, Error code: %s",
356 u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
357 return CA_SOCKET_OPERATION_FAILED;
360 // Make the socket non-blocking
361 if (-1 == fcntl(gUnicastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
363 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
365 close(gUnicastServerSocketDescriptor);
366 gUnicastServerSocketDescriptor = -1;
367 u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
368 return CA_STATUS_FAILED;
371 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket creation success");
373 if (true == forceStart)
375 int32_t setOptionOn = 1;
376 if (-1 == setsockopt(gUnicastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
377 (char *) &setOptionOn,
378 sizeof(setOptionOn)))
380 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
382 close(gUnicastServerSocketDescriptor);
383 gUnicastServerSocketDescriptor = -1;
384 u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
385 return CA_SOCKET_OPERATION_FAILED;
389 struct sockaddr_in sockAddr;
390 bool isBound = false;
391 int16_t serverPort = *port;
393 memset((char *) &sockAddr, 0, sizeof(sockAddr));
394 sockAddr.sin_family = AF_INET;
395 sockAddr.sin_port = htons(serverPort);
396 sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
398 //Trying for bind in a loop
400 for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
402 if (-1 == bind(gUnicastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
405 if (false == forceStart)
407 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind socket[%s]. Trying again... ",
410 //Set the port to next one
412 sockAddr.sin_port = htons(serverPort);
417 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind socket[%s]!",
427 if (false == isBound)
429 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind Socket! Return code[%d]",
430 CA_SOCKET_OPERATION_FAILED);
431 close(gUnicastServerSocketDescriptor);
432 gUnicastServerSocketDescriptor = -1;
433 u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
434 return CA_SOCKET_OPERATION_FAILED;
437 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket bind success");
440 char *serverAddress = NULL;
441 if (-1 != getsockname(gUnicastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len))
443 serverPort = ntohs(sockAddr.sin_port);
444 serverAddress = inet_ntoa(sockAddr.sin_addr);
448 * The task to listen for data from unicast socket is added to the thread pool.
449 * This is a blocking call is made where we try to receive some data..
450 * We will keep waiting until some data is received.
451 * This task will be terminated when thread pool is freed on stopping the adapters.
453 if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAEthernetReceiveThreadForUnicast,
456 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
458 close(gUnicastServerSocketDescriptor);
459 gUnicastServerSocketDescriptor = -1;
460 u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
461 return CA_STATUS_FAILED;
464 //Free the server address previously stored
465 OICFree(gUnicastServerAddress);
466 gUnicastServerAddress = NULL;
467 gUnicastServerPort = serverPort;
468 gUnicastServerAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) :
471 *serverFD = gUnicastServerSocketDescriptor;
472 u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
474 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Unicast Server Started Successfully");
478 CAResult_t CAEthernetStopMulticastServer(void)
480 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
482 u_mutex_lock(gMutexMulticastServerSocketDescriptor);
484 if (gMulticastServerSocketDescriptor == -1)
486 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast Server is not yet Started");
487 u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
488 return CA_SERVER_NOT_STARTED;
491 u_mutex_lock(gMutexStopMulticast);
492 gStopMulticast = true;
494 // leave the group after you are done
495 if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
497 sizeof(struct ip_mreq)))
499 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "cannot leave multicast group, Error code: %s\n",
504 if (-1 == close(gMulticastServerSocketDescriptor))
506 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast Server socket close failed, Error code: %s\n",
508 u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
509 u_mutex_unlock(gMutexStopMulticast);
510 return CA_SOCKET_OPERATION_FAILED;
513 u_mutex_unlock(gMutexStopMulticast);
515 gMulticastServerSocketDescriptor = -1;
516 u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
518 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast Server Stopped Successfully");
520 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
525 CAResult_t CAEthernetStopUnicastServer()
527 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
528 u_mutex_lock(gMutexUnicastServerSocketDescriptor);
530 if (gUnicastServerSocketDescriptor == -1)
532 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Unicast Server is not yet Started");
533 u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
534 return CA_SERVER_NOT_STARTED;
536 u_mutex_lock(gMutexStopUnicast);
540 if (-1 == close(gUnicastServerSocketDescriptor))
542 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Unicast Server socket close failed, Error code: %s\n",
544 u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
545 u_mutex_unlock(gMutexStopUnicast);
546 return CA_SOCKET_OPERATION_FAILED;
549 u_mutex_unlock(gMutexStopUnicast);
550 gUnicastServerSocketDescriptor = -1;
552 u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
554 OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Unicast Server Stopped Successfully");
558 CAResult_t CAEthernetGetUnicastServerInfo(const bool secure, char **ipAddress, int16_t *port,
561 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
564 VERIFY_NON_NULL(ipAddress, ETHERNET_SERVER_TAG, "ipAddress holder is NULL");
565 VERIFY_NON_NULL(port, ETHERNET_SERVER_TAG, "port holder is NULL");
566 VERIFY_NON_NULL(serverFD, ETHERNET_SERVER_TAG, "serverID holder is NULL");
568 *ipAddress = gUnicastServerAddress;
569 *port = gUnicastServerPort;
570 *serverFD = gUnicastServerSocketDescriptor;
572 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
576 void CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCallback callback)
578 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
580 gPacketReceivedCallback = callback;
583 void CAEthernetSetExceptionCallback(CAEthernetExceptionCallback callback)
585 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
587 gExceptionCallback = callback;
590 CAResult_t CAEthernetServerCreateMutex(void)
592 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
594 gMutexUnicastServerSocketDescriptor = u_mutex_new();
595 if (!gMutexUnicastServerSocketDescriptor)
597 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
598 return CA_STATUS_FAILED;
601 gMutexMulticastServerSocketDescriptor = u_mutex_new();
602 if (!gMutexMulticastServerSocketDescriptor)
604 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
606 CAEthernetServerDestroyMutex();
607 return CA_STATUS_FAILED;
610 gMutexStopUnicast = u_mutex_new();
611 if (!gMutexStopUnicast)
613 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
615 CAEthernetServerDestroyMutex();
616 return CA_STATUS_FAILED;
619 gMutexStopMulticast = u_mutex_new();
620 if (!gMutexStopMulticast)
622 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
624 CAEthernetServerDestroyMutex();
625 return CA_STATUS_FAILED;
628 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
632 void CAEthernetServerDestroyMutex(void)
634 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
636 if (gMutexUnicastServerSocketDescriptor)
638 u_mutex_free(gMutexUnicastServerSocketDescriptor);
639 gMutexUnicastServerSocketDescriptor = NULL;
642 if (gMutexMulticastServerSocketDescriptor)
644 u_mutex_free(gMutexMulticastServerSocketDescriptor);
645 gMutexMulticastServerSocketDescriptor = NULL;
648 if (gMutexStopUnicast)
650 u_mutex_free(gMutexStopUnicast);
651 gMutexStopUnicast = NULL;
654 if (gMutexStopMulticast)
656 u_mutex_free(gMutexStopMulticast);
657 gMutexStopMulticast = NULL;
660 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
663 void *CAEthernetReceiveThreadForUnicast(void *data)
665 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
668 struct timeval timeout;
670 //keep listening for data
671 while (!gStopUnicast)
673 //OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "Waiting for data..");
679 FD_SET(gUnicastServerSocketDescriptor, &reads);
681 int32_t ret = select(gUnicastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
684 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "Stop Unicast is called");
689 OIC_LOG_V(FATAL, ETHERNET_SERVER_TAG, "select returned error %s", strerror(errno));
692 if (!FD_ISSET(gUnicastServerSocketDescriptor, &reads))
694 //OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "No data to read");
698 memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
700 //Read data from socket
701 struct sockaddr_in srcSockAddress;
703 socklen_t srcAddressLen = sizeof(srcSockAddress);
704 if (-1 == (recvLen = recvfrom(gUnicastServerSocketDescriptor, gUnicastRecvBuffer,
705 COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
708 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "%s", strerror(errno));
711 else if (0 == recvLen)
713 OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Unicast server socket is shutdown !");
715 //Notify upper layer this exception
716 if (gExceptionCallback)
718 gExceptionCallback(CA_UNICAST_SERVER);
723 const char *srcIPAddress = NULL;
724 int32_t srcPort = -1;
726 srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
727 srcPort = ntohs(srcSockAddress.sin_port);
729 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Received packet from %s:%d\n",
730 srcIPAddress, srcPort);
731 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
732 gUnicastRecvBuffer, recvLen);
734 //Notify data to upper layer
735 if (gPacketReceivedCallback)
737 gPacketReceivedCallback(srcIPAddress, srcPort, gUnicastRecvBuffer, recvLen);
741 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
745 void *CAReceiveThreadForMulticast(void *data)
747 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
750 struct timeval timeout;
752 //keep listening for data
753 while (!gStopMulticast)
759 FD_SET(gMulticastServerSocketDescriptor, &reads);
761 int32_t ret = select(gMulticastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
764 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "Stop Multicast is called");
769 OIC_LOG_V(FATAL, ETHERNET_SERVER_TAG, "select returned error %s", strerror(errno));
772 if (!FD_ISSET(gMulticastServerSocketDescriptor, &reads))
777 memset(gMulticastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
779 //Read data from socket
780 struct sockaddr_in srcSockAddress;
782 socklen_t srcAddressLen = sizeof(srcSockAddress);
783 if (-1 == (recvLen = recvfrom(gMulticastServerSocketDescriptor, gMulticastRecvBuffer,
784 COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
787 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "%s", strerror(errno));
790 else if (0 == recvLen)
792 OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast socket is shutdown, returning from \
795 //Notify upper layer this exception
796 if (gExceptionCallback)
798 gExceptionCallback(CA_MULTICAST_SERVER);
803 const char *srcIPAddress = NULL;
804 int32_t srcPort = -1;
806 srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
807 srcPort = ntohs(srcSockAddress.sin_port);
809 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Received packet from %s:%d\n",
810 srcIPAddress, srcPort);
811 OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
812 gMulticastRecvBuffer, recvLen);
815 //Notify data to upper layer
816 if (gPacketReceivedCallback)
818 gPacketReceivedCallback(srcIPAddress, srcPort, gMulticastRecvBuffer, recvLen);
822 OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");