'\" t .\" Title: coap_io .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 05/14/2022 .\" Manual: libcoap Manual .\" Source: coap_io 4.2.1 .\" Language: English .\" .TH "COAP_IO" "3" "05/14/2022" "coap_io 4\&.2\&.1" "libcoap Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" coap_io, coap_run_once, coap_context_get_coap_fd \- Work with CoAP I/O to do the packet send and receives .SH "SYNOPSIS" .sp \fB#include \fR .sp \fBint coap_run_once(coap_context_t *\fR\fB\fIcontext\fR\fR\fB, unsigned int \fR\fB\fItimeout_ms\fR\fR\fB)\fR; .sp \fBint coap_context_get_coap_fd(coap_context_t *\fR\fB\fIcontext\fR\fR\fB)\fR; .sp Link with \fB\-lcoap\-2\fR, \fB\-lcoap\-2\-gnutls\fR, \fB\-lcoap\-2\-openssl\fR or \fB\-lcoap\-2\-tinydtls\fR depending on your (D)TLS library type\&. .SH "DESCRIPTION" .sp After setting up all the contexts, resources, endpoints sessions etc\&., the underlying CoAP and (D)TLS need to send (and possible re\-send) created packets as well as receive packets for processing\&. .sp The \fBcoap_run_once\fR() function will process any outstanding packets to send for the specified \fIcontext\fR and wait for processing any input packets for up to \fItimeout_ms\fR milli\-seconds before returning\&. Once any outstanding input packets have been processed, the function will return\&. There are 2 special case \fItimeout_ms\fR values\&. .sp .if n \{\ .RS 4 .\} .nf #define COAP_RUN_BLOCK 0 #define COAP_RUN_NONBLOCK 1 .fi .if n \{\ .RE .\} .sp If \fItimeout_ms\fR is set to COAP_RUN_BLOCK, then \fBcoap_run_once\fR() will wait indefinitely for the first new input packet to come in\&. If \fItimeout_ms\fR is set to COAP_RUN_NONBLOCK, then there is no wait if there are no more input packets\&. .sp There are two methods of how to call \fBcoap_run_once\fR()\&. .sp .RS 4 .ie n \{\ \h'-04' 1.\h'+01'\c .\} .el \{\ .sp -1 .IP " 1." 4.2 .\} Have \fBcoap_run_once\fR() called from within a while() loop\&. Under idle conditions (no input traffic) \fBcoap_run_once\fR() will then get called every \fItimeout_ms\fR, but more frequently if there is input traffic\&. .RE .sp .RS 4 .ie n \{\ \h'-04' 2.\h'+01'\c .\} .el \{\ .sp -1 .IP " 2." 4.2 .\} Wait on the file descriptor returned by \fBcoap_context_get_coap_fd\fR() using select() or an event returned by epoll_wait()\&. If \fIread\fR is available on the file descriptor, call \fBcoap_run_once\fR() with \fItimeout_ms\fR set to COAP_RUN_NONBLOCK\&. See EXAMPLES below\&. .RE .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBNote\fR .ps -1 .br .sp This method is only available for environments that support epoll (mostly Linux) as libcoap will then be using epoll internally to process all the file descriptors of the different sessions\&. .sp .5v .RE .sp The \fBcoap_context_get_coap_fd\fR() function obtains from the specified \fIcontext\fR a single file descriptor that can be monitored by a select() or as an event returned from a epoll_wait() call\&. This file descriptor will get updated with information (read, write etc\&. available) whenever any of the internal to libcoap file descriptors (sockets) change state\&. .SH "RETURN VALUES" .sp \fBcoap_run_once\fR() returns the time, in milli\-seconds, that was spent in the function\&. If \-1 is returned, there was an unexpected error\&. .sp \fBcoap_context_get_coap_fd\fR() returns a non\-negative number as the file descriptor to monitor, or \-1 if epoll is not supported by the host environment\&. .SH "EXAMPLES" .sp \fBMethod One\fR .sp .if n \{\ .RS 4 .\} .nf #include int main(int argc, char *argv[]){ coap_context_t *ctx = NULL; unsigned wait_ms; /* Create the libcoap context */ ctx = coap_new_context(NULL); if (!ctx) { exit(1); } /* Other Set up Code */ wait_ms = COAP_RESOURCE_CHECK_TIME * 1000; while (1) { int result = coap_run_once(ctx, wait_ms); if (result < 0) { /* There is an internal issue */ break; } /* Do any other housekeeping */ } coap_free_context(ctx); /* Do any other cleanup */ exit(0); } .fi .if n \{\ .RE .\} .sp \fBMethod Two \- select\fR .sp .if n \{\ .RS 4 .\} .nf #include #include int main(int argc, char *argv[]){ coap_context_t *ctx = NULL; int coap_fd; fd_set m_readfds; int nfds; /* Create the libcoap context */ ctx = coap_new_context(NULL); if (!ctx) { exit(1); } coap_fd = coap_context_get_coap_fd(ctx); if (coap_fd == \-1) { exit(1); } FD_ZERO(&m_readfds); FD_SET(coap_fd, &m_readfds); nfds = coap_fd + 1; /* Other Set up Code */ while (1) { fd_set readfds = m_readfds; int result; /* Wait until any i/o takes place */ result = select (nfds, &readfds, NULL, NULL, NULL); if (result == \-1) { if (errno != EAGAIN) { coap_log(LOG_DEBUG, "select: %s (%d)\en", coap_socket_strerror(), errno); break; } } if (result > 0) { if (FD_ISSET(coap_fd, &readfds)) { result = coap_run_once(ctx, COAP_RUN_NONBLOCK); if (result < 0) { /* There is an internal issue */ break; } } } /* Do any other housekeeping */ } coap_free_context(ctx); /* Do any other cleanup */ exit(0); } .fi .if n \{\ .RE .\} .sp \fBMethod Two \- epoll\fR .sp .if n \{\ .RS 4 .\} .nf #include #include #include #define MAX_EVENTS 10 int main(int argc, char *argv[]){ coap_context_t *ctx = NULL; int coap_fd; int epoll_fd; struct epoll_event ev; struct epoll_event events[MAX_EVENTS]; int nevents; int i; /* Create the libcoap context */ ctx = coap_new_context(NULL); if (!ctx) { exit(1); } coap_fd = coap_context_get_coap_fd(ctx); if (coap_fd == \-1) { exit(1); } epoll_fd = epoll_create1(0); if (epoll_fd == \-1) { exit(2); } ev\&.events = EPOLLIN; ev\&.data\&.fd = coap_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, coap_fd, &ev) == \-1) { exit(3); } /* Other Set up Code */ while (1) { int result; /* Wait until any i/o takes place */ nevents = epoll_wait(epoll_fd, events, MAX_EVENTS, \-1); if (nevents == \-1) { if (errno != EAGAIN) { coap_log(LOG_DEBUG, "epoll_wait: %s (%d)\en", coap_socket_strerror(), errno); break; } } for (i = 0; i < nevents; i++) { if (events[i]\&.data\&.fd == coap_fd) { result = coap_run_once(ctx, COAP_RUN_NONBLOCK); if (result < 0) { /* There is an internal issue */ break; } } else { /* Process other events */ } } /* Do any other housekeeping */ } if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, coap_fd, &ev) == \-1) { coap_log(LOG_DEBUG, "epoll_ctl: %s (%d)\en", coap_socket_strerror(), errno); } coap_free_context(ctx); /* Do any other cleanup */ exit(0); } .fi .if n \{\ .RE .\} .SH "SEE ALSO" .sp \fBcoap_context\fR(3) .SH "FURTHER INFORMATION" .sp See "RFC7252: The Constrained Application Protocol (CoAP)" for further information\&. .SH "BUGS" .sp Please report bugs on the mailing list for libcoap: libcoap\-developers@lists\&.sourceforge\&.net .SH "AUTHORS" .sp The libcoap project