1COAP_IO(3)                      libcoap Manual                      COAP_IO(3)
2
3
4

NAME

6       coap_io, coap_run_once, coap_context_get_coap_fd - Work with CoAP I/O
7       to do the packet send and receives
8

SYNOPSIS

10       #include <coap2/coap.h>
11
12       int coap_run_once(coap_context_t *context, unsigned int timeout_ms);
13
14       int coap_context_get_coap_fd(coap_context_t *context);
15
16       Link with -lcoap-2, -lcoap-2-gnutls, -lcoap-2-openssl or
17       -lcoap-2-tinydtls depending on your (D)TLS library type.
18

DESCRIPTION

20       After setting up all the contexts, resources, endpoints sessions etc.,
21       the underlying CoAP and (D)TLS need to send (and possible re-send)
22       created packets as well as receive packets for processing.
23
24       The coap_run_once() function will process any outstanding packets to
25       send for the specified context and wait for processing any input
26       packets for up to timeout_ms milli-seconds before returning. Once any
27       outstanding input packets have been processed, the function will
28       return. There are 2 special case timeout_ms values.
29
30           #define COAP_RUN_BLOCK    0
31           #define COAP_RUN_NONBLOCK 1
32
33       If timeout_ms is set to COAP_RUN_BLOCK, then coap_run_once() will wait
34       indefinitely for the first new input packet to come in. If timeout_ms
35       is set to COAP_RUN_NONBLOCK, then there is no wait if there are no more
36       input packets.
37
38       There are two methods of how to call coap_run_once().
39
40        1. Have coap_run_once() called from within a while() loop. Under idle
41           conditions (no input traffic) coap_run_once() will then get called
42           every timeout_ms, but more frequently if there is input traffic.
43
44        2. Wait on the file descriptor returned by coap_context_get_coap_fd()
45           using select() or an event returned by epoll_wait(). If read is
46           available on the file descriptor, call coap_run_once() with
47           timeout_ms set to COAP_RUN_NONBLOCK. See EXAMPLES below.
48
49           Note
50           This method is only available for environments that support epoll
51           (mostly Linux) as libcoap will then be using epoll internally to
52           process all the file descriptors of the different sessions.
53
54       The coap_context_get_coap_fd() function obtains from the specified
55       context a single file descriptor that can be monitored by a select() or
56       as an event returned from a epoll_wait() call. This file descriptor
57       will get updated with information (read, write etc. available) whenever
58       any of the internal to libcoap file descriptors (sockets) change state.
59

RETURN VALUES

61       coap_run_once() returns the time, in milli-seconds, that was spent in
62       the function. If -1 is returned, there was an unexpected error.
63
64       coap_context_get_coap_fd() returns a non-negative number as the file
65       descriptor to monitor, or -1 if epoll is not supported by the host
66       environment.
67

EXAMPLES

