#ifdef __TIZENRT__
#include <tinyara/config.h>
#include <uio.h>
+#include <poll.h>
#endif
#include "iotivity_config.h"
#include <sys/types.h>
#include <fcntl.h>
#if !defined(_WIN32)
-#include <sys/select.h>
+#include <sys/poll.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
static void CAFindReadyMessage();
#if !defined(WSA_WAIT_EVENT_0)
-static void CASelectReturned(fd_set *readFds, int ret);
+static void CAPollReturned(struct pollfd *readFds, int ret);
#else
static void CAEventReturned(CASocketFd_t socket);
#endif
caglobals.ip.TYPE.fd = OC_INVALID_SOCKET; \
}
-#define SET(TYPE, FDS) \
- if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET) \
- { \
- FD_SET(caglobals.ip.TYPE.fd, FDS); \
- }
-
-#define ISSET(TYPE, FDS, FLAGS) \
- if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET && FD_ISSET(caglobals.ip.TYPE.fd, FDS)) \
- { \
- fd = caglobals.ip.TYPE.fd; \
- flags = FLAGS; \
- }
-
+#define SET(TYPE, FDS, COUNT) \
+ FDS[COUNT].fd = caglobals.ip.TYPE.fd; \
+ FDS[COUNT].events = POLLIN;
+
+#define MAX_UDP_SOCK_COUNT 8
+
+static const CASocketFd_t *sockFdPtr[MAX_UDP_SOCK_COUNT] = {
+ &caglobals.ip.u6.fd,
+ &caglobals.ip.u6s.fd,
+ &caglobals.ip.u4.fd,
+ &caglobals.ip.u4s.fd,
+ &caglobals.ip.m6.fd,
+ &caglobals.ip.m6s.fd,
+ &caglobals.ip.m4.fd,
+ &caglobals.ip.m4s.fd
+ };
+
+static const CATransportFlags_t inputflags[MAX_UDP_SOCK_COUNT] = {
+ CA_IPV6,
+ CA_IPV6 | CA_SECURE,
+ CA_IPV4,
+ CA_IPV4 | CA_SECURE,
+ CA_MULTICAST | CA_IPV6,
+ CA_MULTICAST | CA_IPV6 | CA_SECURE,
+ CA_MULTICAST | CA_IPV4,
+ CA_MULTICAST | CA_IPV4 | CA_SECURE
+ };
static void CAFindReadyMessage()
{
- fd_set readFds;
- struct timeval timeout;
-
- timeout.tv_sec = caglobals.ip.selectTimeout;
- timeout.tv_usec = 0;
- struct timeval *tv = caglobals.ip.selectTimeout == -1 ? NULL : &timeout;
-
- FD_ZERO(&readFds);
- SET(u6, &readFds)
- SET(u6s, &readFds)
- SET(u4, &readFds)
- SET(u4s, &readFds)
- SET(m6, &readFds)
- SET(m6s, &readFds)
- SET(m4, &readFds)
- SET(m4s, &readFds)
+ struct pollfd readFds[MAX_UDP_SOCK_COUNT + 2]; // 8 UDP sockets, 1 netlink and 1 read pipe socket fd
+ int timeout = (caglobals.ip.selectTimeout * 1000);
+ int counter = 0;
+
+ SET(u6, readFds, counter);
+ counter++;
+ SET(u6s, readFds, counter);
+ counter++;
+ SET(u4, readFds, counter);
+ counter++;
+ SET(u4s, readFds, counter);
+ counter++;
+ SET(m6, readFds, counter);
+ counter++;
+ SET(m6s, readFds, counter);
+ counter++;
+ SET(m4, readFds, counter);
+ counter++;
+ SET(m4s, readFds, counter);
+ counter++;
+
#ifndef __TIZENRT__
- if (caglobals.ip.shutdownFds[0] != -1)
- {
- FD_SET(caglobals.ip.shutdownFds[0], &readFds);
- }
-#endif
- if (caglobals.ip.netlinkFd != OC_INVALID_SOCKET)
- {
- FD_SET(caglobals.ip.netlinkFd, &readFds);
- }
+ readFds[counter].fd = caglobals.ip.shutdownFds[0];
+ readFds[counter].events = POLLIN;
+ counter++;
- int ret = select(caglobals.ip.maxfd + 1, &readFds, NULL, NULL, tv);
+ readFds[counter].fd = caglobals.ip.netlinkFd;
+ readFds[counter].events = POLLIN;
+ counter++;
+#endif
+ int ret = poll(readFds, counter, timeout);
if (caglobals.ip.terminate)
{
OIC_LOG_V(INFO, TAG, "Packet receiver Stop request received.");
u_arraylist_destroy(iflist);
}
#endif
- if (0 < ret)
+ if (ret > 0)
{
- CASelectReturned(&readFds, ret);
+ CAPollReturned(readFds, ret);
}
- else if (0 > ret)
+ else if (ret < 0)
{
- OIC_LOG_V(FATAL, TAG, "select error %s", CAIPS_GET_ERROR);
+ OIC_LOG_V(FATAL, TAG, "poll error %s", CAIPS_GET_ERROR);
}
}
-static void CASelectReturned(fd_set *readFds, int ret)
+static void CAPollReturned(struct pollfd *readFds, int ret)
{
(void)ret;
- CASocketFd_t fd = OC_INVALID_SOCKET;
- CATransportFlags_t flags = CA_DEFAULT_FLAGS;
- while (!caglobals.ip.terminate)
+ int counter = 0;
+
+ for (int i = 0; i < MAX_UDP_SOCK_COUNT && !caglobals.ip.terminate; i++)
{
- ISSET(u6, readFds, CA_IPV6)
- else ISSET(u6s, readFds, CA_IPV6 | CA_SECURE)
- else ISSET(u4, readFds, CA_IPV4)
- else ISSET(u4s, readFds, CA_IPV4 | CA_SECURE)
- else ISSET(m6, readFds, CA_MULTICAST | CA_IPV6)
- else ISSET(m6s, readFds, CA_MULTICAST | CA_IPV6 | CA_SECURE)
- else ISSET(m4, readFds, CA_MULTICAST | CA_IPV4)
- else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE)
- else if ((caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && FD_ISSET(caglobals.ip.netlinkFd, readFds))
+ if (*sockFdPtr[i] != OC_INVALID_SOCKET && readFds[i].revents == POLLIN)
{
-#ifndef __TIZENRT__
- u_arraylist_t *iflist = CAFindInterfaceChange();
- if (iflist)
- {
- uint32_t listLength = u_arraylist_length(iflist);
- for (uint32_t i = 0; i < listLength; i++)
- {
- CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
- if (ifitem)
- {
- CAProcessNewInterface(ifitem);
- }
- }
- u_arraylist_destroy(iflist);
- }
- break;
-#endif
+ (void)CAReceiveMessage(readFds[i].fd, inputflags[i]);
}
+ counter++;
+ }
+
#ifndef __TIZENRT__
- else if (FD_ISSET(caglobals.ip.shutdownFds[0], readFds))
+ if (caglobals.ip.terminate)
+ {
+ return;
+ }
+
+ if (caglobals.ip.shutdownFds[0] != -1 && readFds[counter].revents != 0)
+ {
+ char buf[10] = {0};
+ ssize_t len = read(caglobals.ip.shutdownFds[0], buf, sizeof (buf));
+ if (-1 != len)
{
- char buf[10] = {0};
- ssize_t len = read(caglobals.ip.shutdownFds[0], buf, sizeof (buf));
- if (-1 == len)
- {
- continue;
- }
- break;
+ // Write end of the pipe is closed. Indicates the termination of UDP server.
+ return;
}
-#endif
- else
+
+ counter++;
+ }
+
+ if (!caglobals.ip.terminate &&
+ (caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && readFds[counter].revents != 0)
+ {
+ u_arraylist_t *iflist = CAFindInterfaceChange();
+ if (iflist)
{
- break;
+ uint32_t listLength = u_arraylist_length(iflist);
+ for (uint32_t i = 0; i < listLength; i++)
+ {
+ CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+ if (ifitem)
+ {
+ CAProcessNewInterface(ifitem);
+ }
+ }
+ u_arraylist_destroy(iflist);
}
- (void)CAReceiveMessage(fd, flags);
- FD_CLR(fd, readFds);
}
+#endif
}
#else // if defined(WSA_WAIT_EVENT_0)
OIC_LOG_V(ERROR, TAG, "Recvfrom failed %s", strerror(errno));
return CA_STATUS_FAILED;
}
- OIC_LOG_V(DEBUG, TAG, "recvd %u bytes from recvmsg", recvLen);
+ OIC_LOG_V(DEBUG, TAG, "recvd %zd bytes from recvmsg", recvLen);
if (flags & CA_MULTICAST)
{
return fd;
}
-#define CHECKFD(FD) \
- if (FD > caglobals.ip.maxfd) \
- caglobals.ip.maxfd = FD;
#define NEWSOCKET(FAMILY, NAME, MULTICAST) \
if (caglobals.ip.NAME.fd == OC_INVALID_SOCKET) \
{ \
caglobals.ip.NAME.port = 0; \
caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \
} \
- CHECKFD(caglobals.ip.NAME.fd) \
} \
void CreateMulticastSocket()
close(caglobals.ip.netlinkFd);
caglobals.ip.netlinkFd = OC_INVALID_SOCKET;
}
- else
- {
- CHECKFD(caglobals.ip.netlinkFd);
- }
}
#elif defined (__TIZENRT__) // pkmsgq
struct mq_attr lq_attr;
#elif defined(HAVE_PIPE2)
#ifndef __TIZENRT__
ret = pipe2(caglobals.ip.shutdownFds, O_CLOEXEC);
- CHECKFD(caglobals.ip.shutdownFds[0]);
- CHECKFD(caglobals.ip.shutdownFds[1]);
#endif
#else
#ifndef __TIZENRT__
caglobals.ip.shutdownFds[1] = -1;
}
}
- CHECKFD(caglobals.ip.shutdownFds[0]);
- CHECKFD(caglobals.ip.shutdownFds[1]);
#endif
#endif
if (-1 == ret)