15 #ifdef HAVE_SYS_SELECT_H
16 # include <sys/select.h>
18 #ifdef HAVE_SYS_SOCKET_H
19 # include <sys/socket.h>
20 # define OPTVAL_T(t) (t)
21 # define OPTVAL_GT(t) (t)
23 #ifdef HAVE_SYS_IOCTL_H
24 #include <sys/ioctl.h>
26 #ifdef HAVE_NETINET_IN_H
27 # include <netinet/in.h>
29 #ifdef HAVE_WS2TCPIP_H
31 # define OPTVAL_T(t) (const char*)(t)
32 # define OPTVAL_GT(t) (char*)(t)
34 # define CMSG_DATA WSA_CMSG_DATA
43 #ifdef COAP_EPOLL_SUPPORT
44 #include <sys/epoll.h>
45 #include <sys/timerfd.h>
52 #if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
54 #if defined(IP_PKTINFO)
55 # define GEN_IP_PKTINFO IP_PKTINFO
56 #elif defined(IP_RECVDSTADDR)
57 # define GEN_IP_PKTINFO IP_RECVDSTADDR
59 # error "Need IP_PKTINFO or IP_RECVDSTADDR to request ancillary data from OS."
63 #ifdef IPV6_RECVPKTINFO
64 # define GEN_IPV6_PKTINFO IPV6_RECVPKTINFO
65 #elif defined(IPV6_PKTINFO)
66 # define GEN_IPV6_PKTINFO IPV6_PKTINFO
68 # error "Need IPV6_PKTINFO or IPV6_RECVPKTINFO to request ancillary data from OS."
75 static int ep_initialized = 0;
98 sock->conn = udp_new(NULL, 0, NULL);
101 coap_log(COAP_LOG_WARNING,
"coap_socket_bind_udp");
106 uip_ipaddr_copy(&bound_addr->
addr, &listen_addr->
addr);
107 bound_addr->port = listen_addr->port;
108 udp_bind((
struct uip_udp_conn *)
sock->conn, bound_addr->port);
166 uip_udp_remove((
struct uip_udp_conn *)
sock->conn);
195 sock->
fd = socket(listen_addr->
addr.
sa.sa_family, SOCK_DGRAM, 0);
215 "coap_socket_bind_udp: setsockopt SO_REUSEADDR: %s\n",
219 switch (listen_addr->
addr.
sa.sa_family) {
223 "coap_socket_bind_udp: setsockopt IP_PKTINFO: %s\n",
230 "coap_socket_bind_udp: setsockopt IPV6_V6ONLY: %s\n",
234 "coap_socket_bind_udp: setsockopt IPV6_PKTINFO: %s\n",
236 setsockopt(
sock->
fd, IPPROTO_IP, GEN_IP_PKTINFO, OPTVAL_T(&on),
sizeof(on));
239 coap_log(COAP_LOG_ALERT,
"coap_socket_bind_udp: unsupported sa_family\n");
245 coap_log(COAP_LOG_WARNING,
"coap_socket_bind_udp: bind: %s\n",
250 bound_addr->
size = (socklen_t)
sizeof(*bound_addr);
253 "coap_socket_bind_udp: getsockname: %s\n",
283 sock->
fd = socket(server->
addr.
sa.sa_family, SOCK_STREAM, 0);
287 "coap_socket_connect_tcp1: socket: %s\n",
299 "coap_socket_connect_tcp1: ioctl FIONBIO: %s\n",
304 switch (server->
addr.
sa.sa_family) {
306 if (connect_addr.
addr.
sin.sin_port == 0)
307 connect_addr.
addr.
sin.sin_port = htons(default_port);
310 if (connect_addr.
addr.
sin6.sin6_port == 0)
311 connect_addr.
addr.
sin6.sin6_port = htons(default_port);
316 "coap_socket_connect_tcp1: setsockopt IPV6_V6ONLY: %s\n",
321 coap_log(COAP_LOG_ALERT,
"coap_socket_connect_tcp1: unsupported sa_family\n");
325 if (local_if && local_if->
addr.
sa.sa_family) {
329 "coap_socket_connect_tcp1: setsockopt SO_REUSEADDR: %s\n",
332 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_tcp1: bind: %s\n",
337 local_addr->
addr.
sa.sa_family = server->
addr.
sa.sa_family;
342 if (WSAGetLastError() == WSAEWOULDBLOCK) {
344 if (errno == EINPROGRESS) {
354 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_tcp1: connect: %s\n",
360 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_tcp1: getsockname: %s\n",
365 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_tcp1: getpeername: %s\n",
383 int optlen = (int)
sizeof( error );
385 socklen_t optlen = (socklen_t)
sizeof( error );
390 if (getsockopt(
sock->
fd, SOL_SOCKET, SO_ERROR, OPTVAL_GT(&error),
392 coap_log(COAP_LOG_WARNING,
"coap_socket_finish_connect_tcp: getsockopt: %s\n",
398 "coap_socket_finish_connect_tcp: connect failed: %s\n",
405 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_tcp: getsockname: %s\n",
410 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_tcp: getpeername: %s\n",
429 sock->
fd = socket(listen_addr->
addr.
sa.sa_family, SOCK_STREAM, 0);
432 coap_log(COAP_LOG_WARNING,
"coap_socket_bind_tcp: socket: %s\n",
443 coap_log(COAP_LOG_WARNING,
"coap_socket_bind_tcp: ioctl FIONBIO: %s\n",
447 if (setsockopt (
sock->
fd, SOL_SOCKET, SO_KEEPALIVE, OPTVAL_T(&on),
450 "coap_socket_bind_tcp: setsockopt SO_KEEPALIVE: %s\n",
453 if (setsockopt(
sock->
fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on),
456 "coap_socket_bind_tcp: setsockopt SO_REUSEADDR: %s\n",
459 switch (listen_addr->
addr.
sa.sa_family) {
467 "coap_socket_bind_tcp: setsockopt IPV6_V6ONLY: %s\n",
472 coap_log(COAP_LOG_ALERT,
"coap_socket_bind_tcp: unsupported sa_family\n");
476 coap_log(COAP_LOG_ALERT,
"coap_socket_bind_tcp: bind: %s\n",
481 bound_addr->
size = (socklen_t)
sizeof(*bound_addr);
483 coap_log(COAP_LOG_WARNING,
"coap_socket_bind_tcp: getsockname: %s\n",
489 coap_log(COAP_LOG_ALERT,
"coap_socket_bind_tcp: listen: %s\n",
516 new_client->
fd = accept(server->
fd, &remote_addr->
addr.
sa,
519 coap_log(COAP_LOG_WARNING,
"coap_socket_accept_tcp: accept: %s\n",
524 if (getsockname( new_client->
fd, &local_addr->
addr.
sa, &local_addr->
size) < 0)
525 coap_log(COAP_LOG_WARNING,
"coap_socket_accept_tcp: getsockname: %s\n",
534 coap_log(COAP_LOG_WARNING,
"coap_socket_accept_tcp: ioctl FIONBIO: %s\n",
560 sock->
fd = socket(connect_addr.
addr.
sa.sa_family, SOCK_DGRAM, 0);
563 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_udp: socket: %s\n",
574 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_udp: ioctl FIONBIO: %s\n",
579 switch (connect_addr.
addr.
sa.sa_family) {
581 if (connect_addr.
addr.
sin.sin_port == 0)
582 connect_addr.
addr.
sin.sin_port = htons(default_port);
585 if (connect_addr.
addr.
sin6.sin6_port == 0)
586 connect_addr.
addr.
sin6.sin6_port = htons(default_port);
591 "coap_socket_connect_udp: setsockopt IPV6_V6ONLY: %s\n",
596 coap_log(COAP_LOG_ALERT,
"coap_socket_connect_udp: unsupported sa_family\n");
600 if (local_if && local_if->
addr.
sa.sa_family) {
604 "coap_socket_connect_udp: setsockopt SO_REUSEADDR: %s\n",
608 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_udp: bind: %s\n",
618 "coap_socket_connect_udp: getsockname for multicast socket: %s\n",
627 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_udp: connect: %s\n",
633 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_udp: getsockname: %s\n",
638 coap_log(COAP_LOG_WARNING,
"coap_socket_connect_udp: getpeername: %s\n",
652 #ifdef COAP_EPOLL_SUPPORT
657 struct epoll_event event;
660 ret = epoll_ctl(context->epfd, EPOLL_CTL_DEL, sock->
fd, &event);
663 "%s: epoll_ctl DEL failed: %s (%d)\n",
677 #ifdef COAP_EPOLL_SUPPORT
684 struct epoll_event event;
695 event.events = events;
696 event.data.ptr = sock;
698 ret = epoll_ctl(context->epfd, EPOLL_CTL_MOD, sock->
fd, &event);
701 "%s: epoll_ctl MOD failed: %s (%d)\n",
714 r = send(sock->
fd, (
const char *)data, (
int)data_len, 0);
716 r = send(sock->
fd, data, data_len, 0);
720 if (WSAGetLastError() == WSAEWOULDBLOCK) {
721 #elif EAGAIN != EWOULDBLOCK
722 if (errno==EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
724 if (errno==EAGAIN || errno == EINTR) {
727 #ifdef COAP_EPOLL_SUPPORT
736 coap_log(COAP_LOG_WARNING,
"coap_socket_write: send: %s\n",
740 if (r < (ssize_t)data_len) {
742 #ifdef COAP_EPOLL_SUPPORT
761 r = recv(sock->
fd, (
char *)data, (
int)data_len, 0);
763 r = recv(sock->
fd, data, data_len, 0);
772 error = WSAGetLastError();
773 if (error == WSAEWOULDBLOCK) {
774 #elif EAGAIN != EWOULDBLOCK
775 if (errno==EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
777 if (errno==EAGAIN || errno == EINTR) {
782 if (error != WSAECONNRESET)
784 if (errno != ECONNRESET)
786 coap_log(COAP_LOG_WARNING,
"coap_socket_read: recv: %s\n",
790 if (r < (ssize_t)data_len)
797 #if (!defined(WITH_CONTIKI)) != ( defined(HAVE_NETINET_IN_H) || defined(HAVE_WS2TCPIP_H) )
813 #if !defined(WITH_CONTIKI) && !defined(SOL_IP)
815 #define SOL_IP IPPROTO_IP
819 #define UNUSED_PARAM __attribute__ ((unused))
826 static __declspec(thread) LPFN_WSARECVMSG lpWSARecvMsg = NULL;
828 #define msghdr _WSAMSG
829 #define msg_name name
830 #define msg_namelen namelen
831 #define msg_iov lpBuffers
832 #define msg_iovlen dwBufferCount
833 #define msg_control Control.buf
834 #define msg_controllen Control.len
835 #define iovec _WSABUF
838 #define iov_len_t u_long
840 #define CMSG_DATA WSA_CMSG_DATA
841 #define ipi_spec_dst ipi_addr
843 #define iov_len_t size_t
849 ssize_t bytes_written = 0;
852 bytes_written = (ssize_t)datalen;
856 bytes_written = send(sock->
fd, (
const char *)data, (
int)datalen, 0);
858 bytes_written = send(sock->
fd, data, datalen, 0);
863 DWORD dwNumberOfBytesSent = 0;
866 #ifdef HAVE_STRUCT_CMSGHDR
875 memcpy (&iov[0].iov_base, &data,
sizeof (iov[0].iov_base));
878 memset(buf, 0,
sizeof (buf));
880 memset(&mhdr, 0,
sizeof(
struct msghdr));
881 memcpy (&mhdr.msg_name, &addr, sizeof (mhdr.msg_name));
892 struct cmsghdr *cmsg;
895 #if defined(IP_PKTINFO)
897 mhdr.msg_control = buf;
898 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
900 cmsg = CMSG_FIRSTHDR(&mhdr);
901 cmsg->cmsg_level =
SOL_IP;
902 cmsg->cmsg_type = IP_PKTINFO;
903 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
905 pktinfo = (
struct in_pktinfo *)CMSG_DATA(cmsg);
911 #elif defined(IP_SENDSRCADDR)
912 mhdr.msg_control = buf;
913 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_addr));
915 cmsg = CMSG_FIRSTHDR(&mhdr);
916 cmsg->cmsg_level = IPPROTO_IP;
917 cmsg->cmsg_type = IP_SENDSRCADDR;
918 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_addr));
920 memcpy(CMSG_DATA(cmsg),
922 sizeof(
struct in_addr));
926 mhdr.msg_control = buf;
927 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in6_pktinfo));
929 cmsg = CMSG_FIRSTHDR(&mhdr);
930 cmsg->cmsg_level = IPPROTO_IPV6;
931 cmsg->cmsg_type = IPV6_PKTINFO;
932 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in6_pktinfo));
945 #if defined(IP_PKTINFO)
946 struct cmsghdr *cmsg;
949 mhdr.msg_control = buf;
950 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
952 cmsg = CMSG_FIRSTHDR(&mhdr);
953 cmsg->cmsg_level =
SOL_IP;
954 cmsg->cmsg_type = IP_PKTINFO;
955 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
957 pktinfo = (
struct in_pktinfo *)CMSG_DATA(cmsg);
963 #elif defined(IP_SENDSRCADDR)
964 struct cmsghdr *cmsg;
965 mhdr.msg_control = buf;
966 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_addr));
968 cmsg = CMSG_FIRSTHDR(&mhdr);
969 cmsg->cmsg_level = IPPROTO_IP;
970 cmsg->cmsg_type = IP_SENDSRCADDR;
971 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_addr));
973 memcpy(CMSG_DATA(cmsg),
975 sizeof(
struct in_addr));
981 coap_log(COAP_LOG_WARNING,
"protocol not supported\n");
987 r = WSASendMsg(sock->
fd, &mhdr, 0 , &dwNumberOfBytesSent, NULL , NULL );
989 bytes_written = (ssize_t)dwNumberOfBytesSent;
993 #ifdef HAVE_STRUCT_CMSGHDR
994 bytes_written = sendmsg(sock->
fd, &mhdr, 0);
996 bytes_written = sendto(sock->
fd, data, datalen, 0,
1001 #if defined(WITH_CONTIKI)
1006 uip_udp_packet_sendto((
struct uip_udp_conn *)sock->conn, data, datalen,
1008 bytes_written = datalen;
1009 #elif defined(RIOT_VERSION)
1010 bytes_written = sendto(sock->
fd, data, datalen, 0,
1011 &session->remote_addr.addr.sa,
1012 session->remote_addr.size);
1016 if (bytes_written < 0)
1019 return bytes_written;
1023 #define SIN6(A) ((struct sockaddr_in6 *)(A))
1028 *length = packet->
length;
1031 #ifndef RIOT_VERSION
1046 #if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
1055 if (WSAGetLastError() == WSAECONNRESET) {
1057 if (errno == ECONNREFUSED) {
1060 coap_log(COAP_LOG_WARNING,
"coap_network_read: unreachable\n");
1065 }
else if (len > 0) {
1066 packet->
length = (size_t)len;
1071 DWORD dwNumberOfBytesRecvd = 0;
1074 #if !defined(WITH_CONTIKI)
1075 #ifdef HAVE_STRUCT_CMSGHDR
1078 struct cmsghdr *cmsg;
1080 struct iovec iov[1];
1082 iov[0].iov_base = packet->
payload;
1085 memset(&mhdr, 0,
sizeof(
struct msghdr));
1091 mhdr.msg_iovlen = 1;
1093 mhdr.msg_control = buf;
1094 mhdr.msg_controllen =
sizeof(buf);
1097 cmsg = (
struct cmsghdr *)buf;
1098 cmsg->cmsg_len = CMSG_LEN(
sizeof(buf));
1099 cmsg->cmsg_level = -1;
1100 cmsg->cmsg_type = -1;
1103 if (!lpWSARecvMsg) {
1104 GUID wsaid = WSAID_WSARECVMSG;
1105 DWORD cbBytesReturned = 0;
1106 if (WSAIoctl(sock->
fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &wsaid,
sizeof(wsaid), &lpWSARecvMsg,
sizeof(lpWSARecvMsg), &cbBytesReturned, NULL, NULL) != 0) {
1107 coap_log(COAP_LOG_WARNING,
"coap_network_read: no WSARecvMsg\n");
1111 r = lpWSARecvMsg(sock->
fd, &mhdr, &dwNumberOfBytesRecvd, NULL , NULL );
1113 len = (ssize_t)dwNumberOfBytesRecvd;
1115 len = recvmsg(sock->
fd, &mhdr, 0);
1126 if (WSAGetLastError() == WSAECONNRESET) {
1128 if (errno == ECONNREFUSED) {
1136 #ifdef HAVE_STRUCT_CMSGHDR
1140 packet->
length = (size_t)len;
1144 for (cmsg = CMSG_FIRSTHDR(&mhdr); cmsg; cmsg = CMSG_NXTHDR(&mhdr, cmsg)) {
1147 if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
1152 u.c = CMSG_DATA(cmsg);
1153 packet->
ifindex = (int)(u.p->ipi6_ifindex);
1155 &u.p->ipi6_addr,
sizeof(
struct in6_addr));
1161 #if defined(IP_PKTINFO)
1162 if (cmsg->cmsg_level ==
SOL_IP && cmsg->cmsg_type == IP_PKTINFO) {
1167 u.c = CMSG_DATA(cmsg);
1168 packet->
ifindex = u.p->ipi_ifindex;
1174 &u.p->ipi_addr,
sizeof(
struct in_addr));
1177 &u.p->ipi_addr,
sizeof(
struct in_addr));
1182 #elif defined(IP_RECVDSTADDR)
1183 if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) {
1186 CMSG_DATA(cmsg),
sizeof(
struct in_addr));
1194 if (cmsg->cmsg_level != -1 && cmsg->cmsg_type != -1) {
1196 "cmsg_level = %d and cmsg_type = %d not supported - fix\n",
1197 cmsg->cmsg_level, cmsg->cmsg_type);
1207 coap_log(COAP_LOG_DEBUG,
"Cannot determine local port\n");
1211 packet->
length = (size_t)len;
1215 coap_log(COAP_LOG_DEBUG,
"Cannot determine local port\n");
1223 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
1224 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN])
1226 if (uip_newdata()) {
1229 uip_ipaddr_copy(&(packet)->addr_info.local.addr, &UIP_IP_BUF->destipaddr);
1232 len = uip_datalen();
1236 coap_log(COAP_LOG_WARNING,
"discarded oversized packet\n");
1240 ((
char *)uip_appdata)[len] = 0;
1243 #ifndef INET6_ADDRSTRLEN
1244 #define INET6_ADDRSTRLEN 40
1250 coap_log(COAP_LOG_DEBUG,
"received %zd bytes from %s\n", len, addr_str);
1256 memcpy(&packet->
payload, uip_appdata, len);
1263 packet->src.size =
sizeof(packet->src.addr);
1265 0, &packet->src.addr.sa, &packet->src.size);
1270 coap_log(COAP_LOG_DEBUG,
"received %zd bytes from %s\n", len, addr_str);
1274 #if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
1280 #if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
1287 #if !defined(WITH_CONTIKI)
1292 unsigned int max_sockets,
1293 unsigned int *num_sockets,
1301 #ifdef COAP_EPOLL_SUPPORT
1317 #ifndef COAP_EPOLL_SUPPORT
1319 if (*num_sockets < max_sockets)
1320 sockets[(*num_sockets)++] = &ep->
sock;
1332 if (timeout == 0 || s_timeout < timeout)
1333 timeout = s_timeout;
1335 #ifndef COAP_EPOLL_SUPPORT
1337 if (*num_sockets < max_sockets)
1338 sockets[(*num_sockets)++] = &s->
sock;
1365 if (timeout == 0 || s_timeout < timeout)
1366 timeout = s_timeout;
1386 if (timeout == 0 || s_timeout < timeout)
1387 timeout = s_timeout;
1390 #ifndef COAP_EPOLL_SUPPORT
1392 if (*num_sockets < max_sockets)
1393 sockets[(*num_sockets)++] = &s->
sock;
1405 if (nextpdu && (timeout == 0 || nextpdu->
t - ( now - ctx->
sendqueue_basetime ) < timeout))
1411 if (tls_timeout > 0) {
1414 coap_log(COAP_LOG_DEBUG,
"** DTLS global timeout set to %dms\n",
1416 if (timeout == 0 || tls_timeout - now < timeout)
1417 timeout = tls_timeout - now;
1425 while (tls_timeout > 0 && tls_timeout <= now) {
1426 coap_log(COAP_LOG_DEBUG,
"** %s: DTLS retransmit timeout\n",
1436 if (tls_timeout > 0 && (timeout == 0 || tls_timeout - now < timeout))
1437 timeout = tls_timeout - now;
1445 while (tls_timeout > 0 && tls_timeout <= now) {
1455 if (tls_timeout > 0 && (timeout == 0 || tls_timeout - now < timeout))
1456 timeout = tls_timeout - now;
1465 #ifndef RIOT_VERSION
1468 #if COAP_CONSTRAINED_STACK
1469 static coap_mutex_t static_mutex = COAP_MUTEX_INITIALIZER;
1470 # ifndef COAP_EPOLL_SUPPORT
1471 static fd_set readfds, writefds, exceptfds;
1475 # ifndef COAP_EPOLL_SUPPORT
1476 fd_set readfds, writefds, exceptfds;
1482 unsigned int num_sockets = 0, timeout;
1483 #ifndef COAP_EPOLL_SUPPORT
1489 #if COAP_CONSTRAINED_STACK
1490 coap_mutex_lock(&static_mutex);
1495 timeout =
coap_write(ctx, sockets, (
unsigned int)(
sizeof(sockets) /
sizeof(sockets[0])), &num_sockets, before);
1496 #ifdef COAP_EPOLL_SUPPORT
1498 ctx->next_timeout = timeout ? before + timeout : 0;
1500 if (timeout == 0 || timeout_ms < timeout)
1501 timeout = timeout_ms;
1503 #ifndef COAP_EPOLL_SUPPORT
1506 FD_ZERO(&exceptfds);
1507 for (i = 0; i < num_sockets; i++) {
1508 if (sockets[i]->fd + 1 > nfds)
1509 nfds = sockets[i]->
fd + 1;
1511 FD_SET(sockets[i]->fd, &readfds);
1513 FD_SET(sockets[i]->fd, &writefds);
1515 FD_SET(sockets[i]->fd, &readfds);
1517 FD_SET(sockets[i]->fd, &writefds);
1518 FD_SET(sockets[i]->fd, &exceptfds);
1522 if ( timeout > 0 ) {
1525 tv.tv_usec = (timeout % 1000) * 1000;
1526 tv.tv_sec = (long)(timeout / 1000);
1529 result = select(nfds, &readfds, &writefds, &exceptfds, timeout > 0 ? &tv : NULL);
1533 if (WSAGetLastError() != WSAEINVAL) {
1535 if (errno != EINTR) {
1538 #if COAP_CONSTRAINED_STACK
1539 coap_mutex_unlock(&static_mutex);
1546 for (i = 0; i < num_sockets; i++) {
1553 if ((sockets[i]->flags &
COAP_SOCKET_WANT_CONNECT) && (FD_ISSET(sockets[i]->fd, &writefds) || FD_ISSET(sockets[i]->fd, &exceptfds)))
1564 int etimeout = timeout;
1574 if (errno != EINTR) {
1575 coap_log (COAP_LOG_ERR,
"epoll_wait: unexpected error: %s (%d)\n",
1581 if (coap_io_do_events(ctx, events, nfds)) {
1585 (
unsigned int)(
sizeof(sockets) /
sizeof(sockets[0])),
1599 if (ctx->eptimerfd != -1) {
1600 struct itimerspec new_value;
1603 memset(&new_value, 0,
sizeof(new_value));
1605 if (ctx->next_timeout != 0 && ctx->next_timeout > now) {
1606 coap_tick_t rem_timeout = ctx->next_timeout - now;
1613 ret = timerfd_settime(ctx->eptimerfd, 0, &new_value, NULL);
1616 "%s: timerfd_settime failed: %s (%d)\n",
1624 #if COAP_CONSTRAINED_STACK
1625 coap_mutex_unlock(&static_mutex);
1647 unsigned int max_sockets,
1648 unsigned int *num_sockets,
1658 static char szError[256];
1659 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD)error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)szError, (DWORD)
sizeof(szError), NULL) == 0)
1660 strcpy(szError,
"Unknown error");
1668 #ifndef WITH_CONTIKI
1670 return strerror(error);
1675 return strerror(errno);
1681 const uint8_t *data,
size_t data_len) {
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.
COAP_STATIC_INLINE int coap_address_isany(const coap_address_t *a)
Checks if given address object a denotes the wildcard address.
COAP_STATIC_INLINE void coap_address_copy(coap_address_t *dst, const coap_address_t *src)
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_MAX_EPOLL_EVENTS
#define COAP_RXBUFFER_SIZE
#define COAP_SOCKET_ERROR
@ COAP_NACK_NOT_DELIVERABLE
#define COAP_INVALID_SOCKET
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)
void coap_free_endpoint(coap_endpoint_t *ep)
ssize_t coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len)
void coap_socket_close(coap_socket_t *sock)
ssize_t coap_socket_send(coap_socket_t *sock, coap_session_t *session, const uint8_t *data, size_t data_len)
void coap_mfree_endpoint(struct coap_endpoint_t *ep)
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)
int coap_run_once(coap_context_t *ctx, unsigned timeout_ms)
struct coap_endpoint_t * coap_malloc_endpoint(void)
ssize_t coap_network_read(coap_socket_t *sock, coap_packet_t *packet)
Function interface for reading data.
static const char * coap_socket_format_errno(int error)
int coap_socket_bind_udp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
ssize_t coap_network_send(coap_socket_t *sock, const coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for data transmission.
unsigned int coap_write(coap_context_t *ctx, coap_socket_t *sockets[], unsigned int max_sockets, unsigned int *num_sockets, coap_tick_t now)
const char * coap_socket_strerror(void)
#define COAP_SOCKET_MULTICAST
socket is used for multicast communication
#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
#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
void coap_epoll_ctl_mod(coap_socket_t *sock, uint32_t events, const char *func)
#define COAP_SOCKET_WANT_CONNECT
non blocking client socket is waiting for connect
#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_dtls_handle_timeout(coap_session_t *session COAP_UNUSED)
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)
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_ticks(coap_tick_t *t)
Sets t to the internal time with COAP_TICKS_PER_SECOND resolution.
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_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
coap_log_t coap_get_log_level(void)
Get the current logging level.
const char * coap_session_str(const coap_session_t *session)
Get session description.
size_t coap_print_addr(const coap_address_t *addr, unsigned char *buf, size_t len)
Print the address into the defined buffer.
#define coap_log(level,...)
Logging function.
#define COAP_INVALID_TID
Indicates an invalid message id.
void coap_session_free(coap_session_t *session)
coap_session_t * coap_session_reference(coap_session_t *session)
Increment reference counter on a 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_TYPE_SERVER
server-side
@ COAP_SESSION_TYPE_CLIENT
client-side
@ 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.
int coap_socket_bind_tcp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Create a new TCP socket and then listen for new incoming TCP sessions.
int coap_socket_connect_tcp1(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)
Create a new TCP socket and initiate the connection.
int coap_socket_accept_tcp(coap_socket_t *server, coap_socket_t *new_client, coap_address_t *local_addr, coap_address_t *remote_addr)
Accept a new incoming TCP session.
int coap_socket_connect_tcp2(coap_socket_t *sock, coap_address_t *local_addr, coap_address_t *remote_addr)
Complete the TCP Connection.
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().
#define COAP_RUN_NONBLOCK
COAP_STATIC_INLINE COAP_DEPRECATED void coap_read(coap_context_t *ctx, coap_tick_t now)
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
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.
unsigned int csm_timeout
Timeout for waiting for a CSM from the remote side.
coap_session_t * sessions
client sessions
unsigned int ping_timeout
Minimum inactivity time before sending a ping message.
ssize_t(* network_send)(coap_socket_t *sock, const coap_session_t *session, const uint8_t *data, size_t datalen)
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_socket_t sock
socket object for the interface, if any
coap_proto_t proto
protocol used on this interface
size_t length
length of payload
coap_addr_tuple_t addr_info
local and remote addresses
unsigned char payload[COAP_RXBUFFER_SIZE]
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_socket_t sock
socket object for the session, if any
coap_session_state_t state
current state of relationaship with peer
coap_addr_tuple_t addr_info
key: remote/local address info
coap_proto_t proto
protocol used
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_session_type_t type
client or server side socket
coap_context_t * context
session's context
int ifindex
interface index
coap_endpoint_t * endpoint
coap_socket_flags_t flags
struct in6_addr ipi6_addr
unsigned int ipi6_ifindex
struct in_addr ipi_spec_dst