17 #ifdef HAVE_SYS_SELECT_H
18 # include <sys/select.h>
20 #ifdef HAVE_SYS_SOCKET_H
21 # include <sys/socket.h>
22 # define OPTVAL_T(t) (t)
23 # define OPTVAL_GT(t) (t)
25 #ifdef HAVE_SYS_IOCTL_H
26 #include <sys/ioctl.h>
28 #ifdef HAVE_NETINET_IN_H
29 # include <netinet/in.h>
31 #ifdef HAVE_WS2TCPIP_H
33 # define OPTVAL_T(t) (const char*)(t)
34 # define OPTVAL_GT(t) (char*)(t)
36 # define CMSG_DATA WSA_CMSG_DATA
45 #ifdef COAP_EPOLL_SUPPORT
46 #include <sys/epoll.h>
47 #include <sys/timerfd.h>
57 #if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
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."
78 static int ep_initialized = 0;
101 sock->conn = udp_new(NULL, 0, NULL);
109 uip_ipaddr_copy(&bound_addr->
addr, &listen_addr->
addr);
110 bound_addr->port = listen_addr->port;
111 udp_bind((
struct uip_udp_conn *)sock->conn, bound_addr->port);
137 uip_udp_remove((
struct uip_udp_conn *)sock->conn);
164 sock->
fd = socket(listen_addr->
addr.
sa.sa_family, SOCK_DGRAM, 0);
182 if (setsockopt(sock->
fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on),
sizeof(on)) ==
COAP_SOCKET_ERROR)
184 "coap_socket_bind_udp: setsockopt SO_REUSEADDR: %s\n",
188 switch (listen_addr->
addr.
sa.sa_family) {
190 if (setsockopt(sock->
fd, IPPROTO_IP, GEN_IP_PKTINFO, OPTVAL_T(&on),
sizeof(on)) ==
COAP_SOCKET_ERROR)
192 "coap_socket_bind_udp: setsockopt IP_PKTINFO: %s\n",
197 if (setsockopt(sock->
fd, IPPROTO_IPV6, IPV6_V6ONLY, OPTVAL_T(&off),
sizeof(off)) ==
COAP_SOCKET_ERROR)
199 "coap_socket_bind_udp: setsockopt IPV6_V6ONLY: %s\n",
201 #if !defined(ESPIDF_VERSION)
202 if (setsockopt(sock->
fd, IPPROTO_IPV6, GEN_IPV6_PKTINFO, OPTVAL_T(&on),
sizeof(on)) ==
COAP_SOCKET_ERROR)
204 "coap_socket_bind_udp: setsockopt IPV6_PKTINFO: %s\n",
207 setsockopt(sock->
fd, IPPROTO_IP, GEN_IP_PKTINFO, OPTVAL_T(&on),
sizeof(on));
217 if (bind(sock->
fd, &listen_addr->
addr.
sa,
218 listen_addr->
addr.
sa.sa_family == AF_INET ?
219 (socklen_t)
sizeof(
struct sockaddr_in) :
226 bound_addr->
size = (socklen_t)
sizeof(*bound_addr);
227 if (getsockname(sock->
fd, &bound_addr->
addr.
sa, &bound_addr->
size) < 0) {
229 "coap_socket_bind_udp: getsockname: %s\n",
260 sock->
fd = socket(connect_addr.
addr.
sa.sa_family, SOCK_DGRAM, 0);
279 switch (connect_addr.
addr.
sa.sa_family) {
281 if (connect_addr.
addr.
sin.sin_port == 0)
282 connect_addr.
addr.
sin.sin_port = htons(default_port);
285 if (connect_addr.
addr.
sin6.sin6_port == 0)
286 connect_addr.
addr.
sin6.sin6_port = htons(default_port);
289 if (setsockopt(sock->
fd, IPPROTO_IPV6, IPV6_V6ONLY, OPTVAL_T(&off),
sizeof(off)) ==
COAP_SOCKET_ERROR)
291 "coap_socket_connect_udp: setsockopt IPV6_V6ONLY: %s\n",
300 if (local_if && local_if->
addr.
sa.sa_family) {
302 if (setsockopt(sock->
fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on),
sizeof(on)) ==
COAP_SOCKET_ERROR)
304 "coap_socket_connect_udp: setsockopt SO_REUSEADDR: %s\n",
307 if (bind(sock->
fd, &local_if->
addr.
sa,
308 local_if->
addr.
sa.sa_family == AF_INET ?
309 (socklen_t)
sizeof(
struct sockaddr_in) :
319 if (!(local_if && local_if->
addr.
sa.sa_family)) {
324 bind_addr.
addr.
sa.sa_family = connect_addr.
addr.
sa.sa_family;
325 if (bind(sock->
fd, &bind_addr.
addr.
sa,
326 bind_addr.
addr.
sa.sa_family == AF_INET ?
327 (socklen_t)
sizeof(
struct sockaddr_in) :
336 "coap_socket_connect_udp: getsockname for multicast socket: %s\n",
370 #ifdef COAP_EPOLL_SUPPORT
373 if (context != NULL) {
375 struct epoll_event event;
378 ret = epoll_ctl(context->epfd, EPOLL_CTL_DEL, sock->
fd, &event);
381 "%s: epoll_ctl DEL failed: %s (%d)\n",
395 #ifdef COAP_EPOLL_SUPPORT
402 struct epoll_event event;
413 event.events = events;
414 event.data.ptr = sock;
416 ret = epoll_ctl(context->epfd, EPOLL_CTL_MOD, sock->
fd, &event);
419 "%s: epoll_ctl MOD failed: %s (%d)\n",
432 r = send(sock->
fd, (
const char *)data, (
int)data_len, 0);
434 r = send(sock->
fd, data, data_len, 0);
438 if (WSAGetLastError() == WSAEWOULDBLOCK) {
439 #elif EAGAIN != EWOULDBLOCK
440 if (errno==EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
442 if (errno==EAGAIN || errno == EINTR) {
445 #ifdef COAP_EPOLL_SUPPORT
454 if (errno == EPIPE || errno == ECONNRESET) {
464 if (r < (ssize_t)data_len) {
466 #ifdef COAP_EPOLL_SUPPORT
485 r = recv(sock->
fd, (
char *)data, (
int)data_len, 0);
487 r = recv(sock->
fd, data, data_len, 0);
496 error = WSAGetLastError();
497 if (error == WSAEWOULDBLOCK) {
498 #elif EAGAIN != EWOULDBLOCK
499 if (errno==EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
501 if (errno==EAGAIN || errno == EINTR) {
506 if (error != WSAECONNRESET)
508 if (errno != ECONNRESET)
514 if (r < (ssize_t)data_len)
521 #if (!defined(WITH_CONTIKI)) != ( defined(HAVE_NETINET_IN_H) || defined(HAVE_WS2TCPIP_H) )
537 #if !defined(WITH_CONTIKI) && !defined(SOL_IP)
539 #define SOL_IP IPPROTO_IP
544 static __declspec(thread) LPFN_WSARECVMSG lpWSARecvMsg = NULL;
546 #define msghdr _WSAMSG
547 #define msg_name name
548 #define msg_namelen namelen
549 #define msg_iov lpBuffers
550 #define msg_iovlen dwBufferCount
551 #define msg_control Control.buf
552 #define msg_controllen Control.len
553 #define iovec _WSABUF
556 #define iov_len_t u_long
558 #define CMSG_DATA WSA_CMSG_DATA
559 #define ipi_spec_dst ipi_addr
560 #pragma warning( disable : 4116 )
562 #define iov_len_t size_t
565 #if defined(_CYGWIN_ENV)
566 #define ipi_spec_dst ipi_addr
572 ssize_t bytes_written = 0;
575 bytes_written = (ssize_t)datalen;
579 bytes_written = send(sock->
fd, (
const char *)data, (
int)datalen, 0);
581 bytes_written = send(sock->
fd, data, datalen, 0);
586 DWORD dwNumberOfBytesSent = 0;
589 #ifdef HAVE_STRUCT_CMSGHDR
598 memcpy (&iov[0].iov_base, &data,
sizeof (iov[0].iov_base));
601 memset(buf, 0,
sizeof (buf));
603 memset(&mhdr, 0,
sizeof(
struct msghdr));
604 memcpy (&mhdr.msg_name, &addr, sizeof (mhdr.msg_name));
615 struct cmsghdr *cmsg;
618 #if defined(IP_PKTINFO)
620 mhdr.msg_control = buf;
621 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
623 cmsg = CMSG_FIRSTHDR(&mhdr);
624 cmsg->cmsg_level =
SOL_IP;
625 cmsg->cmsg_type = IP_PKTINFO;
626 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
628 pktinfo = (
struct in_pktinfo *)CMSG_DATA(cmsg);
634 #elif defined(IP_SENDSRCADDR)
635 mhdr.msg_control = buf;
636 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_addr));
638 cmsg = CMSG_FIRSTHDR(&mhdr);
639 cmsg->cmsg_level = IPPROTO_IP;
640 cmsg->cmsg_type = IP_SENDSRCADDR;
641 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_addr));
643 memcpy(CMSG_DATA(cmsg),
645 sizeof(
struct in_addr));
649 mhdr.msg_control = buf;
650 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in6_pktinfo));
652 cmsg = CMSG_FIRSTHDR(&mhdr);
653 cmsg->cmsg_level = IPPROTO_IPV6;
654 cmsg->cmsg_type = IPV6_PKTINFO;
655 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in6_pktinfo));
668 #if defined(IP_PKTINFO)
669 struct cmsghdr *cmsg;
672 mhdr.msg_control = buf;
673 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
675 cmsg = CMSG_FIRSTHDR(&mhdr);
676 cmsg->cmsg_level =
SOL_IP;
677 cmsg->cmsg_type = IP_PKTINFO;
678 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
680 pktinfo = (
struct in_pktinfo *)CMSG_DATA(cmsg);
686 #elif defined(IP_SENDSRCADDR)
687 struct cmsghdr *cmsg;
688 mhdr.msg_control = buf;
689 mhdr.msg_controllen = CMSG_SPACE(
sizeof(
struct in_addr));
691 cmsg = CMSG_FIRSTHDR(&mhdr);
692 cmsg->cmsg_level = IPPROTO_IP;
693 cmsg->cmsg_type = IP_SENDSRCADDR;
694 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_addr));
696 memcpy(CMSG_DATA(cmsg),
698 sizeof(
struct in_addr));
710 r = WSASendMsg(sock->
fd, &mhdr, 0 , &dwNumberOfBytesSent, NULL , NULL );
712 bytes_written = (ssize_t)dwNumberOfBytesSent;
716 #ifdef HAVE_STRUCT_CMSGHDR
717 bytes_written = sendmsg(sock->
fd, &mhdr, 0);
718 #elif !defined(CONTIKI)
719 bytes_written = sendto(sock->
fd, data, datalen, 0,
724 #if defined(WITH_CONTIKI)
729 uip_udp_packet_sendto((
struct uip_udp_conn *)sock->conn, data, datalen,
731 bytes_written = datalen;
735 if (bytes_written < 0)
738 return bytes_written;
742 #define SIN6(A) ((struct sockaddr_in6 *)(A))
765 #if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
774 if (WSAGetLastError() == WSAECONNRESET) {
776 if (errno == ECONNREFUSED) {
784 }
else if (len > 0) {
785 packet->
length = (size_t)len;
790 DWORD dwNumberOfBytesRecvd = 0;
793 #if !defined(WITH_CONTIKI)
794 #ifdef HAVE_STRUCT_CMSGHDR
797 struct cmsghdr *cmsg;
801 iov[0].iov_base = packet->
payload;
804 memset(&mhdr, 0,
sizeof(
struct msghdr));
812 mhdr.msg_control = buf;
813 mhdr.msg_controllen =
sizeof(buf);
816 cmsg = (
struct cmsghdr *)buf;
817 cmsg->cmsg_len = CMSG_LEN(
sizeof(buf));
818 cmsg->cmsg_level = -1;
819 cmsg->cmsg_type = -1;
823 GUID wsaid = WSAID_WSARECVMSG;
824 DWORD cbBytesReturned = 0;
825 if (WSAIoctl(sock->
fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &wsaid,
sizeof(wsaid), &lpWSARecvMsg,
sizeof(lpWSARecvMsg), &cbBytesReturned, NULL, NULL) != 0) {
830 r = lpWSARecvMsg(sock->
fd, &mhdr, &dwNumberOfBytesRecvd, NULL , NULL );
832 len = (ssize_t)dwNumberOfBytesRecvd;
834 len = recvmsg(sock->
fd, &mhdr, 0);
845 if (WSAGetLastError() == WSAECONNRESET) {
847 if (errno == ECONNREFUSED) {
855 #ifdef HAVE_STRUCT_CMSGHDR
859 packet->
length = (size_t)len;
863 for (cmsg = CMSG_FIRSTHDR(&mhdr); cmsg; cmsg = CMSG_NXTHDR(&mhdr, cmsg)) {
866 if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
871 u.c = CMSG_DATA(cmsg);
872 packet->
ifindex = (int)(u.p->ipi6_ifindex);
874 &u.p->ipi6_addr,
sizeof(
struct in6_addr));
880 #if defined(IP_PKTINFO)
881 if (cmsg->cmsg_level ==
SOL_IP && cmsg->cmsg_type == IP_PKTINFO) {
886 u.c = CMSG_DATA(cmsg);
887 packet->
ifindex = u.p->ipi_ifindex;
893 &u.p->ipi_addr,
sizeof(
struct in_addr));
896 &u.p->ipi_addr,
sizeof(
struct in_addr));
901 #elif defined(IP_RECVDSTADDR)
902 if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) {
905 CMSG_DATA(cmsg),
sizeof(
struct in_addr));
913 if (cmsg->cmsg_level != -1 && cmsg->cmsg_type != -1) {
915 "cmsg_level = %d and cmsg_type = %d not supported - fix\n",
916 cmsg->cmsg_level, cmsg->cmsg_type);
930 packet->
length = (size_t)len;
942 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
943 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN])
948 uip_ipaddr_copy(&(packet)->addr_info.local.addr, &UIP_IP_BUF->destipaddr);
959 ((
char *)uip_appdata)[len] = 0;
961 #ifndef INET6_ADDRSTRLEN
962 #define INET6_ADDRSTRLEN 40
973 memcpy(&packet->
payload, uip_appdata, len);
980 packet->src.size =
sizeof(packet->src.addr);
982 0, &packet->src.addr.sa, &packet->src.size);
991 #if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
997 #if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
1004 #if !defined(WITH_CONTIKI)
1008 #ifndef COAP_EPOLL_SUPPORT
1012 "coap_io_prepare_epoll() requires libcoap compiled for using epoll\n");
1016 unsigned int max_sockets =
sizeof(sockets)/
sizeof(sockets[0]);
1017 unsigned int num_sockets;
1018 unsigned int timeout;
1023 ctx->next_timeout = timeout ? now + timeout : 0;
1024 if (ctx->eptimerfd != -1) {
1025 struct itimerspec new_value;
1028 memset(&new_value, 0,
sizeof(new_value));
1030 if (ctx->next_timeout != 0 && ctx->next_timeout > now) {
1031 coap_tick_t rem_timeout = ctx->next_timeout - now;
1037 #ifdef COAP_DEBUG_WAKEUP_TIMES
1039 new_value.it_value.tv_sec, new_value.it_value.tv_nsec);
1042 ret = timerfd_settime(ctx->eptimerfd, 0, &new_value, NULL);
1045 "%s: timerfd_settime failed: %s (%d)\n",
1046 "coap_io_prepare_epoll",
1061 unsigned int max_sockets,
1062 unsigned int *num_sockets,
1071 #ifdef COAP_EPOLL_SUPPORT
1086 #ifndef WITHOUT_ASYNC
1092 #ifndef COAP_EPOLL_SUPPORT
1094 if (*num_sockets < max_sockets)
1095 sockets[(*num_sockets)++] = &ep->
sock;
1106 s_timeout = (s->
last_rx_tx + session_timeout) - now;
1107 if (timeout == 0 || s_timeout < timeout)
1108 timeout = s_timeout;
1113 if (timeout == 0 || s_timeout < timeout)
1114 timeout = s_timeout;
1116 #ifndef COAP_EPOLL_SUPPORT
1118 if (*num_sockets < max_sockets)
1119 sockets[(*num_sockets)++] = &s->
sock;
1126 if (!COAP_DISABLE_TCP
1145 if (timeout == 0 || s_timeout < timeout)
1146 timeout = s_timeout;
1149 if (!COAP_DISABLE_TCP
1165 if (timeout == 0 || s_timeout < timeout)
1166 timeout = s_timeout;
1172 if (timeout == 0 || s_timeout < timeout)
1173 timeout = s_timeout;
1176 #ifndef COAP_EPOLL_SUPPORT
1178 if (*num_sockets < max_sockets)
1179 sockets[(*num_sockets)++] = &s->
sock;
1191 if (nextpdu && (timeout == 0 || nextpdu->
t - ( now - ctx->
sendqueue_basetime ) < timeout))
1197 if (tls_timeout > 0) {
1202 if (timeout == 0 || tls_timeout - now < timeout)
1203 timeout = tls_timeout - now;
1212 while (tls_timeout > 0 && tls_timeout <= now) {
1226 if (tls_timeout > 0 && (timeout == 0 || tls_timeout - now < timeout))
1227 timeout = tls_timeout - now;
1236 while (tls_timeout > 0 && tls_timeout <= now) {
1249 if (tls_timeout > 0 && (timeout == 0 || tls_timeout - now < timeout))
1250 timeout = tls_timeout - now;
1259 #ifndef RIOT_VERSION
1267 int enfds, fd_set *ereadfds, fd_set *ewritefds,
1268 fd_set *eexceptfds) {
1269 #if COAP_CONSTRAINED_STACK
1270 static coap_mutex_t static_mutex = COAP_MUTEX_INITIALIZER;
1271 # ifndef COAP_EPOLL_SUPPORT
1272 static fd_set readfds, writefds, exceptfds;
1274 unsigned int num_sockets = 0;
1277 # ifndef COAP_EPOLL_SUPPORT
1278 fd_set readfds, writefds, exceptfds;
1280 unsigned int num_sockets = 0;
1285 unsigned int timeout;
1286 #ifndef COAP_EPOLL_SUPPORT
1292 #if COAP_CONSTRAINED_STACK
1293 coap_mutex_lock(&static_mutex);
1298 #ifndef COAP_EPOLL_SUPPORT
1300 (
sizeof(sockets) /
sizeof(sockets[0])),
1301 &num_sockets, before);
1302 if (timeout == 0 || timeout_ms < timeout)
1303 timeout = timeout_ms;
1306 readfds = *ereadfds;
1313 writefds = *ewritefds;
1320 exceptfds = *eexceptfds;
1324 FD_ZERO(&exceptfds);
1326 for (i = 0; i < num_sockets; i++) {
1327 if (sockets[i]->fd + 1 > nfds)
1328 nfds = sockets[i]->
fd + 1;
1330 FD_SET(sockets[i]->fd, &readfds);
1332 FD_SET(sockets[i]->fd, &writefds);
1333 #if !COAP_DISABLE_TCP
1335 FD_SET(sockets[i]->fd, &readfds);
1337 FD_SET(sockets[i]->fd, &writefds);
1338 FD_SET(sockets[i]->fd, &exceptfds);
1348 else if (timeout > 0) {
1349 tv.tv_usec = (timeout % 1000) * 1000;
1350 tv.tv_sec = (long)(timeout / 1000);
1353 result = select((
int)nfds, &readfds, &writefds, &exceptfds, timeout > 0 ? &tv : NULL);
1357 if (WSAGetLastError() != WSAEINVAL) {
1359 if (errno != EINTR) {
1362 #if COAP_CONSTRAINED_STACK
1363 coap_mutex_unlock(&static_mutex);
1370 for (i = 0; i < num_sockets; i++) {
1373 #if !COAP_DISABLE_TCP
1378 if ((sockets[i]->flags &
COAP_SOCKET_WANT_CONNECT) && (FD_ISSET(sockets[i]->fd, &writefds) || FD_ISSET(sockets[i]->fd, &exceptfds)))
1387 *ereadfds = readfds;
1390 *ewritefds = writefds;
1393 *eexceptfds = exceptfds;
1404 if (timeout == 0 || timeout_ms < timeout)
1405 timeout = timeout_ms;
1409 int etimeout = timeout;
1419 else if (etimeout < 0) {
1426 if (errno != EINTR) {
1448 #ifndef WITHOUT_ASYNC
1455 #if COAP_CONSTRAINED_STACK
1456 coap_mutex_unlock(&static_mutex);
1478 unsigned int max_sockets,
1479 unsigned int *num_sockets,
1489 static char szError[256];
1490 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)
1491 strcpy(szError,
"Unknown error");
1500 return strerror(error);
1509 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.
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)
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_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_strerror(void)
const char * coap_socket_format_errno(int error)
void coap_mfree_endpoint(coap_endpoint_t *ep)
coap_endpoint_t * coap_malloc_endpoint(void)
#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
#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_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.
coap_tick_t coap_block_check_lg_srcv_timeouts(coap_session_t *session, coap_tick_t now)
coap_tick_t coap_block_check_lg_crcv_timeouts(coap_session_t *session, coap_tick_t now)
void coap_expire_cache_entries(coap_context_t *ctx)
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_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_MID
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_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
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_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