Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
COAP_IO(3)			libcoap	Manual			    COAP_IO(3)

NAME
       coap_io,	coap_io_process, coap_io_process_with_fds,
       coap_context_get_coap_fd, coap_io_prepare_io, coap_io_do_io,
       coap_io_prepare_epoll, coap_io_do_epoll - Work with CoAP	I/O to do the
       packet send and receives

SYNOPSIS
       #include	<coap3/coap.h>

       int coap_io_process(coap_context_t *context, uint32_t timeout_ms);

       int coap_io_process_with_fds(coap_context_t *context, uint32_t
       timeout_ms, int nfds, fd_set *readfds, fd_set *writefds,	fd_set
       *exceptfds);

       int coap_context_get_coap_fd(const coap_context_t *context);

       unsigned	int coap_io_prepare_io(coap_context_t *context,	coap_socket_t
       *sockets[], unsigned int	max_sockets, unsigned int *num_sockets,
       coap_tick_t now);

       void coap_io_do_io(coap_context_t *context, coap_tick_t now);

       unsigned	int coap_io_prepare_epoll(coap_context_t *context, coap_tick_t
       now);

       void coap_io_do_epoll(coap_context_t *context, struct epoll_event
       *events,	size_t nevents);

       For specific (D)TLS library support, link with -lcoap-3-notls,
       -lcoap-3-gnutls,	-lcoap-3-openssl, -lcoap-3-mbedtls or
       -lcoap-3-tinydtls. Otherwise, link with -lcoap-3	to get the default
       (D)TLS library support.

DESCRIPTION
       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.

       The coap_io_process() function will process any outstanding packets to
       send for	the specified context, process any available input packets and
       then wait for processing	any new	input packets, or for when to
       re-transmit a packet, for up to timeout_ms milli-seconds	before
       returning. There	are 2 special case timeout_ms values.

	   #define COAP_IO_WAIT	   0
	   #define COAP_IO_NO_WAIT ((uint32_t)-1)

       If timeout_ms is	set to COAP_IO_WAIT, then coap_io_process() will block
       until the next internal action (e.g. packet retransmit) if any, or
       block until the next packet is received whichever is the	sooner and do
       the necessary processing. If timeout_ms is set to COAP_IO_NO_WAIT, then
       coap_io_process() will return immediately after processing without
       waiting for any new input packets to arrive.

       There are two methods of	how to call coap_io_process().

	1. Have	coap_io_process() called from within a while() loop. Under
	   idle	conditions (no input traffic) coap_io_process()	will then get
	   called every	timeout_ms, but	more frequently	if there is input /
	   retransmission traffic.

	2. Wait	on the file descriptor returned	by coap_context_get_coap_fd()
	   using select() or an	event returned by epoll_wait().	If read	is
	   available on	the file descriptor, call coap_io_process() with
	   timeout_ms set to COAP_IO_NO_WAIT.

	   NOTE: This second method is only available for environments that
	   support epoll (mostly Linux)	with libcoap compiled to use epoll
	   (the	default) as libcoap will then be using epoll internally	to
	   process all the file	descriptors of the different sessions.

       See EXAMPLES below.

       The coap_io_process() function is the primary function applications
       should use. There are internal functions	that coap_io_process() calls
       which are available to use if absolutely	necessary. These internal
       functions and how to use	them is	different depending on whether libcoap
       has been	compiled to use	epoll (Linux systems only) or not.

       For epoll libcoap, coap_io_process() in simple terms calls
       coap_io_prepare_epoll(),	does an	epoll_wait() and then calls
       coap_io_do_epoll() if needed to make sure that all event	based i/o has
       been completed.

       For non-epoll libcoap, coap_io_process()	in simple terms	calls
       coap_io_prepare_io() to set up sockets[], sets up all of	the select()
       parameters based	on the COAP_SOCKET_WANT* values	in the sockets[], does
       a select(), updates the sockets[] with COAP_SOCKET_CAN_*	as appropriate
       and then	calls coap_io_do_io() to make sure that	all current i/o	has
       been completed.

       The coap_io_prepare_epoll() function for	the specified context will
       iterate through the endpoints and sessions to transmit any triggered
       observer	responses as well as handling any timed	out packet
       re-transmissions. Returned, based on now, is the	number of milli-secs
       needed to delay until the next time that	coap_io_prepare_epoll()	needs
       to get called. After this call an epoll_wait() should done.

       The coap_io_do_epoll() function for the specified context will iterate
       through the nevents of events returned by epoll_wait() and execute the
       appropriate low level i/o function to send / receive / process the
       packets.	Where appropriate, structure information (endpoints, sessions
       etc.) is	updated	with the value of now in the lower level functions.

       The coap_io_prepare_io()	function for the specified context will
       iterate through the endpoints and sessions to add all of	sockets
       waiting for network traffic (COAP_SOCKET_WANT_* is set) found to
       sockets (limited	by max_sockets)	and updates num_sockets	with the
       number of sockets found.	Furthermore, any triggered observer responses
       are transmitted as well as handling any timed out packet
       re-transmissions. Returned, based on now, is the	number of milli-secs
       needed to delay until the next time that	coap_io_prepare_io() needs to
       get called. After this call a select() should done on all the file
       descriptors (COAP_WANT_READ for readfds etc.), and any that are
       returned	active should set the appropriate COAP_SOCKET_CAN_* in the
       sockets.

       The coap_io_do_io() function for	the specified context will iterate
       through the endpoints and sessions to find all of sockets that have
       COAP_SOCKET_CAN_* set and then execute the appropriate low level	i/o
       function	to send	/ receive / process the	packets. Where appropriate,
       structure information (endpoints, sessions etc.)	is updated with	the
       value of	now in the lower level functions.

       The coap_io_process_with_fds() function is the same as
       coap_process_io() but supports additional select() style	parameters
       nfds, readfds, writefds and exceptfds. This provides the	ability	to add
       in additional non libcoap FDs to	test for in the	internal select() call
       which can then tested after the return from coap_io_process_with_fds().
       readfds,	writefds and exceptfds can either point	to a defined and
       pre-filled fd_set structure or NULL if not required. nfds needs to be
       set to the maximum FD to	test for in readfds, writefds or exceptfds if
       any of them are set plus	1. If none of them are set, then nfds should
       be set to 0.

	   Note
	   The additional parameters for coap_io_process_with_fds() are	only
	   used	if there is no epoll support in	libcoap. If there is epoll
	   support, then coap_context_get_coap_fd() should be used and this
	   returned FD along with other	non libcoap FDs	can separately be
	   monitored using method 2 above.

       The coap_context_get_coap_fd() function obtains from the	specified
       context 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.

