26#ifdef HAVE_SYS_SELECT_H
27# include <sys/select.h>
29#ifdef HAVE_SYS_SOCKET_H
30# include <sys/socket.h>
32#ifdef HAVE_SYS_IOCTL_H
35#ifdef HAVE_NETINET_IN_H
36# include <netinet/in.h>
44#ifdef COAP_EPOLL_SUPPORT
46#include <sys/timerfd.h>
53#include <sys/select.h>
56#if COAP_SERVER_SUPPORT
72 if (context->eptimerfd != -1) {
77 struct itimerspec new_value;
81 memset(&new_value, 0,
sizeof(new_value));
83 new_value.it_value.tv_nsec = 1;
89 ret = timerfd_settime(context->eptimerfd, 0, &new_value, NULL);
92 "coap_update_io_timer",
95#ifdef COAP_DEBUG_WAKEUP_TIMES
98 new_value.it_value.tv_sec, new_value.it_value.tv_nsec);
116coap_win_error_to_errno(
void) {
117 int w_error = WSAGetLastError();
119 case WSA_NOT_ENOUGH_MEMORY:
122 case WSA_INVALID_PARAMETER:
155 case WSAECONNABORTED:
156 errno = ECONNABORTED;
167 case WSAECONNREFUSED:
168 errno = ECONNREFUSED;
170 case WSAEADDRNOTAVAIL:
171 errno = EADDRNOTAVAIL;
174 coap_log_err(
"WSAGetLastError: %d mapping to errno failed - please fix\n",
182#if !defined(WITH_LWIP) && !defined(__ZEPHYR__)
183#if (!defined(WITH_CONTIKI)) != ( defined(HAVE_NETINET_IN_H) || defined(HAVE_WS2TCPIP_H) )
187#if !defined(__MINGW32__) && !defined(RIOT_VERSION)
220#ifndef COAP_EPOLL_SUPPORT
223 coap_log_emerg(
"coap_io_prepare_epoll() requires libcoap compiled for using epoll\n");
227 unsigned int max_sockets =
sizeof(sockets)/
sizeof(sockets[0]);
228 unsigned int num_sockets;
229 unsigned int timeout;
236 if (ctx->eptimerfd != -1) {
237 struct itimerspec new_value;
240 memset(&new_value, 0,
sizeof(new_value));
249#ifdef COAP_DEBUG_WAKEUP_TIMES
251 new_value.it_value.tv_sec, new_value.it_value.tv_nsec);
254 ret = timerfd_settime(ctx->eptimerfd, 0, &new_value, NULL);
257 "coap_io_prepare_epoll",
272 unsigned int max_sockets,
273 unsigned int *num_sockets,
290 unsigned int max_sockets,
291 unsigned int *num_sockets,
297#if COAP_SERVER_SUPPORT
298 int check_dtls_timeouts = 0;
300#if defined(COAP_EPOLL_SUPPORT) || defined(WITH_LWIP) || defined(RIOT_VERSION)
308#if COAP_SERVER_SUPPORT
312#if COAP_ASYNC_SUPPORT
314 if (coap_check_async(ctx, now, &s_timeout)) {
315 if (s_timeout < timeout)
336 if (tls_timeout > 0) {
341 if (tls_timeout - now < timeout)
342 timeout = tls_timeout - now;
344#if COAP_SERVER_SUPPORT
346 check_dtls_timeouts = 1;
350#if COAP_PROXY_SUPPORT
351 if (coap_proxy_check_timeouts(ctx, now, &s_timeout)) {
352 if (s_timeout < timeout)
356#if COAP_SERVER_SUPPORT
366#if !defined(COAP_EPOLL_SUPPORT) && !defined(WITH_LWIP) && !defined(RIOT_VERSION)
368 if (*num_sockets < max_sockets)
369 sockets[(*num_sockets)++] = &ep->
sock;
385 s_timeout = (s->
last_rx_tx + session_timeout) - now;
386 if (s_timeout < timeout)
395 while (tls_timeout > 0 && tls_timeout <= now) {
408 if (tls_timeout > 0 && tls_timeout - now < timeout)
409 timeout = tls_timeout - now;
414 if (s_timeout < timeout)
421 if (s_timeout < timeout)
425#if !defined(COAP_EPOLL_SUPPORT) && !defined(WITH_LWIP) && !defined(RIOT_VERSION)
428 sockets[(*num_sockets)++] = &s->
sock;
431#if COAP_Q_BLOCK_SUPPORT
437 if (coap_block_check_q_block2_xmit(s, now, &s_timeout)) {
438 if (s_timeout < timeout)
471 if (s_timeout < timeout)
478#if COAP_CLIENT_SUPPORT
502 if (s_timeout < timeout)
513 if (timeout == 0 || s_timeout < timeout)
519 if (s_timeout < timeout)
536 if (s_timeout < timeout)
547 while (tls_timeout > 0 && tls_timeout <= now) {
559 if (tls_timeout > 0 && tls_timeout - now < timeout)
560 timeout = tls_timeout - now;
566 if (s_timeout < timeout)
573 if (s_timeout < timeout)
577#if COAP_Q_BLOCK_SUPPORT
583 if (coap_block_check_q_block1_xmit(s, now, &s_timeout)) {
584 if (s_timeout < timeout)
590#if !defined(COAP_EPOLL_SUPPORT) && !defined(WITH_LWIP) && !defined(RIOT_VERSION)
596 sockets[(*num_sockets)++] = &s->
sock;
614 unsigned int *have_read_fds,
615 unsigned int max_read_fds,
617 unsigned int *have_write_fds,
618 unsigned int max_write_fds,
619 unsigned int *rem_timeout_ms) {
624 have_write_fds, max_write_fds, rem_timeout_ms);
629#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
632 unsigned int max_this_fds) {
633 if (*have_this_fds < max_this_fds) {
634 this_fds[(*have_this_fds)++] = fd;
637 coap_log_warn(
"coap_io_get_fds: Insufficient space for new fd (%u >= %u)\n", *have_this_fds,
649 unsigned int *have_read_fds,
650 unsigned int max_read_fds,
652 unsigned int *have_write_fds,
653 unsigned int max_write_fds,
654 unsigned int *rem_timeout_ms) {
658#ifdef COAP_EPOLL_SUPPORT
660 (void)max_write_fds;;
662 if (!
coap_add_fd(ctx->epfd, read_fds, have_read_fds, max_read_fds))
670 unsigned int timeout_ms;
671#if COAP_SERVER_SUPPORT
696#if COAP_CLIENT_SUPPORT
713 *rem_timeout_ms = timeout_ms;
727 unsigned int *have_read_fds,
728 unsigned int max_read_fds,
730 unsigned int *have_write_fds,
731 unsigned int max_write_fds,
732 unsigned int *rem_timeout_ms) {
765#if COAP_SERVER_SUPPORT
777#if COAP_SERVER_SUPPORT
789#if COAP_CLIENT_SUPPORT
804 return strerror(error);
809 coap_win_error_to_errno();
821#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
const char * coap_socket_format_errno(int error)
static int coap_add_fd(coap_fd_t fd, coap_fd_t this_fds[], unsigned int *have_this_fds, unsigned int max_this_fds)
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.
void coap_update_io_timer(coap_context_t *context, coap_tick_t delay)
Update when to continue with I/O processing, unless packets come in in the meantime.
uint16_t coap_socket_flags_t
#define COAP_INVALID_SOCKET
#define COAP_SOCKET_WANT_ACCEPT
non blocking server socket is waiting for accept
#define COAP_SOCKET_SLAVE
socket is a slave socket - do not close
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
#define COAP_SOCKET_WANT_WRITE
non blocking socket is waiting for writing
coap_endpoint_t * coap_malloc_endpoint(void)
#define COAP_SOCKET_WANT_CONNECT
non blocking client socket is waiting for connect
void coap_mfree_endpoint(coap_endpoint_t *ep)
Library specific build wrapper for coap_internal.h.
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)
#define SESSIONS_ITER_SAFE(e, el, rtmp)
#define SESSIONS_ITER(e, el, rtmp)
#define COAP_DEFAULT_SESSION_TIMEOUT
int coap_io_pending_lkd(coap_context_t *context)
Check to see if there is any i/o pending for the context.
unsigned int coap_io_get_fds_lkd(coap_context_t *ctx, coap_fd_t read_fds[], unsigned int *have_read_fds, unsigned int max_read_fds, coap_fd_t write_fds[], unsigned int *have_write_fds, unsigned int max_write_fds, unsigned int *rem_timeout_ms)
int coap_io_process_lkd(coap_context_t *ctx, uint32_t timeout_ms)
The main I/O processing function.
unsigned int coap_io_prepare_io_lkd(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...
unsigned int coap_io_prepare_epoll_lkd(coap_context_t *ctx, coap_tick_t now)
Any now timed out delayed packet is transmitted, along with any packets associated with requested obs...
COAP_API int coap_io_pending(coap_context_t *context)
Check to see if there is any i/o pending for the context.
COAP_API unsigned int coap_io_get_fds(coap_context_t *ctx, coap_fd_t read_fds[], unsigned int *have_read_fds, unsigned int max_read_fds, coap_fd_t write_fds[], unsigned int *have_write_fds, unsigned int max_write_fds, unsigned int *rem_timeout_ms)
COAP_API 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...
COAP_API void coap_socket_set_flags(coap_socket_t *sock, coap_socket_flags_t flags)
Set the libcoap internal flags for a socket.
COAP_API 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...
COAP_API coap_fd_t coap_socket_get_fd(coap_socket_t *sock)
Get the libcoap internal file descriptor for a socket.
COAP_API coap_socket_flags_t coap_socket_get_flags(coap_socket_t *sock)
Get the libcoap internal flags for a socket.
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)
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.
#define COAP_MAX_DELAY_TICKS
int coap_handle_event_lkd(coap_context_t *context, coap_event_t event, coap_session_t *session)
Invokes the event handler of context for the given event and data.
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.
void coap_ticks(coap_tick_t *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_lock_unlock()
Dummy for no thread-safe code.
#define coap_lock_check_locked()
Dummy for no thread-safe code.
#define coap_lock_lock(failed)
Dummy for no thread-safe code.
#define coap_log_debug(...)
#define coap_log_emerg(...)
const char * coap_session_str(const coap_session_t *session)
Get session description.
#define coap_log_warn(...)
#define coap_log_err(...)
int coap_mid_t
coap_mid_t is used to store the CoAP Message ID of a CoAP PDU.
#define COAP_INVALID_MID
Indicates an invalid message id.
int coap_session_reconnect(coap_session_t *session)
Close the current session (if not already closed) and reconnect to server (client session only).
void coap_session_server_keepalive_failed(coap_session_t *session)
Clear down a session following a keepalive failure.
void coap_session_failed(coap_session_t *session)
Session has failed due to a socket error.
coap_mid_t coap_session_send_ping_lkd(coap_session_t *session)
Send a ping message for the session.
void coap_session_free(coap_session_t *session)
void coap_session_release_lkd(coap_session_t *session)
Decrement reference counter on a session.
coap_session_t * coap_session_reference_lkd(coap_session_t *session)
Increment reference counter on a session.
#define COAP_PROTO_RELIABLE(p)
@ 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_lkd(coap_context_t *context)
Checks all known resources to see if they are dirty and then notifies subscribed observers.
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 reconnect_time
Time to wait before reconnecting a failed client session.
coap_session_t * sessions
client sessions
unsigned int ping_timeout
Minimum inactivity time before sending a ping message.
coap_endpoint_t * endpoint
the endpoints used for listening
uint32_t csm_timeout_ms
Timeout for waiting for a CSM from the remote side.
coap_tick_t next_timeout
When the next timeout is to occur.
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_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
unsigned char * payload
payload
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
unsigned ref_subscriptions
reference count of current subscriptions
coap_socket_t sock
socket object for the session, if any
coap_session_state_t state
current state of relationship with peer
unsigned ref_proxy_subs
reference count of current proxy subscriptions
coap_proto_t proto
protocol used
unsigned ref
reference count from queues
void * tls
security parameters
uint8_t con_active
Active CON request sent.
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
uint8_t session_failed
Set if session failed and can try re-connect.
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