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

NAME

6       coap_handler, coap_register_request_handler,
7       coap_register_response_handler, coap_register_nack_handler,
8       coap_register_ping_handler, coap_register_pong_handler,
9       coap_register_event_handler - Work with CoAP handlers
10

SYNOPSIS

12       #include <coap3/coap.h>
13
14       void coap_register_request_handler(coap_resource_t *resource,
15       coap_request_t method, coap_method_handler_t handler);
16
17       void coap_register_response_handler(coap_context_t *context,
18       coap_response_handler_t handler);
19
20       void coap_register_nack_handler(coap_context_t *context,
21       coap_nack_handler_t handler);
22
23       void coap_register_ping_handler(coap_context_t *context,
24       coap_ping_handler_t handler);
25
26       void coap_register_pong_handler(coap_context_t *context,
27       coap_pong_handler_t handler);
28
29       void coap_register_event_handler(coap_context_t *context,
30       coap_event_handler_t handler);
31
32       For specific (D)TLS library support, link with -lcoap-3-notls,
33       -lcoap-3-gnutls, -lcoap-3-openssl, -lcoap-3-mbedtls or
34       -lcoap-3-tinydtls. Otherwise, link with -lcoap-3 to get the default
35       (D)TLS library support.
36

DESCRIPTION

38       The coap_register_request_handler() is a server side function that
39       registers a callback handler handler that is called when there is an
40       incoming request PDU and there is a URI match against the resource and
41       there is a method (e.g. PUT, POST etc.) match. method can be one of the
42       following.
43
44           COAP_REQUEST_GET
45           COAP_REQUEST_POST
46           COAP_REQUEST_PUT
47           COAP_REQUEST_DELETE
48           COAP_REQUEST_FETCH
49           COAP_REQUEST_PATCH
50           COAP_REQUEST_IPATCH
51
52       The method handler function prototype is defined as:
53
54           typedef void (*coap_method_handler_t)(coap_resource_t *resource,
55                                                 coap_session_t *session,
56                                                 const coap_pdu_t *incoming_pdu,
57                                                 const coap_string_t *query,
58                                                 coap_pdu_t *response_pdu);
59
60       In handler, data from incoming_pdu can be abstracted as described in
61       coap_pdu_access(3) for analysis and then updates response_pdu as
62       appropriate as described in coap_pdu_setup(3). response_pdu is already
63       pre-populated with the incoming_pdu's token and the PDU type. If this
64       handler is called as a result of an unsolicited Observe trigger, then
65       the option OBSERVE (and potentially option BLOCK2) are also added in.
66       The response_pdu's response code should always be updated.
67
68       NOTE: Any data associated with incoming_pdu is no longer be available
69       after exiting this function as incoming_pdu is deleted. In particular
70       incoming_pdu's data must not be used if calling
71       coap_add_data_large_response(). However, it is safe to use the data if
72       coap_add_data() is used to update response_pdu where a copy of the data
73       is taken.
74
75       NOTE: A request callback handler can be called with a generic resource
76       (i.e. set up using coap_resource_unknown_init2(3)), so
77       coap_resource_get_uri_path(3) can be used to determine the URI in this
78       case.
79
80       The coap_register_response_handler() is a client side function that
81       registers a request’s response callback handler for traffic associated
82       with the context. The application can use this for handling any
83       response packets, including sending a RST packet if this response was
84       unexpected. If handler is NULL, then the handler is de-registered.
85
86       The response handler function prototype is defined as:
87
88           typedef enum coap_response_t {
89             COAP_RESPONSE_FAIL, /* Response not liked - send CoAP RST packet */
90             COAP_RESPONSE_OK    /* Response is fine */
91           } coap_response_t;
92
93           typedef coap_response_t (*coap_response_handler_t)(coap_session_t *session,
94                                                              const coap_pdu_t *sent,
95                                                              const coap_pdu_t *received,
96                                                              const coap_mid_t id);
97
98       In handler, data from received (and optionally sent if set) can be
99       abstracted as described in coap_pdu_access(3) for analysis.
100
101       NOTE: sent will only be non NULL when the request PDU is Confirmable
102       and this is an ACK or RST response to the request. In general, matching
103       of Requests and Responses whould be done by generating unique Tokens
104       for each Request and then matching up based on the Token in received
105       Response.
106
107       NOTE: If the returned value is COAP_RESPONSE_FAIL, then a CoAP RST
108       packet will get sent to the server by libcoap. The returned value of
109       COAP_RESPONSE_OK indicates that all is OK.
110
111       The coap_register_nack_handler() is a client side function that
112       registers a request’s negative response callback handler for traffic
113       associated with the context. If handler is NULL, then the handler is
114       de-registered.
115
116       The nack handler function prototype is defined as:
117
118           typedef void (*coap_nack_handler_t)(coap_session_t *session,
119                                               const coap_pdu_t *sent,
120                                               const coap_nack_reason_t reason,
121                                               const coap_mid_t mid);
122
123       NACK reason can be one of the following
124
125           COAP_NACK_TOO_MANY_RETRIES
126           COAP_NACK_NOT_DELIVERABLE
127           COAP_NACK_RST
128           COAP_NACK_TLS_FAILED
129           COAP_NACK_ICMP_ISSUE
130
131       sent can be NULL. mid can be used for determing which is the
132       transmitting request.
133
134       The coap_register_ping_handler() function registers a callback handler
135       for tracking receipt of CoAP ping traffic associated with the context.
136       If handler is NULL, then the handler is de-registered. It can be used
137       both client and server side.
138
139       The ping handler function prototype is defined as:
140
141           typedef void (*coap_ping_handler_t)(coap_session_t *session,
142                                               const coap_pdu_t *received,
143                                               const coap_mid_t mid);
144
145       The coap_register_pong_handler() function registers a callback handler
146       for tracking receipt of CoAP ping response traffic associated with the
147       context. If handler is NULL, then the handler is de-registered. It can
148       be used both client and server side.
149
150       The pong handler function prototype is defined as:
151
152           typedef void (*coap_pong_handler_t)(coap_session_t *session,
153                                               const coap_pdu_t *received,
154                                               const coap_mid_t mid);
155
156       The coap_register_event_handler() function registers a callback handler
157       for tracking network events associated with the context. If handler is
158       NULL, then the handler is de-registered. It can be used both client and
159       server side.
160
161       The event handler function prototype is defined as:
162
163           typedef void (*coap_event_handler_t)(coap_session_t *session,
164                                                const coap_event_t event);
165
166       Events can be one of the following
167
168           /**
169            * (D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS
170            */
171           COAP_EVENT_DTLS_CLOSED        0x0000
172           COAP_EVENT_DTLS_CONNECTED     0x01DE
173           COAP_EVENT_DTLS_RENEGOTIATE   0x01DF
174           COAP_EVENT_DTLS_ERROR         0x0200
175           /**
176            * TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS
177            */
178           COAP_EVENT_TCP_CONNECTED      0x1001
179           COAP_EVENT_TCP_CLOSED         0x1002
180           COAP_EVENT_TCP_FAILED         0x1003
181           /**
182            * CSM exchange events for reliable protocols only
183            */
184           COAP_EVENT_SESSION_CONNECTED  0x2001
185           COAP_EVENT_SESSION_CLOSED     0x2002
186           COAP_EVENT_SESSION_FAILED     0x2003
187           /**
188            * (Q-)BLOCK errors
189            */
190           COAP_EVENT_PARTIAL_BLOCK      0x3001
191           COAP_EVENT_XMIT_BLOCK_FAIL    0x3002
192           /**
193            * Server session state management events
194            */
195           COAP_EVENT_SERVER_SESSION_NEW 0x4001
196           COAP_EVENT_SERVER_SESSION_DEL 0x4002
197

