22#ifdef HAVE_SYS_SELECT_H
23# include <sys/select.h>
25#ifdef HAVE_SYS_SOCKET_H
26# include <sys/socket.h>
27# define OPTVAL_T(t) (t)
28# define OPTVAL_GT(t) (t)
30#ifdef HAVE_SYS_IOCTL_H
33#ifdef HAVE_NETINET_IN_H
34# include <netinet/in.h>
38# define OPTVAL_T(t) (const char*)(t)
39# define OPTVAL_GT(t) (char*)(t)
41# define CMSG_DATA WSA_CMSG_DATA
49#ifdef COAP_EPOLL_SUPPORT
51#include <sys/timerfd.h>
57#if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION) && !(WITH_LWIP)
59#if defined(IP_PKTINFO)
60# define GEN_IP_PKTINFO IP_PKTINFO
61#elif defined(IP_RECVDSTADDR)
62# define GEN_IP_PKTINFO IP_RECVDSTADDR
64# error "Need IP_PKTINFO or IP_RECVDSTADDR to request ancillary data from OS."
68#ifdef IPV6_RECVPKTINFO
69# define GEN_IPV6_PKTINFO IPV6_RECVPKTINFO
70#elif defined(IPV6_PKTINFO)
71# define GEN_IPV6_PKTINFO IPV6_PKTINFO
73# error "Need IPV6_PKTINFO or IPV6_RECVPKTINFO to request ancillary data from OS."
77#if COAP_SERVER_SUPPORT
89#if !defined(WITH_CONTIKI) && !defined(WITH_LWIP)
101 struct timeval timeout = {0, 0};
107 sock->
fd = socket(listen_addr->
addr.
sa.sa_family, SOCK_DGRAM, 0);
122 if (setsockopt(sock->
fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on),
sizeof(on)) ==
COAP_SOCKET_ERROR)
123 coap_log_warn(
"coap_socket_bind_udp: setsockopt SO_REUSEADDR: %s\n",
126 switch (listen_addr->
addr.
sa.sa_family) {
129 if (setsockopt(sock->
fd, IPPROTO_IP, GEN_IP_PKTINFO, OPTVAL_T(&on),
131 coap_log_alert(
"coap_socket_bind_udp: setsockopt IP_PKTINFO: %s\n",
138 if (setsockopt(sock->
fd, IPPROTO_IPV6, IPV6_V6ONLY, OPTVAL_T(&off),
140 coap_log_alert(
"coap_socket_bind_udp: setsockopt IPV6_V6ONLY: %s\n",
142#if !defined(ESPIDF_VERSION)
143 if (setsockopt(sock->
fd, IPPROTO_IPV6, GEN_IPV6_PKTINFO, OPTVAL_T(&on),
145 coap_log_alert(
"coap_socket_bind_udp: setsockopt IPV6_PKTINFO: %s\n",
149 setsockopt(sock->
fd, IPPROTO_IP, GEN_IP_PKTINFO, OPTVAL_T(&on),
sizeof(on));
153#if COAP_AF_UNIX_SUPPORT
162 if (setsockopt(sock->
fd, SOL_SOCKET, SO_RCVTIMEO, OPTVAL_T(&timeout),
164 coap_log_alert(
"coap_socket_bind_udp: setsockopt SO_RCVTIMEO: %s\n",
168 if (bind(sock->
fd, &listen_addr->
addr.
sa,
170 listen_addr->
addr.
sa.sa_family == AF_INET ?
171 (socklen_t)
sizeof(
struct sockaddr_in) :
179 bound_addr->
size = (socklen_t)
sizeof(*bound_addr);
180 if (getsockname(sock->
fd, &bound_addr->
addr.
sa, &bound_addr->
size) < 0) {
185#if defined(RIOT_VERSION) && defined(COAP_SERVER_SUPPORT)
187 bound_addr->
addr.
sa.sa_family == AF_INET6) {
188 bound_addr->
addr.
sin6.sin6_scope_id =
189 listen_addr->
addr.
sin6.sin6_scope_id;
190 bound_addr->
addr.
sin6.sin6_flowinfo = 0;
201#if COAP_CLIENT_SUPPORT
215 struct timeval timeout = {0, 0};
221#if !defined(RIOT_VERSION)
227 sock->
fd = socket(connect_addr.
addr.
sa.sa_family, SOCK_DGRAM, 0);
242 coap_log_warn(
"coap_socket_connect_udp: ioctl FIONBIO: %s\n",
247 switch (connect_addr.
addr.
sa.sa_family) {
250 if (connect_addr.
addr.
sin.sin_port == 0)
251 connect_addr.
addr.
sin.sin_port = htons(default_port);
256 if (connect_addr.
addr.
sin6.sin6_port == 0)
257 connect_addr.
addr.
sin6.sin6_port = htons(default_port);
260 if (setsockopt(sock->
fd, IPPROTO_IPV6, IPV6_V6ONLY, OPTVAL_T(&off),
262 coap_log_warn(
"coap_socket_connect_udp: setsockopt IPV6_V6ONLY: %s\n",
267#if COAP_AF_UNIX_SUPPORT
272 coap_log_alert(
"coap_socket_connect_udp: unsupported sa_family %d\n",
273 connect_addr.
addr.
sa.sa_family);
277 if (local_if && local_if->
addr.
sa.sa_family) {
278 if (local_if->
addr.
sa.sa_family != connect_addr.
addr.
sa.sa_family) {
279 coap_log_warn(
"coap_socket_connect_udp: local address family != "
280 "remote address family\n");
284 if (setsockopt(sock->
fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on),
sizeof(on)) ==
COAP_SOCKET_ERROR)
285 coap_log_warn(
"coap_socket_connect_udp: setsockopt SO_REUSEADDR: %s\n",
288 if (bind(sock->
fd, &local_if->
addr.
sa,
290 local_if->
addr.
sa.sa_family == AF_INET ?
291 (socklen_t)
sizeof(
struct sockaddr_in) :
298#if COAP_AF_UNIX_SUPPORT
299 }
else if (connect_addr.
addr.
sa.sa_family == AF_UNIX) {
301 coap_log_warn(
"coap_socket_connect_udp: local address required\n");
307#if !defined(RIOT_VERSION)
309 if (!(local_if && local_if->
addr.
sa.sa_family)) {
314 bind_addr.
addr.
sa.sa_family = connect_addr.
addr.
sa.sa_family;
315 if (bind(sock->
fd, &bind_addr.
addr.
sa,
317 bind_addr.
addr.
sa.sa_family == AF_INET ?
318 (socklen_t)
sizeof(
struct sockaddr_in) :
327 coap_log_warn(
"coap_socket_connect_udp: getsockname for multicast socket: %s\n",
334 setsockopt(sock->
fd, SOL_SOCKET, SO_BROADCAST, OPTVAL_T(&on),
336 coap_log_warn(
"coap_socket_connect_udp: setsockopt SO_BROADCAST: %s\n",
341 if (!(local_if && local_if->
addr.
sa.sa_family)) {
346 bind_addr.
addr.
sa.sa_family = connect_addr.
addr.
sa.sa_family;
348 if (bind_addr.
addr.
sa.sa_family == AF_INET6)
351 if (bind(sock->
fd, &bind_addr.
addr.
sa,
352 bind_addr.
addr.
sa.sa_family == AF_INET ?
353 (socklen_t)
sizeof(
struct sockaddr_in) :
360 if (setsockopt(sock->
fd, SOL_SOCKET, SO_RCVTIMEO, OPTVAL_T(&timeout),
362 coap_log_alert(
"coap_socket_bind_udp: setsockopt SO_RCVTIMEO: %s\n",
367#if COAP_AF_UNIX_SUPPORT
368 if (connect_addr.
addr.
sa.sa_family == AF_UNIX) {
402#ifdef COAP_EPOLL_SUPPORT
403#if COAP_SERVER_SUPPORT
409 if (context != NULL) {
411 struct epoll_event event;
414 ret = epoll_ctl(context->epfd, EPOLL_CTL_DEL, sock->
fd, &event);
415 if (ret == -1 && errno != ENOENT) {
421#if COAP_SERVER_SUPPORT
422#if COAP_AF_UNIX_SUPPORT
431#if COAP_CLIENT_SUPPORT
432#if COAP_AF_UNIX_SUPPORT
448#ifdef COAP_EPOLL_SUPPORT
454 struct epoll_event event;
457#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_ERR
464#if COAP_SERVER_SUPPORT
474 memset(&event, 0,
sizeof(event));
475 event.events = events;
476 event.data.ptr = sock;
478 ret = epoll_ctl(context->epfd, EPOLL_CTL_ADD, sock->
fd, &event);
491 struct epoll_event event;
494#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_ERR
501#if COAP_SERVER_SUPPORT
510 event.events = events;
511 event.data.ptr = sock;
513 ret = epoll_ctl(context->epfd, EPOLL_CTL_MOD, sock->
fd, &event);
515#if (COAP_MAX_LOGGING_LEVEL < COAP_LOG_ERR)
526 if (context->eptimerfd != -1) {
530 if (context->next_timeout == 0 || context->next_timeout > now + delay) {
531 struct itimerspec new_value;
534 context->next_timeout = now + delay;
535 memset(&new_value, 0,
sizeof(new_value));
537 new_value.it_value.tv_nsec = 1;
543 ret = timerfd_settime(context->eptimerfd, 0, &new_value, NULL);
546 "coap_resource_notify_observers",
549#ifdef COAP_DEBUG_WAKEUP_TIMES
552 new_value.it_value.tv_sec, new_value.it_value.tv_nsec);
563coap_win_error_to_errno(
void) {
564 int w_error = WSAGetLastError();
566 case WSA_NOT_ENOUGH_MEMORY:
569 case WSA_INVALID_PARAMETER:
602 case WSAECONNABORTED:
603 errno = ECONNABORTED;
614 case WSAECONNREFUSED:
615 errno = ECONNREFUSED;
618 coap_log_err(
"WSAGetLastError: %d mapping to errno failed - please fix\n",
638 r = send(sock->
fd, (
const char *)data, (
int)data_len, 0);
641#define MSG_NOSIGNAL 0
647 coap_win_error_to_errno();
650#
if EAGAIN != EWOULDBLOCK
651 errno == EWOULDBLOCK ||
655#ifdef COAP_EPOLL_SUPPORT
664 if (errno == EPIPE || errno == ECONNRESET) {
673 if (r < (ssize_t)data_len) {
675#ifdef COAP_EPOLL_SUPPORT
696 r = recv(sock->
fd, (
char *)data, (
int)data_len, 0);
698 r = recv(sock->
fd, data, data_len, 0);
702 sock->
flags &= ~COAP_SOCKET_CAN_READ;
706 sock->
flags &= ~COAP_SOCKET_CAN_READ;
708 coap_win_error_to_errno();
711#
if EAGAIN != EWOULDBLOCK
712 errno == EWOULDBLOCK ||
717 if (errno != ECONNRESET) {
723 if (r < (ssize_t)data_len)
724 sock->
flags &= ~COAP_SOCKET_CAN_READ;
730#if !defined(WITH_LWIP)
731#if (!defined(WITH_CONTIKI)) != ( defined(HAVE_NETINET_IN_H) || defined(HAVE_WS2TCPIP_H) )
735#if !defined(__MINGW32__)
750#if !defined(WITH_CONTIKI) && !defined(SOL_IP)
752#define SOL_IP IPPROTO_IP
755#define COAP_SOL_IP IPPROTO_IP
757#define COAP_SOL_IP SOL_IP
762#if !defined(__MINGW32__)
763static __declspec(thread) LPFN_WSARECVMSG lpWSARecvMsg = NULL;
766#define msghdr _WSAMSG
768#define msg_namelen namelen
769#define msg_iov lpBuffers
770#define msg_iovlen dwBufferCount
771#define msg_control Control.buf
772#define msg_controllen Control.len
776#define iov_len_t u_long
778#define CMSG_DATA WSA_CMSG_DATA
779#define ipi_spec_dst ipi_addr
780#if !defined(__MINGW32__)
781#pragma warning( disable : 4116 )
784#define iov_len_t size_t
787#if defined(_CYGWIN_ENV)
788#define ipi_spec_dst ipi_addr
791#if !defined(RIOT_VERSION) && !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
799 const uint8_t *data,
size_t datalen) {
800 ssize_t bytes_written = 0;
803 bytes_written = (ssize_t)datalen;
806 bytes_written = send(sock->
fd, (
const char *)data, (
int)datalen, 0);
808 bytes_written = send(sock->
fd, data, datalen, 0);
811#if defined(_WIN32) && !defined(__MINGW32__)
812 DWORD dwNumberOfBytesSent = 0;
815#ifdef HAVE_STRUCT_CMSGHDR
824 memcpy(&iov[0].iov_base, &data,
sizeof(iov[0].iov_base));
827 memset(buf, 0,
sizeof(buf));
829 memset(&mhdr, 0,
sizeof(
struct msghdr));
830 memcpy(&mhdr.msg_name, &addr,
sizeof(mhdr.msg_name));
832 (socklen_t)
sizeof(
struct sockaddr_in) :
843 struct cmsghdr *cmsg;
847#if defined(IP_PKTINFO)
849 mhdr.msg_control = buf;
850 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
852 cmsg = CMSG_FIRSTHDR(&mhdr);
854 cmsg->cmsg_type = IP_PKTINFO;
855 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
857 pktinfo = (
struct in_pktinfo *)CMSG_DATA(cmsg);
863#elif defined(IP_SENDSRCADDR)
864 mhdr.msg_control = buf;
865 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_addr));
867 cmsg = CMSG_FIRSTHDR(&mhdr);
868 cmsg->cmsg_level = IPPROTO_IP;
869 cmsg->cmsg_type = IP_SENDSRCADDR;
870 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_addr));
872 memcpy(CMSG_DATA(cmsg),
874 sizeof(
struct in_addr));
879 mhdr.msg_control = buf;
880 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in6_pktinfo));
882 cmsg = CMSG_FIRSTHDR(&mhdr);
883 cmsg->cmsg_level = IPPROTO_IPV6;
884 cmsg->cmsg_type = IPV6_PKTINFO;
885 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in6_pktinfo));
901#if defined(IP_PKTINFO)
902 struct cmsghdr *cmsg;
905 mhdr.msg_control = buf;
906 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
908 cmsg = CMSG_FIRSTHDR(&mhdr);
910 cmsg->cmsg_type = IP_PKTINFO;
911 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
913 pktinfo = (
struct in_pktinfo *)CMSG_DATA(cmsg);
919#elif defined(IP_SENDSRCADDR)
920 struct cmsghdr *cmsg;
921 mhdr.msg_control = buf;
922 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_addr));
924 cmsg = CMSG_FIRSTHDR(&mhdr);
925 cmsg->cmsg_level = IPPROTO_IP;
926 cmsg->cmsg_type = IP_SENDSRCADDR;
927 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_addr));
929 memcpy(CMSG_DATA(cmsg),
931 sizeof(
struct in_addr));
936#if COAP_AF_UNIX_SUPPORT
948#if defined(_WIN32) && !defined(__MINGW32__)
949 r = WSASendMsg(sock->
fd, &mhdr, 0 , &dwNumberOfBytesSent, NULL ,
952 bytes_written = (ssize_t)dwNumberOfBytesSent;
955 coap_win_error_to_errno();
958#ifdef HAVE_STRUCT_CMSGHDR
959 bytes_written = sendmsg(sock->
fd, &mhdr, 0);
961 bytes_written = sendto(sock->
fd, (
const void *)data, datalen, 0,
968 if (bytes_written < 0)
971 return bytes_written;
975#define SIN6(A) ((struct sockaddr_in6 *)(A))
983#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
1001 sock->
flags &= ~COAP_SOCKET_CAN_READ;
1012 coap_win_error_to_errno();
1014 if (errno == ECONNREFUSED || errno == EHOSTUNREACH || errno == ECONNRESET) {
1027 }
else if (len > 0) {
1028 packet->
length = (size_t)len;
1031#if defined(_WIN32) && !defined(__MINGW32__)
1032 DWORD dwNumberOfBytesRecvd = 0;
1035#ifdef HAVE_STRUCT_CMSGHDR
1038 struct cmsghdr *cmsg;
1040 struct iovec iov[1];
1042 iov[0].iov_base = packet->
payload;
1045 memset(&mhdr, 0,
sizeof(
struct msghdr));
1051 mhdr.msg_iovlen = 1;
1053 mhdr.msg_control = buf;
1054 mhdr.msg_controllen =
sizeof(buf);
1057 cmsg = (
struct cmsghdr *)buf;
1058 cmsg->cmsg_len = CMSG_LEN(
sizeof(buf));
1059 cmsg->cmsg_level = -1;
1060 cmsg->cmsg_type = -1;
1063 if (!lpWSARecvMsg) {
1064 GUID wsaid = WSAID_WSARECVMSG;
1065 DWORD cbBytesReturned = 0;
1066 if (WSAIoctl(sock->
fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &wsaid,
sizeof(wsaid), &lpWSARecvMsg,
1067 sizeof(lpWSARecvMsg), &cbBytesReturned, NULL, NULL) != 0) {
1072 r = lpWSARecvMsg(sock->
fd, &mhdr, &dwNumberOfBytesRecvd, NULL ,
1075 len = (ssize_t)dwNumberOfBytesRecvd;
1077 coap_win_error_to_errno();
1079 len = recvmsg(sock->
fd, &mhdr, 0);
1086#if defined(RIOT_VERSION) && defined(COAP_SERVER_SUPPORT) && COAP_IPV6_SUPPORT
1098 coap_win_error_to_errno();
1100 if (errno == ECONNREFUSED || errno == EHOSTUNREACH || errno == ECONNRESET) {
1111#ifdef HAVE_STRUCT_CMSGHDR
1115 packet->
length = (size_t)len;
1119 for (cmsg = CMSG_FIRSTHDR(&mhdr); cmsg; cmsg = CMSG_NXTHDR(&mhdr, cmsg)) {
1121#if COAP_IPV6_SUPPORT
1123 if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
1128 u.c = CMSG_DATA(cmsg);
1129 packet->
ifindex = (int)(u.p->ipi6_ifindex);
1131 &u.p->ipi6_addr,
sizeof(
struct in6_addr));
1137#if COAP_IPV4_SUPPORT
1139#if defined(IP_PKTINFO)
1140 if (cmsg->cmsg_level ==
COAP_SOL_IP && cmsg->cmsg_type == IP_PKTINFO) {
1145 u.c = CMSG_DATA(cmsg);
1146 packet->
ifindex = u.p->ipi_ifindex;
1147#if COAP_IPV6_SUPPORT
1153 &u.p->ipi_addr,
sizeof(
struct in_addr));
1158 &u.p->ipi_addr,
sizeof(
struct in_addr));
1164#if defined(IP_RECVDSTADDR)
1165 if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) {
1168 CMSG_DATA(cmsg),
sizeof(
struct in_addr));
1177 if (cmsg->cmsg_level != -1 && cmsg->cmsg_type != -1) {
1178 coap_log_debug(
"cmsg_level = %d and cmsg_type = %d not supported - fix\n",
1179 cmsg->cmsg_level, cmsg->cmsg_type);
1193 packet->
length = (size_t)len;
1200#if defined(RIOT_VERSION) && defined(COAP_SERVER_SUPPORT) && COAP_IPV6_SUPPORT
1221#ifndef COAP_EPOLL_SUPPORT
1224 coap_log_emerg(
"coap_io_prepare_epoll() requires libcoap compiled for using epoll\n");
1228 unsigned int max_sockets =
sizeof(sockets)/
sizeof(sockets[0]);
1229 unsigned int num_sockets;
1230 unsigned int timeout;
1235 ctx->next_timeout = timeout ? now + timeout : 0;
1236 if (ctx->eptimerfd != -1) {
1237 struct itimerspec new_value;
1240 memset(&new_value, 0,
sizeof(new_value));
1242 if (ctx->next_timeout != 0 && ctx->next_timeout > now) {
1243 coap_tick_t rem_timeout = ctx->next_timeout - now;
1249#ifdef COAP_DEBUG_WAKEUP_TIMES
1251 new_value.it_value.tv_sec, new_value.it_value.tv_nsec);
1254 ret = timerfd_settime(ctx->eptimerfd, 0, &new_value, NULL);
1257 "coap_io_prepare_epoll",
1272 unsigned int max_sockets,
1273 unsigned int *num_sockets,
1279#if COAP_SERVER_SUPPORT
1280 int check_dtls_timeouts = 0;
1282#if defined(COAP_EPOLL_SUPPORT) || defined(WITH_LWIP)
1289#if COAP_SERVER_SUPPORT
1293#if COAP_ASYNC_SUPPORT
1295 timeout = coap_check_async(ctx, now);
1306 if (nextpdu && (timeout == 0 ||
1314 if (tls_timeout > 0) {
1319 if (timeout == 0 || tls_timeout - now < timeout)
1320 timeout = tls_timeout - now;
1322#if COAP_SERVER_SUPPORT
1324 check_dtls_timeouts = 1;
1328#if COAP_SERVER_SUPPORT
1338#if !defined(COAP_EPOLL_SUPPORT) && !defined(WITH_LWIP)
1340 if (*num_sockets < max_sockets)
1341 sockets[(*num_sockets)++] = &ep->
sock;
1355 s_timeout = (s->
last_rx_tx + session_timeout) - now;
1356 if (timeout == 0 || s_timeout < timeout)
1357 timeout = s_timeout;
1365 while (tls_timeout > 0 && tls_timeout <= now) {
1378 if (tls_timeout > 0 && (timeout == 0 || tls_timeout - now < timeout))
1379 timeout = tls_timeout - now;
1384 if (timeout == 0 || s_timeout < timeout)
1385 timeout = s_timeout;
1391 if (timeout == 0 || s_timeout < timeout)
1392 timeout = s_timeout;
1395#if !defined(COAP_EPOLL_SUPPORT) && !defined(WITH_LWIP)
1397 if (*num_sockets < max_sockets)
1398 sockets[(*num_sockets)++] = &s->
sock;
1401#if COAP_Q_BLOCK_SUPPORT
1407 s_timeout = coap_block_check_q_block2_xmit(s, now);
1408 if (timeout == 0 || s_timeout < timeout)
1409 timeout = s_timeout;
1418#if COAP_CLIENT_SUPPORT
1435 if (timeout == 0 || s_timeout < timeout)
1436 timeout = s_timeout;
1439#if !COAP_DISABLE_TCP
1452 if (timeout == 0 || s_timeout < timeout)
1453 timeout = s_timeout;
1463 while (tls_timeout > 0 && tls_timeout <= now) {
1475 if (tls_timeout > 0 && (timeout == 0 || tls_timeout - now < timeout))
1476 timeout = tls_timeout - now;
1482 if (timeout == 0 || s_timeout < timeout)
1483 timeout = s_timeout;
1489 if (timeout == 0 || s_timeout < timeout)
1490 timeout = s_timeout;
1493#if COAP_Q_BLOCK_SUPPORT
1499 s_timeout = coap_block_check_q_block1_xmit(s, now);
1500 if (timeout == 0 || s_timeout < timeout)
1501 timeout = s_timeout;
1505#if !defined(COAP_EPOLL_SUPPORT) && !defined(WITHLWIP)
1510 if (*num_sockets < max_sockets)
1511 sockets[(*num_sockets)++] = &s->
sock;
1522#if !defined(WITH_LWIP) && !defined(CONTIKI)
1530 int enfds, fd_set *ereadfds, fd_set *ewritefds,
1531 fd_set *eexceptfds) {
1534 unsigned int timeout;
1535#ifndef COAP_EPOLL_SUPPORT
1543#ifndef COAP_EPOLL_SUPPORT
1548 if (timeout == 0 || timeout_ms < timeout)
1549 timeout = timeout_ms;
1576#if !COAP_DISABLE_TCP
1590 }
else if (timeout > 0) {
1591 tv.tv_usec = (timeout % 1000) * 1000;
1592 tv.tv_sec = (long)(timeout / 1000);
1596 timeout > 0 ? &tv : NULL);
1600 coap_win_error_to_errno();
1602 if (errno != EINTR) {
1622#if !COAP_DISABLE_TCP
1648 if (timeout == 0 || timeout_ms < timeout)
1649 timeout = timeout_ms;
1653 int etimeout = timeout;
1661 }
else if (etimeout < 0) {
1668 if (errno != EINTR) {
1669 coap_log_err(
"epoll_wait: unexpected error: %s (%d)\n",
1688#if COAP_SERVER_SUPPORT
1692#if COAP_ASYNC_SUPPORT
1695 coap_check_async(ctx, now);
1710#if COAP_SERVER_SUPPORT
1721#if COAP_SERVER_SUPPORT
1722 LL_FOREACH(context->
endpoint, ep) {
1733#if COAP_CLIENT_SUPPORT
1749 static char szError[256];
1750 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1751 NULL, (DWORD)error, MAKELANGID(LANG_NEUTRAL,
1752 SUBLANG_DEFAULT), (LPSTR)szError, (DWORD)
sizeof(szError),
1754 strcpy(szError,
"Unknown error");
1765 return strerror(error);
int coap_is_bcast(const coap_address_t *a)
Checks if given address a denotes a broadcast address.
void coap_address_init(coap_address_t *addr)
Resets the given coap_address_t object addr to its default values.
int coap_is_mcast(const coap_address_t *a)
Checks if given address a denotes a multicast address.
void coap_address_copy(coap_address_t *dst, const coap_address_t *src)
COAP_STATIC_INLINE int coap_address_isany(const coap_address_t *a)
Checks if given address object a denotes the wildcard address.
int coap_debug_send_packet(void)
Check to see whether a packet should be sent or not.
Pulls together all the internal only header files.
#define COAP_IPV4_SUPPORT
const char * coap_socket_format_errno(int error)
ssize_t coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len)
Function interface for data stream receiving off a socket.
void coap_socket_close(coap_socket_t *sock)
Function interface to close off a socket.
ssize_t coap_socket_send(coap_socket_t *sock, const coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for data transmission.
const char * coap_socket_strerror(void)
ssize_t coap_socket_recv(coap_socket_t *sock, coap_packet_t *packet)
Function interface for reading data.
void coap_packet_get_memmapped(coap_packet_t *packet, unsigned char **address, size_t *length)
Given a packet, set msg and msg_len to an address and length of the packet's data in memory.
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
Function interface for data stream sending off a socket.
int coap_socket_bind_udp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
#define COAP_MAX_EPOLL_EVENTS
#define COAP_RXBUFFER_SIZE
#define COAP_SOCKET_ERROR
@ COAP_NACK_NOT_DELIVERABLE
#define COAP_INVALID_SOCKET
#define COAP_SOCKET_MULTICAST
socket is used for multicast communication
void coap_epoll_ctl_add(coap_socket_t *sock, uint32_t events, const char *func)
Epoll specific function to add the state of events that epoll is to track for the appropriate file de...
int coap_socket_connect_udp(coap_socket_t *sock, const coap_address_t *local_if, const coap_address_t *server, int default_port, coap_address_t *local_addr, coap_address_t *remote_addr)
#define COAP_SOCKET_WANT_ACCEPT
non blocking server socket is waiting for accept
#define COAP_SOCKET_CAN_WRITE
non blocking socket can now write without blocking
void coap_update_epoll_timer(coap_context_t *context, coap_tick_t delay)
Update the epoll timer fd as to when it is to trigger.
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
#define COAP_SOCKET_CAN_ACCEPT
non blocking server socket can now accept without blocking
#define COAP_SOCKET_WANT_WRITE
non blocking socket is waiting for writing
#define COAP_SOCKET_CAN_CONNECT
non blocking client socket can now connect without blocking
coap_endpoint_t * coap_malloc_endpoint(void)
void coap_epoll_ctl_mod(coap_socket_t *sock, uint32_t events, const char *func)
Epoll specific function to modify the state of events that epoll is tracking on the appropriate file ...
#define COAP_SOCKET_WANT_CONNECT
non blocking client socket is waiting for connect
void coap_mfree_endpoint(coap_endpoint_t *ep)
#define COAP_SOCKET_CAN_READ
non blocking socket can now read without blocking
#define COAP_SOCKET_CONNECTED
the socket is connected
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
coap_tick_t coap_dtls_get_timeout(coap_session_t *session COAP_UNUSED, coap_tick_t now COAP_UNUSED)
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context COAP_UNUSED)
int coap_dtls_handle_timeout(coap_session_t *session COAP_UNUSED)
coap_mid_t coap_session_send_ping(coap_session_t *session)
Send a ping message for the session.
#define SESSIONS_ITER_SAFE(e, el, rtmp)
#define SESSIONS_ITER(e, el, rtmp)
#define COAP_DEFAULT_SESSION_TIMEOUT
void coap_io_do_io(coap_context_t *ctx, coap_tick_t now)
Processes any outstanding read, write, accept or connect I/O as indicated in the coap_socket_t struct...
unsigned int coap_io_prepare_epoll(coap_context_t *ctx, coap_tick_t now)
Any now timed out delayed packet is transmitted, along with any packets associated with requested obs...
void coap_io_do_epoll(coap_context_t *ctx, struct epoll_event *events, size_t nevents)
Process all the epoll events.
unsigned int coap_io_prepare_io(coap_context_t *ctx, coap_socket_t *sockets[], unsigned int max_sockets, unsigned int *num_sockets, coap_tick_t now)
Iterates through all the coap_socket_t structures embedded in endpoints or sessions associated with t...
int coap_io_process(coap_context_t *ctx, uint32_t timeout_ms)
The main I/O processing function.
int coap_io_process_with_fds(coap_context_t *ctx, uint32_t timeout_ms, int enfds, fd_set *ereadfds, fd_set *ewritefds, fd_set *eexceptfds)
The main message processing loop with additional fds for internal select.
int coap_io_pending(coap_context_t *context)
Check to see if there is any i/o pending for the context.
int coap_block_check_lg_crcv_timeouts(coap_session_t *session, coap_tick_t now, coap_tick_t *tim_rem)
int coap_block_check_lg_srcv_timeouts(coap_session_t *session, coap_tick_t now, coap_tick_t *tim_rem)
int coap_block_check_lg_xmit_timeouts(coap_session_t *session, coap_tick_t now, coap_tick_t *tim_rem)
void coap_expire_cache_entries(coap_context_t *context)
Expire coap_cache_entry_t entries.
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
#define COAP_TICKS_PER_SECOND
Use ms resolution on POSIX systems.
coap_queue_t * coap_peek_next(coap_context_t *context)
Returns the next pdu to send without removing from sendqeue.
coap_queue_t * coap_pop_next(coap_context_t *context)
Returns the next pdu to send and removes it from the sendqeue.
coap_mid_t coap_retransmit(coap_context_t *context, coap_queue_t *node)
Handles retransmissions of confirmable messages.
int coap_handle_event(coap_context_t *context, coap_event_t event, coap_session_t *session)
Invokes the event handler of context for the given event and data.
void coap_ticks(coap_tick_t *)
Returns the current value of an internal tick counter.
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
@ COAP_EVENT_SERVER_SESSION_DEL
Called in the CoAP IO loop if a server session is deleted (e.g., due to inactivity or because the max...
@ COAP_EVENT_KEEPALIVE_FAILURE
Triggered when no response to a keep alive (ping) packet.
#define coap_log_debug(...)
#define coap_log_alert(...)
#define coap_log_emerg(...)
const char * coap_session_str(const coap_session_t *session)
Get session description.
#define coap_log_info(...)
#define coap_log_warn(...)
#define coap_log_err(...)
#define coap_log_crit(...)
#define COAP_INVALID_MID
Indicates an invalid message id.
void coap_session_free(coap_session_t *session)
#define COAP_PROTO_RELIABLE(p)
void coap_session_release(coap_session_t *session)
Decrement reference counter on a session.
void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
coap_session_t * coap_session_reference(coap_session_t *session)
Increment reference counter on a session.
@ COAP_SESSION_TYPE_SERVER
server-side
@ COAP_SESSION_TYPE_CLIENT
client-side
@ COAP_SESSION_STATE_HANDSHAKE
@ COAP_SESSION_STATE_ESTABLISHED
@ COAP_SESSION_STATE_NONE
void coap_check_notify(coap_context_t *context)
Checks all known resources to see if they are dirty and then notifies subscribed observers.
coap_address_t remote
remote address and port
coap_address_t local
local address and port
Multi-purpose address abstraction.
socklen_t size
size of addr
struct coap_sockaddr_un cun
union coap_address_t::@0 addr
The CoAP stack's global state is stored in a coap_context_t object.
coap_tick_t sendqueue_basetime
The time stamp in the first element of the sendqeue is relative to sendqueue_basetime.
coap_socket_t * sockets[64]
Track different socket information in coap_io_process_with_fds.
unsigned int csm_timeout
Timeout for waiting for a CSM from the remote side.
unsigned int num_sockets
Number of sockets being tracked.
coap_session_t * sessions
client sessions
fd_set exceptfds
Used for select call in coap_io_process_with_fds()
unsigned int ping_timeout
Minimum inactivity time before sending a ping message.
coap_endpoint_t * endpoint
the endpoints used for listening
unsigned int session_timeout
Number of seconds of inactivity after which an unused session will be closed.
Abstraction of virtual endpoint that can be attached to coap_context_t.
coap_context_t * context
endpoint's context
coap_session_t * sessions
hash table or list of active sessions
coap_address_t bind_addr
local interface address
coap_socket_t sock
socket object for the interface, if any
size_t length
length of payload
coap_addr_tuple_t addr_info
local and remote addresses
unsigned char * payload
payload
int ifindex
the interface index
coap_tick_t t
when to send PDU for the next time
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
coap_lg_xmit_t * lg_xmit
list of large transmissions
coap_socket_t sock
socket object for the session, if any
coap_session_state_t state
current state of relationship with peer
coap_addr_tuple_t addr_info
remote/local address info
coap_proto_t proto
protocol used
unsigned ref
reference count from queues
void * tls
security parameters
coap_queue_t * delayqueue
list of delayed messages waiting to be sent
coap_mid_t last_ping_mid
the last keepalive message id that was used in this session
coap_lg_srcv_t * lg_srcv
Server list of expected large receives.
coap_lg_crcv_t * lg_crcv
Client list of expected large receives.
coap_session_type_t type
client or server side socket
coap_context_t * context
session's context
int ifindex
interface index
char sun_path[COAP_UNIX_PATH_MAX]
coap_session_t * session
Used to determine session owner.
coap_endpoint_t * endpoint
Used by the epoll logic for a listening endpoint.
coap_address_t mcast_addr
remote address and port (multicast track)
coap_socket_flags_t flags
1 or more of COAP_SOCKET* flag values
struct in6_addr ipi6_addr
unsigned int ipi6_ifindex
struct in_addr ipi_spec_dst