RETURN VALUES
       coap_io_process() and coap_io_process_with_fds()	returns	the time, in
       milli-seconds, that was spent in	the function. If -1 is returned, there
       was an unexpected error.

       coap_context_get_coap_fd() returns a non-negative number	as the file
       descriptor to monitor, or -1 if epoll is	not configured in libcoap.

       coap_io_prepare_io() and	coap_io_prepare_epoll()	returns	the number of
       milli-seconds that need to be waited before the function	should next be
       called.

EXAMPLES
       Method One - use	coap_io_process()

	   #include <coap3/coap.h>

	   int main(int	argc, char *argv[]){

	     coap_context_t *ctx = NULL;
	     unsigned wait_ms;
	     /*	Remove (void) definition if variable is	used */
	     (void)argc;
	     (void)argv;

	     /*	Create the libcoap context */
	     ctx = coap_new_context(NULL);
	     if	(!ctx) {
	       exit(1);
	     }
	     /*	See coap_block(3) */
	     coap_context_set_block_mode(ctx,
					 COAP_BLOCK_USE_LIBCOAP	| COAP_BLOCK_SINGLE_BODY);

	     /*	Other Set up Code */

	     wait_ms = COAP_RESOURCE_CHECK_TIME	* 1000;

	     while (1) {
	       int result = coap_io_process(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);

	   }

       Method One - coap_io_process_with_fds

	   #include <coap3/coap.h>

	   int main(int	argc, char *argv[]){

	     coap_context_t *ctx = NULL;
	     unsigned wait_ms;
	     fd_set readfds;
	     int nfds =	0;
	     /*	Remove (void) definition if variable is	used */
	     (void)argc;
	     (void)argv;

	     /*	Create the libcoap context */
	     ctx = coap_new_context(NULL);
	     if	(!ctx) {
	       exit(1);
	     }
	     /*	See coap_block(3) */
	     coap_context_set_block_mode(ctx,
					 COAP_BLOCK_USE_LIBCOAP	| COAP_BLOCK_SINGLE_BODY);

	     FD_ZERO(&readfds);
	     /*	Set up readfds and nfds	to handle other	non libcoap FDs	*/

	     /*	Other Set up Code */

	     wait_ms = COAP_RESOURCE_CHECK_TIME	* 1000;

	     while (1) {
	       int result = coap_io_process_with_fds(ctx, wait_ms, nfds, &readfds, NULL, NULL);
	       if (result < 0) {
		 /* There is an	internal issue */
		 break;
	       }
	       /* Check	if set non libcoap FDs and process accordingly */

	       /* Do any other housekeeping */
	     }
	     coap_free_context(ctx);

	     /*	Do any other cleanup */

	     exit(0);

	   }

       Method Two - select() based on monitorable file descriptor

	   #include <coap3/coap.h>

	   #include <errno.h>

	   int main(int	argc, char *argv[]){

	     coap_context_t *ctx = NULL;
	     int coap_fd;
	     fd_set m_readfds;
	     int nfds;
	     /*	Remove (void) definition if variable is	used */
	     (void)argc;
	     (void)argv;

	     /*	Create the libcoap context */
	     ctx = coap_new_context(NULL);
	     if	(!ctx) {
	       exit(1);
	     }
	     /*	See coap_block(3) */
	     coap_context_set_block_mode(ctx,
					 COAP_BLOCK_USE_LIBCOAP	| COAP_BLOCK_SINGLE_BODY);

	     coap_fd = coap_context_get_coap_fd(ctx);
	     if	(coap_fd == -1)	{
	       /* epoll	is not supported */
	       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)\n", coap_socket_strerror(), errno);
		   break;
		 }
	       }
	       if (result > 0) {
		 if (FD_ISSET(coap_fd, &readfds)) {
		   result = coap_io_process(ctx, COAP_IO_NO_WAIT);
		   if (result <	0) {
		     /*	There is an internal issue */
		     break;
		   }
		 }
	       }
	       /* Do any other housekeeping */
	     }
	     coap_free_context(ctx);

	     /*	Do any other cleanup */

	     exit(0);

	   }

       Method Two - epoll_wait() based on monitorable file descriptor

	   #include <coap3/coap.h>

	   #include <sys/epoll.h>

	   #include <errno.h>

	   #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;
	     /*	Remove (void) definition if variable is	used */
	     (void)argc;
	     (void)argv;

	     /*	Create the libcoap context */
	     ctx = coap_new_context(NULL);
	     if	(!ctx) {
	       exit(1);
	     }
	     /*	See coap_block(3) */
	     coap_context_set_block_mode(ctx,
					 COAP_BLOCK_USE_LIBCOAP	| COAP_BLOCK_SINGLE_BODY);

	     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)\n",	coap_socket_strerror(),	errno);
		   break;
		 }
	       }
	       for (i =	0; i < nevents;	i++) {
		 if (events[i].data.fd == coap_fd) {
		   result = coap_io_process(ctx, COAP_IO_NO_WAIT);
		   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)\n", coap_socket_strerror(), errno);
	     }
	     coap_free_context(ctx);

	     /*	Do any other cleanup */

	     exit(0);

	   }

SEE ALSO
       coap_block(3), coap_context(3)

FURTHER	INFORMATION
       See "RFC7252: The Constrained Application Protocol (CoAP)" for further
       information.

BUGS
       Please report bugs on the mailing list for libcoap:
       libcoap-developers@lists.sourceforge.net	or raise an issue on GitHub at
       https://github.com/obgm/libcoap/issues

AUTHORS
       The libcoap project <libcoap-developers@lists.sourceforge.net>

coap_io	4.3.0			  11/06/2021			    COAP_IO(3)

NAME | SYNOPSIS | DESCRIPTION | RETURN VALUES | EXAMPLES | SEE ALSO | FURTHER INFORMATION | BUGS | AUTHORS

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=coap_io&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help