EXAMPLES

199       GET Resource Callback Handler
200
201           #include <coap3/coap.h>
202
203           #include <stdio.h>
204
205           static void
206           hnd_get_time(coap_resource_t *resource, coap_session_t *session,
207           coap_pdu_t *request, coap_string_t *query, coap_pdu_t *response) {
208
209             unsigned char buf[40];
210             size_t len;
211             time_t now;
212
213             /* ... Additional analysis code for resource, request pdu etc.  ... */
214
215             /* After analysis, generate a suitable response */
216
217             now = time(NULL);
218
219             if (query != NULL && coap_string_equal(query, coap_make_str_const("secs"))) {
220               /* Output secs since Jan 1 1970 */
221               len = snprintf((char *)buf, sizeof(buf), "%lu", now);
222             }
223             else {
224               /* Output human-readable time */
225               struct tm *tmp;
226               tmp = gmtime(&now);
227               if (!tmp) {
228                 /* If 'now' is not valid */
229                 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
230                 return;
231               }
232               len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp);
233             }
234             coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
235             /*
236              * Invoke coap_add_data_large_response() to do all the hard work.
237              *
238              * Define the format - COAP_MEDIATYPE_TEXT_PLAIN - to add in
239              * Define how long this response is valid for (secs) - 1 - to add in.
240              *
241              * OBSERVE Option added internally if needed within the function
242              * BLOCK2 Option added internally if output too large
243              * ETAG Option added internally
244              */
245             coap_add_data_large_response(resource, session, request, response,
246                                          query, COAP_MEDIATYPE_TEXT_PLAIN, 1, 0,
247                                          len,
248                                          buf, NULL, 0);
249
250           }
251
252       Packet Response Handler
253
254           #include <coap3/coap.h>
255
256           static int check_token(coap_pdu_t *received) {
257             /* Remove (void) definition if variable is used */
258             (void)received;
259
260             /* Code to validate the token is what we expect */
261
262             return 1;
263           }
264
265           static coap_response_t
266           response_handler(coap_context_t *ctx, coap_session_t *session,
267           coap_pdu_t *sent, coap_pdu_t *received, const coap_mid_t mid) {
268             /* Remove (void) definition if variable is used */
269             (void)ctx;
270             (void)session;
271             (void)mid;
272             coap_pdu_type_t rcv_type = coap_pdu_get_type(received);
273             coap_pdu_code_t rcv_code = coap_pdu_get_code(received);
274
275             /* check if this is a response to our original request */
276             if (!check_token(received)) {
277               /* drop if this was just some message, or send RST in case of notification */
278               if (!sent && (rcv_type == COAP_MESSAGE_CON ||
279                             rcv_type == COAP_MESSAGE_NON)) {
280                 /* Cause a CoAP RST to be sent */
281                 return COAP_RESPONSE_FAIL;
282               }
283               return COAP_RESPONSE_OK;
284             }
285
286             if (rcv_type == COAP_MESSAGE_RST) {
287               coap_log(LOG_INFO, "got RST\n");
288               return COAP_RESPONSE_OK;
289             }
290
291             /* Output the received data, if any */
292             if (COAP_RESPONSE_CLASS(rcv_code) == 2) {
293               /* Additional code to deal with the response */
294
295             }
296             return COAP_RESPONSE_OK;
297
298           }
299

SEE ALSO

301       coap_block(3), coap_observe(3), coap_pdu_access(3), coap_pdu_setup(3)
302       and coap_resource(3)
303

FURTHER INFORMATION

305       See "RFC7252: The Constrained Application Protocol (CoAP)" for further
306       information.
307

BUGS

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

AUTHORS

314       The libcoap project <libcoap-developers@lists.sourceforge.net>
315
316
317
318coap_handler 4.3.1                01/19/2023                   COAP_HANDLER(3)
Impressum