1c87c5fbaSopenharmony_ci// -*- mode:doc; -*- 2c87c5fbaSopenharmony_ci// vim: set syntax=asciidoc tw=0 3c87c5fbaSopenharmony_ci 4c87c5fbaSopenharmony_cicoap_io(3) 5c87c5fbaSopenharmony_ci========== 6c87c5fbaSopenharmony_ci:doctype: manpage 7c87c5fbaSopenharmony_ci:man source: coap_io 8c87c5fbaSopenharmony_ci:man version: @PACKAGE_VERSION@ 9c87c5fbaSopenharmony_ci:man manual: libcoap Manual 10c87c5fbaSopenharmony_ci 11c87c5fbaSopenharmony_ciNAME 12c87c5fbaSopenharmony_ci---- 13c87c5fbaSopenharmony_cicoap_io, 14c87c5fbaSopenharmony_cicoap_io_process, 15c87c5fbaSopenharmony_cicoap_io_process_with_fds, 16c87c5fbaSopenharmony_cicoap_context_get_coap_fd, 17c87c5fbaSopenharmony_cicoap_io_prepare_io, 18c87c5fbaSopenharmony_cicoap_io_do_io, 19c87c5fbaSopenharmony_cicoap_io_prepare_epoll, 20c87c5fbaSopenharmony_cicoap_io_do_epoll, 21c87c5fbaSopenharmony_cicoap_io_pending, 22c87c5fbaSopenharmony_cicoap_can_exit 23c87c5fbaSopenharmony_ci- Work with CoAP I/O to do the packet send and receives 24c87c5fbaSopenharmony_ci 25c87c5fbaSopenharmony_ciSYNOPSIS 26c87c5fbaSopenharmony_ci-------- 27c87c5fbaSopenharmony_ci*#include <coap@LIBCOAP_API_VERSION@/coap.h>* 28c87c5fbaSopenharmony_ci 29c87c5fbaSopenharmony_ci*int coap_io_process(coap_context_t *_context_, uint32_t _timeout_ms_)*; 30c87c5fbaSopenharmony_ci 31c87c5fbaSopenharmony_ci*int coap_io_process_with_fds(coap_context_t *_context_, 32c87c5fbaSopenharmony_ciuint32_t _timeout_ms_, int _nfds_, fd_set *_readfds_, fd_set *_writefds_, 33c87c5fbaSopenharmony_cifd_set *_exceptfds_)*; 34c87c5fbaSopenharmony_ci 35c87c5fbaSopenharmony_ci*int coap_context_get_coap_fd(const coap_context_t *_context_)*; 36c87c5fbaSopenharmony_ci 37c87c5fbaSopenharmony_ci*unsigned int coap_io_prepare_io(coap_context_t *_context_, 38c87c5fbaSopenharmony_cicoap_socket_t *_sockets_[], unsigned int _max_sockets_, 39c87c5fbaSopenharmony_ciunsigned int *_num_sockets_, coap_tick_t _now_)*; 40c87c5fbaSopenharmony_ci 41c87c5fbaSopenharmony_ci*void coap_io_do_io(coap_context_t *_context_, coap_tick_t _now_)*; 42c87c5fbaSopenharmony_ci 43c87c5fbaSopenharmony_ci*unsigned int coap_io_prepare_epoll(coap_context_t *_context_, 44c87c5fbaSopenharmony_cicoap_tick_t _now_)*; 45c87c5fbaSopenharmony_ci 46c87c5fbaSopenharmony_ci*void coap_io_do_epoll(coap_context_t *_context_, struct epoll_event *_events_, 47c87c5fbaSopenharmony_cisize_t _nevents_)*; 48c87c5fbaSopenharmony_ci 49c87c5fbaSopenharmony_ci*int coap_io_pending(coap_context_t *_context_)*; 50c87c5fbaSopenharmony_ci 51c87c5fbaSopenharmony_ci*int coap_can_exit(coap_context_t *_context_)*; 52c87c5fbaSopenharmony_ci 53c87c5fbaSopenharmony_ciFor specific (D)TLS library support, link with 54c87c5fbaSopenharmony_ci*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*, 55c87c5fbaSopenharmony_ci*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls* 56c87c5fbaSopenharmony_cior *-lcoap-@LIBCOAP_API_VERSION@-tinydtls*. Otherwise, link with 57c87c5fbaSopenharmony_ci*-lcoap-@LIBCOAP_API_VERSION@* to get the default (D)TLS library support. 58c87c5fbaSopenharmony_ci 59c87c5fbaSopenharmony_ciDESCRIPTION 60c87c5fbaSopenharmony_ci----------- 61c87c5fbaSopenharmony_ciAfter setting up all the contexts, resources, endpoints sessions etc., the 62c87c5fbaSopenharmony_ciunderlying CoAP and (D)TLS need to send (and possible re-send) created packets 63c87c5fbaSopenharmony_cias well as receive packets for processing. 64c87c5fbaSopenharmony_ci 65c87c5fbaSopenharmony_ciThe *coap_io_process*() function is the primary function applications should 66c87c5fbaSopenharmony_ciuse. There are internal functions that *coap_io_process*() calls which are 67c87c5fbaSopenharmony_ciavailable to use if absolutely necessary. These internal functions and how to 68c87c5fbaSopenharmony_ciuse them is different depending on whether libcoap has been compiled to use 69c87c5fbaSopenharmony_ci*epoll* (Linux systems only) or not. 70c87c5fbaSopenharmony_ci 71c87c5fbaSopenharmony_ciFor *epoll* libcoap, *coap_io_process*() in simple terms calls 72c87c5fbaSopenharmony_ci*coap_io_prepare_epoll*(), does an *epoll_wait*() and then calls 73c87c5fbaSopenharmony_ci*coap_io_do_epoll*() if needed to make sure that all event based i/o has been 74c87c5fbaSopenharmony_cicompleted. 75c87c5fbaSopenharmony_ci 76c87c5fbaSopenharmony_ciFor *non-epoll* libcoap, *coap_io_process*() in simple terms calls 77c87c5fbaSopenharmony_ci*coap_io_prepare_io*() to set up sockets[], sets up all of the *select*() 78c87c5fbaSopenharmony_ciparameters based on the COAP_SOCKET_WANT* values in the sockets[], does a 79c87c5fbaSopenharmony_ci*select*(), updates the sockets[] with COAP_SOCKET_CAN_* as appropriate and 80c87c5fbaSopenharmony_cithen calls *coap_io_do_io*() to make sure that all current i/o has been 81c87c5fbaSopenharmony_cicompleted. 82c87c5fbaSopenharmony_ci 83c87c5fbaSopenharmony_ciFUNCTIONS 84c87c5fbaSopenharmony_ci--------- 85c87c5fbaSopenharmony_ci 86c87c5fbaSopenharmony_ci*Function: coap_io_process()* 87c87c5fbaSopenharmony_ci 88c87c5fbaSopenharmony_ciThe *coap_io_process*() function will process any outstanding packets to send 89c87c5fbaSopenharmony_cifor the specified _context_, process any available input packets and then wait 90c87c5fbaSopenharmony_cifor processing any new input packets, or for when to re-transmit a packet, for 91c87c5fbaSopenharmony_ciup to _timeout_ms_ milli-seconds before returning. There are 2 special case 92c87c5fbaSopenharmony_ci_timeout_ms_ values. 93c87c5fbaSopenharmony_ci[source, c] 94c87c5fbaSopenharmony_ci---- 95c87c5fbaSopenharmony_ci#define COAP_IO_WAIT 0 96c87c5fbaSopenharmony_ci#define COAP_IO_NO_WAIT ((uint32_t)-1) 97c87c5fbaSopenharmony_ci---- 98c87c5fbaSopenharmony_ciIf _timeout_ms_ is set to COAP_IO_WAIT, then *coap_io_process*() will block 99c87c5fbaSopenharmony_ciuntil the next internal action (e.g. packet retransmit) if any, or block until 100c87c5fbaSopenharmony_cithe next packet is received whichever is the sooner and do the necessary 101c87c5fbaSopenharmony_ciprocessing. If _timeout_ms_ is set to COAP_IO_NO_WAIT, then *coap_io_process*() 102c87c5fbaSopenharmony_ciwill return immediately after processing without waiting for any new input 103c87c5fbaSopenharmony_cipackets to arrive. 104c87c5fbaSopenharmony_ci 105c87c5fbaSopenharmony_ci*NOTE:* *coap_io_process*() should not be called from within a callback 106c87c5fbaSopenharmony_cihandler as defined using the coap_register_*_handler() as *coap_io_process*() 107c87c5fbaSopenharmony_ciwill likely recursively call the same handler. 108c87c5fbaSopenharmony_ci 109c87c5fbaSopenharmony_ciThere are two methods of how to call *coap_io_process*(). 110c87c5fbaSopenharmony_ci 111c87c5fbaSopenharmony_ci1. Have *coap_io_process*() called from within a while() loop. Under idle 112c87c5fbaSopenharmony_ciconditions (no input traffic) *coap_io_process*() will then get called every 113c87c5fbaSopenharmony_ci_timeout_ms_, but more frequently if there is input / retransmission traffic. 114c87c5fbaSopenharmony_ci 115c87c5fbaSopenharmony_ci2. Wait on the file descriptor returned by *coap_context_get_coap_fd*() 116c87c5fbaSopenharmony_ciusing *select*(), *poll*() or an event returned by epoll_wait(). If 'read' is 117c87c5fbaSopenharmony_ciavailable on the CoAP file descriptor, call *coap_io_process*() with 118c87c5fbaSopenharmony_ci_timeout_ms_ set to COAP_IO_NO_WAIT. + 119c87c5fbaSopenharmony_ci*NOTE*: This second method is only available for environments that support epoll 120c87c5fbaSopenharmony_ci(mostly Linux) with libcoap compiled to use *epoll* (the default) as libcoap 121c87c5fbaSopenharmony_ciwill then be using *epoll* internally to process all the file descriptors of 122c87c5fbaSopenharmony_cithe different sessions. 123c87c5fbaSopenharmony_ci 124c87c5fbaSopenharmony_ciSee EXAMPLES below. 125c87c5fbaSopenharmony_ci 126c87c5fbaSopenharmony_ci*Function: coap_io_prepare_epoll()* 127c87c5fbaSopenharmony_ci 128c87c5fbaSopenharmony_ciThe *coap_io_prepare_epoll*() function for the specified _context_ will 129c87c5fbaSopenharmony_ciiterate through the endpoints and sessions to transmit any triggered observer 130c87c5fbaSopenharmony_ciresponses as well as handling any timed out packet re-transmissions. Returned, 131c87c5fbaSopenharmony_cibased on _now_, is the number of milli-secs needed to delay until the next 132c87c5fbaSopenharmony_citime that *coap_io_prepare_epoll*() needs to get called. After this call an 133c87c5fbaSopenharmony_ci*epoll_wait*() should done. 134c87c5fbaSopenharmony_ci 135c87c5fbaSopenharmony_ci*Function: coap_io_do_epoll()* 136c87c5fbaSopenharmony_ci 137c87c5fbaSopenharmony_ciThe *coap_io_do_epoll*() function for the specified _context_ will 138c87c5fbaSopenharmony_ciiterate through the _nevents_ of _events_ returned by *epoll_wait*() and 139c87c5fbaSopenharmony_ciexecute the appropriate low level i/o function to send / receive / process the 140c87c5fbaSopenharmony_cipackets. Where appropriate, structure information (endpoints, sessions etc.) 141c87c5fbaSopenharmony_ciis updated with the value of _now_ in the lower level functions. 142c87c5fbaSopenharmony_ci 143c87c5fbaSopenharmony_ci*Function: coap_io_prepare_io()* 144c87c5fbaSopenharmony_ci 145c87c5fbaSopenharmony_ciThe *coap_io_prepare_io*() function for the specified _context_ will iterate 146c87c5fbaSopenharmony_cithrough the endpoints and sessions to add all of sockets waiting for network 147c87c5fbaSopenharmony_citraffic (COAP_SOCKET_WANT_* is set) found to _sockets_ (limited by 148c87c5fbaSopenharmony_ci_max_sockets_) and updates _num_sockets_ with the number of sockets found. 149c87c5fbaSopenharmony_ciFurthermore, any triggered observer responses are transmitted 150c87c5fbaSopenharmony_cias well as handling any timed out packet re-transmissions. Returned, based on 151c87c5fbaSopenharmony_ci_now_, is the number of milli-secs needed to delay until the next time that 152c87c5fbaSopenharmony_ci*coap_io_prepare_io*() needs to get called. After this call a *select*() should 153c87c5fbaSopenharmony_cidone on all the file descriptors (COAP_WANT_READ for readfds etc.), and any 154c87c5fbaSopenharmony_cithat are returned active should set the appropriate COAP_SOCKET_CAN_* in the 155c87c5fbaSopenharmony_ci_sockets_. 156c87c5fbaSopenharmony_ci 157c87c5fbaSopenharmony_ci*Function: coap_io_do_io()* 158c87c5fbaSopenharmony_ci 159c87c5fbaSopenharmony_ciThe *coap_io_do_io*() function for the specified _context_ will 160c87c5fbaSopenharmony_ciiterate through the endpoints and sessions to find all of sockets that have 161c87c5fbaSopenharmony_ciCOAP_SOCKET_CAN_* set and then execute the appropriate low level i/o function 162c87c5fbaSopenharmony_cito send / receive / process the packets. Where appropriate, structure 163c87c5fbaSopenharmony_ciinformation (endpoints, sessions etc.) is updated with the value of _now_ in 164c87c5fbaSopenharmony_cithe lower level functions. 165c87c5fbaSopenharmony_ci 166c87c5fbaSopenharmony_ci*Function: coap_io_process_with_fds()* 167c87c5fbaSopenharmony_ci 168c87c5fbaSopenharmony_ciThe *coap_io_process_with_fds*() function is the same as *coap_process_io*() 169c87c5fbaSopenharmony_cibut supports additional select() style parameters _nfds_, _readfds_, 170c87c5fbaSopenharmony_ci_writefds_ and _exceptfds_. This provides the ability to add in additional 171c87c5fbaSopenharmony_cinon libcoap FDs to test for in the internal select() call which can then 172c87c5fbaSopenharmony_citested after the return from coap_io_process_with_fds(). _readfds_, 173c87c5fbaSopenharmony_ci_writefds_ and _exceptfds_ can either point to a defined and pre-filled fd_set 174c87c5fbaSopenharmony_cistructure or NULL if not required. _nfds_ needs to be set to the maximum FD to 175c87c5fbaSopenharmony_citest for in _readfds_, _writefds_ or _exceptfds_ if any of them are set plus 1. 176c87c5fbaSopenharmony_ciIf none of them are set, then _nfds_ should be set to 0. 177c87c5fbaSopenharmony_ci 178c87c5fbaSopenharmony_ci*NOTE:* The additional parameters for *coap_io_process_with_fds*() are only used 179c87c5fbaSopenharmony_ciif there is no epoll support in libcoap. If there is epoll support, then 180c87c5fbaSopenharmony_ci*coap_context_get_coap_fd*() should be used and this returned FD along with 181c87c5fbaSopenharmony_ciother non libcoap FDs can separately be monitored using method 2 above. 182c87c5fbaSopenharmony_ci 183c87c5fbaSopenharmony_ci*Function: coap_context_get_coap_fd()* 184c87c5fbaSopenharmony_ci 185c87c5fbaSopenharmony_ciThe *coap_context_get_coap_fd*() function obtains from the specified 186c87c5fbaSopenharmony_ci_context_ a single file descriptor that can be monitored by a *select*() or 187c87c5fbaSopenharmony_cias an event returned from a *epoll_wait*() call. This file descriptor will get 188c87c5fbaSopenharmony_ciupdated with information (read, write etc. available) whenever any of the 189c87c5fbaSopenharmony_ciinternal to libcoap file descriptors (sockets) change state. 190c87c5fbaSopenharmony_ci 191c87c5fbaSopenharmony_ci*Function: coap_io_pending()* 192c87c5fbaSopenharmony_ci 193c87c5fbaSopenharmony_ciThe *coap_io_pending*() function checks to see if there are any outstanding 194c87c5fbaSopenharmony_cii/o requests / responses associated with _context_ as well as if Observe has 195c87c5fbaSopenharmony_cibeen set up (client only) and large transfers are in process. 196c87c5fbaSopenharmony_ci 197c87c5fbaSopenharmony_ci*Function: coap_can_exit()* 198c87c5fbaSopenharmony_ci 199c87c5fbaSopenharmony_ciThe *coap_can_exit*() function checks to see if there are any outstanding 200c87c5fbaSopenharmony_ciPDUs to transmit associated with _context_ and returns 1 if there is nothing 201c87c5fbaSopenharmony_cioutstanding else 0. This function does not check that all requests transmitted 202c87c5fbaSopenharmony_cihave been responded to. 203c87c5fbaSopenharmony_ci 204c87c5fbaSopenharmony_ciRETURN VALUES 205c87c5fbaSopenharmony_ci------------- 206c87c5fbaSopenharmony_ci*coap_io_process*() and *coap_io_process_with_fds*() return the time, in 207c87c5fbaSopenharmony_cimilli-seconds, that was spent in the function. If -1 is returned, there was 208c87c5fbaSopenharmony_cian unexpected error. 209c87c5fbaSopenharmony_ci 210c87c5fbaSopenharmony_ci*coap_context_get_coap_fd*() returns a non-negative number as the file 211c87c5fbaSopenharmony_cidescriptor to monitor, or -1 if epoll is not configured in libcoap. 212c87c5fbaSopenharmony_ci 213c87c5fbaSopenharmony_ci*coap_io_prepare_io*() and *coap_io_prepare_epoll*() return the number of 214c87c5fbaSopenharmony_cimilli-seconds that need to be waited before the function should next be called. 215c87c5fbaSopenharmony_ci 216c87c5fbaSopenharmony_ci*coap_io_pending*() returns 1 if there is outstanding i/o else returns 0. 217c87c5fbaSopenharmony_ci 218c87c5fbaSopenharmony_ci*coap_can_exit*() returns 1 if there is nothing outstanding to transmit else 219c87c5fbaSopenharmony_cireturns 0. 220c87c5fbaSopenharmony_ci 221c87c5fbaSopenharmony_ciEXAMPLES 222c87c5fbaSopenharmony_ci-------- 223c87c5fbaSopenharmony_ci*Method One - use coap_io_process()* 224c87c5fbaSopenharmony_ci 225c87c5fbaSopenharmony_ci[source, c] 226c87c5fbaSopenharmony_ci---- 227c87c5fbaSopenharmony_ci#include <coap@LIBCOAP_API_VERSION@/coap.h> 228c87c5fbaSopenharmony_ci 229c87c5fbaSopenharmony_ciint 230c87c5fbaSopenharmony_cimain(int argc, char *argv[]) { 231c87c5fbaSopenharmony_ci 232c87c5fbaSopenharmony_ci coap_context_t *ctx = NULL; 233c87c5fbaSopenharmony_ci unsigned wait_ms; 234c87c5fbaSopenharmony_ci /* Remove (void) definition if variable is used */ 235c87c5fbaSopenharmony_ci (void)argc; 236c87c5fbaSopenharmony_ci (void)argv; 237c87c5fbaSopenharmony_ci 238c87c5fbaSopenharmony_ci /* Initialize libcoap library */ 239c87c5fbaSopenharmony_ci coap_startup(); 240c87c5fbaSopenharmony_ci 241c87c5fbaSopenharmony_ci /* Create the libcoap context */ 242c87c5fbaSopenharmony_ci ctx = coap_new_context(NULL); 243c87c5fbaSopenharmony_ci if (!ctx) { 244c87c5fbaSopenharmony_ci exit(1); 245c87c5fbaSopenharmony_ci } 246c87c5fbaSopenharmony_ci /* See coap_block(3) */ 247c87c5fbaSopenharmony_ci coap_context_set_block_mode(ctx, 248c87c5fbaSopenharmony_ci COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 249c87c5fbaSopenharmony_ci 250c87c5fbaSopenharmony_ci 251c87c5fbaSopenharmony_ci /* Other Set up Code */ 252c87c5fbaSopenharmony_ci 253c87c5fbaSopenharmony_ci wait_ms = COAP_RESOURCE_CHECK_TIME * 1000; 254c87c5fbaSopenharmony_ci 255c87c5fbaSopenharmony_ci while (1) { 256c87c5fbaSopenharmony_ci int result = coap_io_process(ctx, wait_ms); 257c87c5fbaSopenharmony_ci if (result < 0) { 258c87c5fbaSopenharmony_ci /* There is an internal issue */ 259c87c5fbaSopenharmony_ci break; 260c87c5fbaSopenharmony_ci } 261c87c5fbaSopenharmony_ci /* Do any other housekeeping */ 262c87c5fbaSopenharmony_ci } 263c87c5fbaSopenharmony_ci coap_free_context(ctx); 264c87c5fbaSopenharmony_ci coap_cleanup(); 265c87c5fbaSopenharmony_ci 266c87c5fbaSopenharmony_ci /* Do any other cleanup */ 267c87c5fbaSopenharmony_ci 268c87c5fbaSopenharmony_ci exit(0); 269c87c5fbaSopenharmony_ci 270c87c5fbaSopenharmony_ci} 271c87c5fbaSopenharmony_ci---- 272c87c5fbaSopenharmony_ci 273c87c5fbaSopenharmony_ci*Method One - coap_io_process_with_fds* 274c87c5fbaSopenharmony_ci 275c87c5fbaSopenharmony_ci[source, c] 276c87c5fbaSopenharmony_ci---- 277c87c5fbaSopenharmony_ci#include <coap@LIBCOAP_API_VERSION@/coap.h> 278c87c5fbaSopenharmony_ci 279c87c5fbaSopenharmony_ciint 280c87c5fbaSopenharmony_cimain(int argc, char *argv[]) { 281c87c5fbaSopenharmony_ci 282c87c5fbaSopenharmony_ci coap_context_t *ctx = NULL; 283c87c5fbaSopenharmony_ci unsigned wait_ms; 284c87c5fbaSopenharmony_ci fd_set readfds; 285c87c5fbaSopenharmony_ci int nfds = 0; 286c87c5fbaSopenharmony_ci /* Remove (void) definition if variable is used */ 287c87c5fbaSopenharmony_ci (void)argc; 288c87c5fbaSopenharmony_ci (void)argv; 289c87c5fbaSopenharmony_ci 290c87c5fbaSopenharmony_ci /* Initialize libcoap library */ 291c87c5fbaSopenharmony_ci coap_startup(); 292c87c5fbaSopenharmony_ci 293c87c5fbaSopenharmony_ci /* Create the libcoap context */ 294c87c5fbaSopenharmony_ci ctx = coap_new_context(NULL); 295c87c5fbaSopenharmony_ci if (!ctx) { 296c87c5fbaSopenharmony_ci exit(1); 297c87c5fbaSopenharmony_ci } 298c87c5fbaSopenharmony_ci /* See coap_block(3) */ 299c87c5fbaSopenharmony_ci coap_context_set_block_mode(ctx, 300c87c5fbaSopenharmony_ci COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 301c87c5fbaSopenharmony_ci 302c87c5fbaSopenharmony_ci 303c87c5fbaSopenharmony_ci FD_ZERO(&readfds); 304c87c5fbaSopenharmony_ci /* Set up readfds and nfds to handle other non libcoap FDs */ 305c87c5fbaSopenharmony_ci 306c87c5fbaSopenharmony_ci /* Other Set up Code */ 307c87c5fbaSopenharmony_ci 308c87c5fbaSopenharmony_ci wait_ms = COAP_RESOURCE_CHECK_TIME * 1000; 309c87c5fbaSopenharmony_ci 310c87c5fbaSopenharmony_ci while (1) { 311c87c5fbaSopenharmony_ci int result = coap_io_process_with_fds(ctx, wait_ms, nfds, &readfds, NULL, NULL); 312c87c5fbaSopenharmony_ci if (result < 0) { 313c87c5fbaSopenharmony_ci /* There is an internal issue */ 314c87c5fbaSopenharmony_ci break; 315c87c5fbaSopenharmony_ci } 316c87c5fbaSopenharmony_ci /* Check if set non libcoap FDs and process accordingly */ 317c87c5fbaSopenharmony_ci 318c87c5fbaSopenharmony_ci /* Do any other housekeeping */ 319c87c5fbaSopenharmony_ci } 320c87c5fbaSopenharmony_ci coap_free_context(ctx); 321c87c5fbaSopenharmony_ci coap_cleanup(); 322c87c5fbaSopenharmony_ci 323c87c5fbaSopenharmony_ci /* Do any other cleanup */ 324c87c5fbaSopenharmony_ci 325c87c5fbaSopenharmony_ci exit(0); 326c87c5fbaSopenharmony_ci 327c87c5fbaSopenharmony_ci} 328c87c5fbaSopenharmony_ci---- 329c87c5fbaSopenharmony_ci 330c87c5fbaSopenharmony_ci*Method Two - select() based on monitorable file descriptor* 331c87c5fbaSopenharmony_ci 332c87c5fbaSopenharmony_ci[source, c] 333c87c5fbaSopenharmony_ci---- 334c87c5fbaSopenharmony_ci#include <coap@LIBCOAP_API_VERSION@/coap.h> 335c87c5fbaSopenharmony_ci 336c87c5fbaSopenharmony_ci#include <errno.h> 337c87c5fbaSopenharmony_ci 338c87c5fbaSopenharmony_ciint 339c87c5fbaSopenharmony_cimain(int argc, char *argv[]) { 340c87c5fbaSopenharmony_ci 341c87c5fbaSopenharmony_ci coap_context_t *ctx = NULL; 342c87c5fbaSopenharmony_ci int coap_fd; 343c87c5fbaSopenharmony_ci fd_set m_readfds; 344c87c5fbaSopenharmony_ci int nfds; 345c87c5fbaSopenharmony_ci /* Remove (void) definition if variable is used */ 346c87c5fbaSopenharmony_ci (void)argc; 347c87c5fbaSopenharmony_ci (void)argv; 348c87c5fbaSopenharmony_ci 349c87c5fbaSopenharmony_ci /* Initialize libcoap library */ 350c87c5fbaSopenharmony_ci coap_startup(); 351c87c5fbaSopenharmony_ci 352c87c5fbaSopenharmony_ci /* Create the libcoap context */ 353c87c5fbaSopenharmony_ci ctx = coap_new_context(NULL); 354c87c5fbaSopenharmony_ci if (!ctx) { 355c87c5fbaSopenharmony_ci exit(1); 356c87c5fbaSopenharmony_ci } 357c87c5fbaSopenharmony_ci /* See coap_block(3) */ 358c87c5fbaSopenharmony_ci coap_context_set_block_mode(ctx, 359c87c5fbaSopenharmony_ci COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 360c87c5fbaSopenharmony_ci 361c87c5fbaSopenharmony_ci coap_fd = coap_context_get_coap_fd(ctx); 362c87c5fbaSopenharmony_ci if (coap_fd == -1) { 363c87c5fbaSopenharmony_ci /* epoll is not supported */ 364c87c5fbaSopenharmony_ci exit(1); 365c87c5fbaSopenharmony_ci } 366c87c5fbaSopenharmony_ci FD_ZERO(&m_readfds); 367c87c5fbaSopenharmony_ci FD_SET(coap_fd, &m_readfds); 368c87c5fbaSopenharmony_ci nfds = coap_fd + 1; 369c87c5fbaSopenharmony_ci 370c87c5fbaSopenharmony_ci /* Other Set up Code */ 371c87c5fbaSopenharmony_ci 372c87c5fbaSopenharmony_ci while (1) { 373c87c5fbaSopenharmony_ci fd_set readfds = m_readfds; 374c87c5fbaSopenharmony_ci int result; 375c87c5fbaSopenharmony_ci /* Wait until any i/o takes place */ 376c87c5fbaSopenharmony_ci result = select (nfds, &readfds, NULL, NULL, NULL); 377c87c5fbaSopenharmony_ci if (result == -1) { 378c87c5fbaSopenharmony_ci if (errno != EAGAIN) { 379c87c5fbaSopenharmony_ci coap_log_debug("select: %s (%d)\n", coap_socket_strerror(), errno); 380c87c5fbaSopenharmony_ci break; 381c87c5fbaSopenharmony_ci } 382c87c5fbaSopenharmony_ci } 383c87c5fbaSopenharmony_ci if (result > 0) { 384c87c5fbaSopenharmony_ci if (FD_ISSET(coap_fd, &readfds)) { 385c87c5fbaSopenharmony_ci result = coap_io_process(ctx, COAP_IO_NO_WAIT); 386c87c5fbaSopenharmony_ci if (result < 0) { 387c87c5fbaSopenharmony_ci /* There is an internal issue */ 388c87c5fbaSopenharmony_ci break; 389c87c5fbaSopenharmony_ci } 390c87c5fbaSopenharmony_ci } 391c87c5fbaSopenharmony_ci } 392c87c5fbaSopenharmony_ci /* Do any other housekeeping */ 393c87c5fbaSopenharmony_ci } 394c87c5fbaSopenharmony_ci coap_free_context(ctx); 395c87c5fbaSopenharmony_ci coap_cleanup(); 396c87c5fbaSopenharmony_ci 397c87c5fbaSopenharmony_ci /* Do any other cleanup */ 398c87c5fbaSopenharmony_ci 399c87c5fbaSopenharmony_ci exit(0); 400c87c5fbaSopenharmony_ci 401c87c5fbaSopenharmony_ci} 402c87c5fbaSopenharmony_ci---- 403c87c5fbaSopenharmony_ci 404c87c5fbaSopenharmony_ci*Method Two - epoll_wait() based on monitorable file descriptor* 405c87c5fbaSopenharmony_ci 406c87c5fbaSopenharmony_ci[source, c] 407c87c5fbaSopenharmony_ci---- 408c87c5fbaSopenharmony_ci#include <coap@LIBCOAP_API_VERSION@/coap.h> 409c87c5fbaSopenharmony_ci 410c87c5fbaSopenharmony_ci#include <sys/epoll.h> 411c87c5fbaSopenharmony_ci 412c87c5fbaSopenharmony_ci#include <errno.h> 413c87c5fbaSopenharmony_ci 414c87c5fbaSopenharmony_ci#define MAX_EVENTS 10 415c87c5fbaSopenharmony_ci 416c87c5fbaSopenharmony_ciint 417c87c5fbaSopenharmony_cimain(int argc, char *argv[]) { 418c87c5fbaSopenharmony_ci 419c87c5fbaSopenharmony_ci coap_context_t *ctx = NULL; 420c87c5fbaSopenharmony_ci int coap_fd; 421c87c5fbaSopenharmony_ci int epoll_fd; 422c87c5fbaSopenharmony_ci struct epoll_event ev; 423c87c5fbaSopenharmony_ci struct epoll_event events[MAX_EVENTS]; 424c87c5fbaSopenharmony_ci int nevents; 425c87c5fbaSopenharmony_ci int i; 426c87c5fbaSopenharmony_ci /* Remove (void) definition if variable is used */ 427c87c5fbaSopenharmony_ci (void)argc; 428c87c5fbaSopenharmony_ci (void)argv; 429c87c5fbaSopenharmony_ci 430c87c5fbaSopenharmony_ci /* Initialize libcoap library */ 431c87c5fbaSopenharmony_ci coap_startup(); 432c87c5fbaSopenharmony_ci 433c87c5fbaSopenharmony_ci /* Create the libcoap context */ 434c87c5fbaSopenharmony_ci ctx = coap_new_context(NULL); 435c87c5fbaSopenharmony_ci if (!ctx) { 436c87c5fbaSopenharmony_ci exit(1); 437c87c5fbaSopenharmony_ci } 438c87c5fbaSopenharmony_ci /* See coap_block(3) */ 439c87c5fbaSopenharmony_ci coap_context_set_block_mode(ctx, 440c87c5fbaSopenharmony_ci COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 441c87c5fbaSopenharmony_ci 442c87c5fbaSopenharmony_ci coap_fd = coap_context_get_coap_fd(ctx); 443c87c5fbaSopenharmony_ci if (coap_fd == -1) { 444c87c5fbaSopenharmony_ci exit(1); 445c87c5fbaSopenharmony_ci } 446c87c5fbaSopenharmony_ci epoll_fd = epoll_create1(0); 447c87c5fbaSopenharmony_ci if (epoll_fd == -1) { 448c87c5fbaSopenharmony_ci exit(2); 449c87c5fbaSopenharmony_ci } 450c87c5fbaSopenharmony_ci ev.events = EPOLLIN; 451c87c5fbaSopenharmony_ci ev.data.fd = coap_fd; 452c87c5fbaSopenharmony_ci if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, coap_fd, &ev) == -1) { 453c87c5fbaSopenharmony_ci exit(3); 454c87c5fbaSopenharmony_ci } 455c87c5fbaSopenharmony_ci 456c87c5fbaSopenharmony_ci /* Other Set up Code */ 457c87c5fbaSopenharmony_ci 458c87c5fbaSopenharmony_ci while (1) { 459c87c5fbaSopenharmony_ci int result; 460c87c5fbaSopenharmony_ci /* Wait until any i/o takes place */ 461c87c5fbaSopenharmony_ci nevents = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); 462c87c5fbaSopenharmony_ci if (nevents == -1) { 463c87c5fbaSopenharmony_ci if (errno != EAGAIN) { 464c87c5fbaSopenharmony_ci coap_log_debug("epoll_wait: %s (%d)\n", coap_socket_strerror(), errno); 465c87c5fbaSopenharmony_ci break; 466c87c5fbaSopenharmony_ci } 467c87c5fbaSopenharmony_ci } 468c87c5fbaSopenharmony_ci for (i = 0; i < nevents; i++) { 469c87c5fbaSopenharmony_ci if (events[i].data.fd == coap_fd) { 470c87c5fbaSopenharmony_ci result = coap_io_process(ctx, COAP_IO_NO_WAIT); 471c87c5fbaSopenharmony_ci if (result < 0) { 472c87c5fbaSopenharmony_ci /* There is an internal issue */ 473c87c5fbaSopenharmony_ci break; 474c87c5fbaSopenharmony_ci } 475c87c5fbaSopenharmony_ci } 476c87c5fbaSopenharmony_ci else { 477c87c5fbaSopenharmony_ci /* Process other events */ 478c87c5fbaSopenharmony_ci } 479c87c5fbaSopenharmony_ci } 480c87c5fbaSopenharmony_ci /* Do any other housekeeping */ 481c87c5fbaSopenharmony_ci } 482c87c5fbaSopenharmony_ci 483c87c5fbaSopenharmony_ci if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, coap_fd, &ev) == -1) { 484c87c5fbaSopenharmony_ci coap_log_debug("epoll_ctl: %s (%d)\n", coap_socket_strerror(), errno); 485c87c5fbaSopenharmony_ci } 486c87c5fbaSopenharmony_ci coap_free_context(ctx); 487c87c5fbaSopenharmony_ci coap_cleanup(); 488c87c5fbaSopenharmony_ci 489c87c5fbaSopenharmony_ci /* Do any other cleanup */ 490c87c5fbaSopenharmony_ci 491c87c5fbaSopenharmony_ci exit(0); 492c87c5fbaSopenharmony_ci 493c87c5fbaSopenharmony_ci} 494c87c5fbaSopenharmony_ci---- 495c87c5fbaSopenharmony_ci 496c87c5fbaSopenharmony_ciSEE ALSO 497c87c5fbaSopenharmony_ci-------- 498c87c5fbaSopenharmony_ci*coap_block*(3), *coap_context*(3) and *coap_init*(3) 499c87c5fbaSopenharmony_ci 500c87c5fbaSopenharmony_ciFURTHER INFORMATION 501c87c5fbaSopenharmony_ci------------------- 502c87c5fbaSopenharmony_ciSee 503c87c5fbaSopenharmony_ci 504c87c5fbaSopenharmony_ci"https://rfc-editor.org/rfc/rfc7252[RFC7252: The Constrained Application Protocol (CoAP)]" 505c87c5fbaSopenharmony_ci 506c87c5fbaSopenharmony_cifor further information. 507c87c5fbaSopenharmony_ci 508c87c5fbaSopenharmony_ciBUGS 509c87c5fbaSopenharmony_ci---- 510c87c5fbaSopenharmony_ciPlease report bugs on the mailing list for libcoap: 511c87c5fbaSopenharmony_cilibcoap-developers@lists.sourceforge.net or raise an issue on GitHub at 512c87c5fbaSopenharmony_cihttps://github.com/obgm/libcoap/issues 513c87c5fbaSopenharmony_ci 514c87c5fbaSopenharmony_ciAUTHORS 515c87c5fbaSopenharmony_ci------- 516c87c5fbaSopenharmony_ciThe libcoap project <libcoap-developers@lists.sourceforge.net> 517