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
31 #include <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
50#ifdef COAP_EPOLL_SUPPORT
52#include <sys/timerfd.h>
62#if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
64#if defined(IP_PKTINFO)
65# define GEN_IP_PKTINFO IP_PKTINFO
66#elif defined(IP_RECVDSTADDR)
67# define GEN_IP_PKTINFO IP_RECVDSTADDR
69# error "Need IP_PKTINFO or IP_RECVDSTADDR to request ancillary data from OS."
73#ifdef IPV6_RECVPKTINFO
74# define GEN_IPV6_PKTINFO IPV6_RECVPKTINFO
75#elif defined(IPV6_PKTINFO)
76# define GEN_IPV6_PKTINFO IPV6_PKTINFO
78# error "Need IPV6_PKTINFO or IPV6_RECVPKTINFO to request ancillary data from OS."
83static int ep_initialized = 0;
106 sock->conn = udp_new(NULL, 0, NULL);
114 uip_ipaddr_copy(&bound_addr->
addr, &listen_addr->
addr);
115 bound_addr->port = listen_addr->port;
116 udp_bind((
struct uip_udp_conn *)sock->conn, bound_addr->port);
142 uip_udp_remove((
struct uip_udp_conn *)sock->conn);
148#if COAP_SERVER_SUPPORT
171 sock->
fd = socket(listen_addr->
addr.
sa.sa_family, SOCK_DGRAM, 0);
189 if (setsockopt(sock->
fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on),
sizeof(on)) ==
COAP_SOCKET_ERROR)
191 "coap_socket_bind_udp: setsockopt SO_REUSEADDR: %s\n",
195 switch (listen_addr->
addr.
sa.sa_family) {
197 if (setsockopt(sock->
fd, IPPROTO_IP, GEN_IP_PKTINFO, OPTVAL_T(&on),
sizeof(on)) ==
COAP_SOCKET_ERROR)
199 "coap_socket_bind_udp: setsockopt IP_PKTINFO: %s\n",
204 if (setsockopt(sock->
fd, IPPROTO_IPV6, IPV6_V6ONLY, OPTVAL_T(&off),
sizeof(off)) ==
COAP_SOCKET_ERROR)
206 "coap_socket_bind_udp: setsockopt IPV6_V6ONLY: %s\n",
208#if !defined(ESPIDF_VERSION)
209 if (setsockopt(sock->
fd, IPPROTO_IPV6, GEN_IPV6_PKTINFO, OPTVAL_T(&on),
sizeof(on)) ==
COAP_SOCKET_ERROR)
211 "coap_socket_bind_udp: setsockopt IPV6_PKTINFO: %s\n",
214 setsockopt(sock->
fd, IPPROTO_IP, GEN_IP_PKTINFO, OPTVAL_T(&on),
sizeof(on));
224 if (bind(sock->
fd, &listen_addr->
addr.
sa,
225 listen_addr->
addr.
sa.sa_family == AF_INET ?
226 (socklen_t)
sizeof(
struct sockaddr_in) :
233 bound_addr->
size = (socklen_t)
sizeof(*bound_addr);
234 if (getsockname(sock->
fd, &bound_addr->
addr.
sa, &bound_addr->
size) < 0) {
236 "coap_socket_bind_udp: getsockname: %s\n",
248#if COAP_CLIENT_SUPPORT
268 sock->
fd = socket(connect_addr.
addr.
sa.sa_family, SOCK_DGRAM, 0);
287 switch (connect_addr.
addr.
sa.sa_family) {
289 if (connect_addr.
addr.
sin.sin_port == 0)
290 connect_addr.
addr.
sin.sin_port = htons(default_port);
293 if (connect_addr.
addr.
sin6.sin6_port == 0)
294 connect_addr.
addr.
sin6.sin6_port = htons(default_port);
297 if (setsockopt(sock->
fd, IPPROTO_IPV6, IPV6_V6ONLY, OPTVAL_T(&off),
sizeof(off)) ==
COAP_SOCKET_ERROR)
299 "coap_socket_connect_udp: setsockopt IPV6_V6ONLY: %s\n",
308 if (local_if && local_if->
addr.
sa.sa_family) {
310 if (setsockopt(sock->
fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on),
sizeof(on)) ==
COAP_SOCKET_ERROR)
312 "coap_socket_connect_udp: setsockopt SO_REUSEADDR: %s\n",
315 if (bind(sock->
fd, &local_if->
addr.
sa,
316 local_if->
addr.
sa.sa_family == AF_INET ?
317 (socklen_t)
sizeof(
struct sockaddr_in) :
327 if (!(local_if && local_if->
addr.
sa.sa_family)) {
332 bind_addr.
addr.
sa.sa_family = connect_addr.
addr.
sa.sa_family;
333 if (bind(sock->
fd, &bind_addr.
addr.
sa,
334 bind_addr.
addr.
sa.sa_family == AF_INET ?
335 (socklen_t)
sizeof(
struct sockaddr_in) :
344 "coap_socket_connect_udp: getsockname for multicast socket: %s\n",
379#ifdef COAP_EPOLL_SUPPORT
380#if COAP_SERVER_SUPPORT
386 if (context != NULL) {
388 struct epoll_event event;
391 ret = epoll_ctl(context->epfd, EPOLL_CTL_DEL, sock->
fd, &event);
394 "%s: epoll_ctl DEL failed: %s (%d)\n",
408#ifdef COAP_EPOLL_SUPPORT
415 struct epoll_event event;
421#if COAP_SERVER_SUPPORT
430 event.events = events;
431 event.data.ptr = sock;
433 ret = epoll_ctl(context->epfd, EPOLL_CTL_MOD, sock->
fd, &event);
436 "%s: epoll_ctl MOD failed: %s (%d)\n",
445 if (context->eptimerfd != -1) {
449 if (context->next_timeout == 0 || context->next_timeout > now + delay) {
450 struct itimerspec new_value;
453 context->next_timeout = now + delay;
454 memset(&new_value, 0,
sizeof(new_value));
456 new_value.it_value.tv_nsec = 1;
463 ret = timerfd_settime(context->eptimerfd, 0, &new_value, NULL);
466 "%s: timerfd_settime failed: %s (%d)\n",
467 "coap_resource_notify_observers",
470#ifdef COAP_DEBUG_WAKEUP_TIMES
473 new_value.it_value.tv_sec, new_value.it_value.tv_nsec);
488 r = send(sock->
fd, (
const char *)data, (
int)data_len, 0);
491#define MSG_NOSIGNAL 0
497 if (WSAGetLastError() == WSAEWOULDBLOCK) {
498#elif EAGAIN != EWOULDBLOCK
499 if (errno==EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
501 if (errno==EAGAIN || errno == EINTR) {
504#ifdef COAP_EPOLL_SUPPORT
513 if (errno == EPIPE || errno == ECONNRESET) {
523 if (r < (ssize_t)data_len) {
525#ifdef COAP_EPOLL_SUPPORT
544 r = recv(sock->
fd, (
char *)data, (
int)data_len, 0);
546 r = recv(sock->
fd, data, data_len, 0);
550 sock->
flags &= ~COAP_SOCKET_CAN_READ;
553 sock->
flags &= ~COAP_SOCKET_CAN_READ;
555 error = WSAGetLastError();
556 if (error == WSAEWOULDBLOCK) {
557#elif EAGAIN != EWOULDBLOCK
558 if (errno==EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
560 if (errno==EAGAIN || errno == EINTR) {
565 if (error != WSAECONNRESET)
567 if (errno != ECONNRESET)
573 if (r < (ssize_t)data_len)
574 sock->
flags &= ~COAP_SOCKET_CAN_READ;
580#if (!defined(WITH_CONTIKI)) != ( defined(HAVE_NETINET_IN_H) || defined(HAVE_WS2TCPIP_H) )
596#if !defined(WITH_CONTIKI) && !defined(SOL_IP)
598#define SOL_IP IPPROTO_IP
603static __declspec(thread) LPFN_WSARECVMSG lpWSARecvMsg = NULL;
605#define msghdr _WSAMSG
607#define msg_namelen namelen
608#define msg_iov lpBuffers
609#define msg_iovlen dwBufferCount
610#define msg_control Control.buf
611#define msg_controllen Control.len
615#define iov_len_t u_long
617#define CMSG_DATA WSA_CMSG_DATA
618#define ipi_spec_dst ipi_addr
619#pragma warning( disable : 4116 )
621#define iov_len_t size_t
624#if defined(_CYGWIN_ENV)
625#define ipi_spec_dst ipi_addr
631 ssize_t bytes_written = 0;
634 bytes_written = (ssize_t)datalen;
638 bytes_written = send(sock->
fd, (
const char *)data, (
int)datalen, 0);
640 bytes_written = send(sock->
fd, data, datalen, 0);
645 DWORD dwNumberOfBytesSent = 0;
648#ifdef HAVE_STRUCT_CMSGHDR
657 memcpy (&iov[0].iov_base, &data,
sizeof (iov[0].iov_base));
660 memset(buf, 0,
sizeof (buf));
662 memset(&mhdr, 0,
sizeof(
struct msghdr));
663 memcpy (&mhdr.msg_name, &addr, sizeof (mhdr.msg_name));
674 struct cmsghdr *cmsg;
677#if defined(IP_PKTINFO)
679 mhdr.msg_control = buf;
680 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
682 cmsg = CMSG_FIRSTHDR(&mhdr);
683 cmsg->cmsg_level =
SOL_IP;
684 cmsg->cmsg_type = IP_PKTINFO;
685 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
687 pktinfo = (
struct in_pktinfo *)CMSG_DATA(cmsg);
693#elif defined(IP_SENDSRCADDR)
694 mhdr.msg_control = buf;
695 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_addr));
697 cmsg = CMSG_FIRSTHDR(&mhdr);
698 cmsg->cmsg_level = IPPROTO_IP;
699 cmsg->cmsg_type = IP_SENDSRCADDR;
700 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_addr));
702 memcpy(CMSG_DATA(cmsg),
704 sizeof(
struct in_addr));
708 mhdr.msg_control = buf;
709 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in6_pktinfo));
711 cmsg = CMSG_FIRSTHDR(&mhdr);
712 cmsg->cmsg_level = IPPROTO_IPV6;
713 cmsg->cmsg_type = IPV6_PKTINFO;
714 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in6_pktinfo));
727#if defined(IP_PKTINFO)
728 struct cmsghdr *cmsg;
731 mhdr.msg_control = buf;
732 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
734 cmsg = CMSG_FIRSTHDR(&mhdr);
735 cmsg->cmsg_level =
SOL_IP;
736 cmsg->cmsg_type = IP_PKTINFO;
737 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
739 pktinfo = (
struct in_pktinfo *)CMSG_DATA(cmsg);
745#elif defined(IP_SENDSRCADDR)
746 struct cmsghdr *cmsg;
747 mhdr.msg_control = buf;
748 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_addr));
750 cmsg = CMSG_FIRSTHDR(&mhdr);
751 cmsg->cmsg_level = IPPROTO_IP;
752 cmsg->cmsg_type = IP_SENDSRCADDR;
753 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_addr));
755 memcpy(CMSG_DATA(cmsg),
757 sizeof(
struct in_addr));
769 r = WSASendMsg(sock->
fd, &mhdr, 0 , &dwNumberOfBytesSent, NULL , NULL );
771 bytes_written = (ssize_t)dwNumberOfBytesSent;
775#ifdef HAVE_STRUCT_CMSGHDR
776 bytes_written = sendmsg(sock->
fd, &mhdr, 0);
777#elif !defined(CONTIKI)
778 bytes_written = sendto(sock->
fd, data, datalen, 0,
783#if defined(WITH_CONTIKI)
788 uip_udp_packet_sendto((
struct uip_udp_conn *)sock->conn, data, datalen,
790 bytes_written = datalen;
794 if (bytes_written < 0)
797 return bytes_written;
801#define SIN6(A) ((struct sockaddr_in6 *)(A))
821 sock->
flags &= ~COAP_SOCKET_CAN_READ;
824#if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
833 if (WSAGetLastError() == WSAECONNRESET ||
834 WSAGetLastError() == WSAECONNREFUSED) {
836 if (errno == ECONNREFUSED || errno == EHOSTUNREACH) {
850 }
else if (len > 0) {
851 packet->
length = (size_t)len;
856 DWORD dwNumberOfBytesRecvd = 0;
859#if !defined(WITH_CONTIKI)
860#ifdef HAVE_STRUCT_CMSGHDR
863 struct cmsghdr *cmsg;
867 iov[0].iov_base = packet->
payload;
870 memset(&mhdr, 0,
sizeof(
struct msghdr));
878 mhdr.msg_control = buf;
879 mhdr.msg_controllen =
sizeof(buf);
882 cmsg = (
struct cmsghdr *)buf;
883 cmsg->cmsg_len = CMSG_LEN(
sizeof(buf));
884 cmsg->cmsg_level = -1;
885 cmsg->cmsg_type = -1;
889 GUID wsaid = WSAID_WSARECVMSG;
890 DWORD cbBytesReturned = 0;
891 if (WSAIoctl(sock->
fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &wsaid,
sizeof(wsaid), &lpWSARecvMsg,
sizeof(lpWSARecvMsg), &cbBytesReturned, NULL, NULL) != 0) {
896 r = lpWSARecvMsg(sock->
fd, &mhdr, &dwNumberOfBytesRecvd, NULL , NULL );
898 len = (ssize_t)dwNumberOfBytesRecvd;
900 len = recvmsg(sock->
fd, &mhdr, 0);
911 if (WSAGetLastError() == WSAECONNRESET) {
913 if (errno == ECONNREFUSED) {
921#ifdef HAVE_STRUCT_CMSGHDR
925 packet->
length = (size_t)len;
929 for (cmsg = CMSG_FIRSTHDR(&mhdr); cmsg; cmsg = CMSG_NXTHDR(&mhdr, cmsg)) {
932 if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
937 u.c = CMSG_DATA(cmsg);
938 packet->
ifindex = (int)(u.p->ipi6_ifindex);
940 &u.p->ipi6_addr,
sizeof(
struct in6_addr));
946#if defined(IP_PKTINFO)
947 if (cmsg->cmsg_level ==
SOL_IP && cmsg->cmsg_type == IP_PKTINFO) {
952 u.c = CMSG_DATA(cmsg);
953 packet->
ifindex = u.p->ipi_ifindex;
959 &u.p->ipi_addr,
sizeof(
struct in_addr));
962 &u.p->ipi_addr,
sizeof(
struct in_addr));
967#elif defined(IP_RECVDSTADDR)
968 if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) {
971 CMSG_DATA(cmsg),
sizeof(
struct in_addr));
979 if (cmsg->cmsg_level != -1 && cmsg->cmsg_type != -1) {
981 "cmsg_level = %d and cmsg_type = %d not supported - fix\n",
982 cmsg->cmsg_level, cmsg->cmsg_type);
996 packet->
length = (size_t)len;
1008#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
1009#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN])
1011 if (uip_newdata()) {
1014 uip_ipaddr_copy(&(packet)->addr_info.local.addr, &UIP_IP_BUF->destipaddr);
1017 len = uip_datalen();
1025 ((
char *)uip_appdata)[len] = 0;
1027#ifndef INET6_ADDRSTRLEN
1028#define INET6_ADDRSTRLEN 40
1039 memcpy(&packet->
payload, uip_appdata, len);
1046 packet->src.size =
sizeof(packet->src.addr);
1048 0, &packet->src.addr.sa, &packet->src.size);
1057#if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
1063#if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
1070#if !defined(WITH_CONTIKI)
1074#ifndef COAP_EPOLL_SUPPORT
1078 "coap_io_prepare_epoll() requires libcoap compiled for using epoll\n");
1082 unsigned int max_sockets =
sizeof(sockets)/
sizeof(sockets[0]);
1083 unsigned int num_sockets;
1084 unsigned int timeout;
1089 ctx->next_timeout = timeout ? now + timeout : 0;
1090 if (ctx->eptimerfd != -1) {
1091 struct itimerspec new_value;
1094 memset(&new_value, 0,
sizeof(new_value));
1096 if (ctx->next_timeout != 0 && ctx->next_timeout > now) {
1097 coap_tick_t rem_timeout = ctx->next_timeout - now;
1103#ifdef COAP_DEBUG_WAKEUP_TIMES
1105 new_value.it_value.tv_sec, new_value.it_value.tv_nsec);
1108 ret = timerfd_settime(ctx->eptimerfd, 0, &new_value, NULL);
1111 "%s: timerfd_settime failed: %s (%d)\n",
1112 "coap_io_prepare_epoll",
1127 unsigned int max_sockets,
1128 unsigned int *num_sockets,
1135#if COAP_SERVER_SUPPORT
1136 int check_dtls_timeouts = 0;
1138#ifdef COAP_EPOLL_SUPPORT
1145#if COAP_SERVER_SUPPORT
1150#ifndef WITHOUT_ASYNC
1162 if (nextpdu && (timeout == 0 ||
1170 if (tls_timeout > 0) {
1175 if (timeout == 0 || tls_timeout - now < timeout)
1176 timeout = tls_timeout - now;
1178#if COAP_SERVER_SUPPORT
1180 check_dtls_timeouts = 1;
1184#if COAP_SERVER_SUPPORT
1194#ifndef COAP_EPOLL_SUPPORT
1196 if (*num_sockets < max_sockets)
1197 sockets[(*num_sockets)++] = &ep->
sock;
1211 s_timeout = (s->
last_rx_tx + session_timeout) - now;
1212 if (timeout == 0 || s_timeout < timeout)
1213 timeout = s_timeout;
1221 while (tls_timeout > 0 && tls_timeout <= now) {
1234 if (tls_timeout > 0 && (timeout == 0 || tls_timeout - now < timeout))
1235 timeout = tls_timeout - now;
1240 if (timeout == 0 || s_timeout < timeout)
1241 timeout = s_timeout;
1247 if (timeout == 0 || s_timeout < timeout)
1248 timeout = s_timeout;
1251#ifndef COAP_EPOLL_SUPPORT
1253 if (*num_sockets < max_sockets)
1254 sockets[(*num_sockets)++] = &s->
sock;
1263#if COAP_CLIENT_SUPPORT
1282 if (timeout == 0 || s_timeout < timeout)
1283 timeout = s_timeout;
1286#if !COAP_DISABLE_TCP
1299 if (timeout == 0 || s_timeout < timeout)
1300 timeout = s_timeout;
1310 while (tls_timeout > 0 && tls_timeout <= now) {
1322 if (tls_timeout > 0 && (timeout == 0 || tls_timeout - now < timeout))
1323 timeout = tls_timeout - now;
1329 if (timeout == 0 || s_timeout < timeout)
1330 timeout = s_timeout;
1336 if (timeout == 0 || s_timeout < timeout)
1337 timeout = s_timeout;
1341#ifndef COAP_EPOLL_SUPPORT
1346 if (*num_sockets < max_sockets)
1347 sockets[(*num_sockets)++] = &s->
sock;
1366 int enfds, fd_set *ereadfds, fd_set *ewritefds,
1367 fd_set *eexceptfds) {
1368#if COAP_CONSTRAINED_STACK
1369# ifndef COAP_EPOLL_SUPPORT
1370 static coap_mutex_t static_mutex = COAP_MUTEX_INITIALIZER;
1371 static fd_set readfds, writefds, exceptfds;
1373 unsigned int num_sockets = 0;
1376# ifndef COAP_EPOLL_SUPPORT
1377 fd_set readfds, writefds, exceptfds;
1379 unsigned int num_sockets = 0;
1384 unsigned int timeout;
1385#ifndef COAP_EPOLL_SUPPORT
1393#ifndef COAP_EPOLL_SUPPORT
1395#if COAP_CONSTRAINED_STACK
1396 coap_mutex_lock(&static_mutex);
1400 (
sizeof(sockets) /
sizeof(sockets[0])),
1401 &num_sockets, before);
1402 if (timeout == 0 || timeout_ms < timeout)
1403 timeout = timeout_ms;
1406 readfds = *ereadfds;
1413 writefds = *ewritefds;
1420 exceptfds = *eexceptfds;
1424 FD_ZERO(&exceptfds);
1426 for (i = 0; i < num_sockets; i++) {
1427 if (sockets[i]->fd + 1 > nfds)
1428 nfds = sockets[i]->
fd + 1;
1430 FD_SET(sockets[i]->fd, &readfds);
1432 FD_SET(sockets[i]->fd, &writefds);
1433#if !COAP_DISABLE_TCP
1435 FD_SET(sockets[i]->fd, &readfds);
1437 FD_SET(sockets[i]->fd, &writefds);
1438 FD_SET(sockets[i]->fd, &exceptfds);
1448 else if (timeout > 0) {
1449 tv.tv_usec = (timeout % 1000) * 1000;
1450 tv.tv_sec = (long)(timeout / 1000);
1453 result = select((
int)nfds, &readfds, &writefds, &exceptfds, timeout > 0 ? &tv : NULL);
1457 if (WSAGetLastError() != WSAEINVAL) {
1459 if (errno != EINTR) {
1462#if COAP_CONSTRAINED_STACK
1463 coap_mutex_unlock(&static_mutex);
1469 *ereadfds = readfds;
1472 *ewritefds = writefds;
1475 *eexceptfds = exceptfds;
1479 for (i = 0; i < num_sockets; i++) {
1482#if !COAP_DISABLE_TCP
1487 if ((sockets[i]->flags &
COAP_SOCKET_WANT_CONNECT) && (FD_ISSET(sockets[i]->fd, &writefds) || FD_ISSET(sockets[i]->fd, &exceptfds)))
1493#if COAP_CONSTRAINED_STACK
1494 coap_mutex_unlock(&static_mutex);
1508 if (timeout == 0 || timeout_ms < timeout)
1509 timeout = timeout_ms;
1513 int etimeout = timeout;
1523 else if (etimeout < 0) {
1530 if (errno != EINTR) {
1550#if COAP_SERVER_SUPPORT
1554#ifndef WITHOUT_ASYNC
1580 unsigned int max_sockets,
1581 unsigned int *num_sockets,
1591 static char szError[256];
1592 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)
1593 strcpy(szError,
"Unknown error");
1602 return strerror(error);
1611 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.
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)
const char * coap_socket_strerror(void)
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)
ssize_t coap_network_read(coap_socket_t *sock, coap_packet_t *packet)
Function interface for reading data.
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.
const char * coap_socket_format_errno(int error)
#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_mfree_endpoint(struct coap_endpoint_t *ep)
struct coap_endpoint_t * coap_malloc_endpoint(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
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
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
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 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_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.
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_tick_t coap_check_async(coap_context_t *context, coap_tick_t now)
Checks if there are any pending Async requests - if so, send them off.
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.
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_log_t coap_get_log_level(void)
Get the current logging level.
size_t coap_print_addr(const coap_address_t *addr, unsigned char *buf, size_t len)
Print the address into the defined buffer.
const char * coap_session_str(const coap_session_t *session)
Get session description.
#define coap_log(level,...)
Logging function.
#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.
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_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
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_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 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_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
coap_endpoint_t * endpoint
coap_socket_flags_t flags
struct in6_addr ipi6_addr
unsigned int ipi6_ifindex
struct in_addr ipi_spec_dst