'\" t
.\" Title: coap_io
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1
.\" Date: 11/09/2019
.\" Manual: libcoap Manual
.\" Source: coap_io 4.2.1
.\" Language: English
.\"
.TH "COAP_IO" "3" "11/09/2019" "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