69       Method One
70
71           #include <coap2/coap.h>
72
73           int main(int argc, char *argv[]){
74
75             coap_context_t *ctx = NULL;
76             unsigned wait_ms;
77
78             /* Create the libcoap context */
79             ctx = coap_new_context(NULL);
80             if (!ctx) {
81               exit(1);
82             }
83
84             /* Other Set up Code */
85
86             wait_ms = COAP_RESOURCE_CHECK_TIME * 1000;
87
88             while (1) {
89               int result = coap_run_once(ctx, wait_ms);
90               if (result < 0) {
91                 /* There is an internal issue */
92                 break;
93               }
94               /* Do any other housekeeping */
95             }
96             coap_free_context(ctx);
97
98             /* Do any other cleanup */
99
100             exit(0);
101
102           }
103
104       Method Two - select
105
106           #include <coap2/coap.h>
107
108           #include <errno.h>
109
110           int main(int argc, char *argv[]){
111
112             coap_context_t *ctx = NULL;
113             int coap_fd;
114             fd_set m_readfds;
115             int nfds;
116
117             /* Create the libcoap context */
118             ctx = coap_new_context(NULL);
119             if (!ctx) {
120               exit(1);
121             }
122             coap_fd = coap_context_get_coap_fd(ctx);
123             if (coap_fd == -1) {
124               exit(1);
125             }
126             FD_ZERO(&m_readfds);
127             FD_SET(coap_fd, &m_readfds);
128             nfds = coap_fd + 1;
129
130             /* Other Set up Code */
131
132             while (1) {
133               fd_set readfds = m_readfds;
134               int result;
135               /* Wait until any i/o takes place */
136               result = select (nfds, &readfds, NULL, NULL, NULL);
137               if (result == -1) {
138                 if (errno != EAGAIN) {
139                   coap_log(LOG_DEBUG, "select: %s (%d)\n", coap_socket_strerror(), errno);
140                   break;
141                 }
142               }
143               if (result > 0) {
144                 if (FD_ISSET(coap_fd, &readfds)) {
145                   result = coap_run_once(ctx, COAP_RUN_NONBLOCK);
146                   if (result < 0) {
147                     /* There is an internal issue */
148                     break;
149                   }
150                 }
151               }
152               /* Do any other housekeeping */
153             }
154             coap_free_context(ctx);
155
156             /* Do any other cleanup */
157
158             exit(0);
159
160           }
161
162       Method Two - epoll
163
164           #include <coap2/coap.h>
165
166           #include <sys/epoll.h>
167
168           #include <errno.h>
169
170           #define MAX_EVENTS 10
171
172           int main(int argc, char *argv[]){
173
174             coap_context_t *ctx = NULL;
175             int coap_fd;
176             int epoll_fd;
177             struct epoll_event ev;
178             struct epoll_event events[MAX_EVENTS];
179             int nevents;
180             int i;
181
182             /* Create the libcoap context */
183             ctx = coap_new_context(NULL);
184             if (!ctx) {
185               exit(1);
186             }
187             coap_fd = coap_context_get_coap_fd(ctx);
188             if (coap_fd == -1) {
189               exit(1);
190             }
191             epoll_fd = epoll_create1(0);
192             if (epoll_fd == -1) {
193               exit(2);
194             }
195             ev.events = EPOLLIN;
196             ev.data.fd = coap_fd;
197             if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, coap_fd, &ev) == -1) {
198               exit(3);
199             }
200
201             /* Other Set up Code */
202
203             while (1) {
204               int result;
205               /* Wait until any i/o takes place */
206               nevents = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
207               if (nevents == -1) {
208                 if (errno != EAGAIN) {
209                   coap_log(LOG_DEBUG, "epoll_wait: %s (%d)\n", coap_socket_strerror(), errno);
210                   break;
211                 }
212               }
213               for (i = 0; i < nevents; i++) {
214                 if (events[i].data.fd == coap_fd) {
215                   result = coap_run_once(ctx, COAP_RUN_NONBLOCK);
216                   if (result < 0) {
217                     /* There is an internal issue */
218                     break;
219                   }
220                 }
221                 else {
222                   /* Process other events */
223                 }
224               }
225               /* Do any other housekeeping */
226             }
227
228             if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, coap_fd, &ev) == -1) {
229               coap_log(LOG_DEBUG, "epoll_ctl: %s (%d)\n", coap_socket_strerror(), errno);
230             }
231             coap_free_context(ctx);
232
233             /* Do any other cleanup */
234
235             exit(0);
236
237           }
238

SEE ALSO

240       coap_context(3)
241

FURTHER INFORMATION

243       See "RFC7252: The Constrained Application Protocol (CoAP)" for further
244       information.
245

BUGS

247       Please report bugs on the mailing list for libcoap:
248       libcoap-developers@lists.sourceforge.net
249

AUTHORS

251       The libcoap project <libcoap-developers@lists.sourceforge.net>
252
253
254
255coap_io 4.2.1                     01/26/2021                        COAP_IO(3)
Impressum