1COAP_HANDLER(3) libcoap Manual COAP_HANDLER(3)
2
3
4
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
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
38 This documents the different callback handlers that can optionally be
39 invoked on receipt of a packet or when a timeout occurs.
40
42 Function: coap_register_request_handler()
43
44 The coap_register_request_handler() is a server side function that
45 registers a callback handler handler that is called when there is an
46 incoming request PDU, there is a URI match against the resource and
47 there is a method (e.g. PUT, POST etc.) match. method can be one of the
48 following.
49
50 COAP_REQUEST_GET
51 COAP_REQUEST_POST
52 COAP_REQUEST_PUT
53 COAP_REQUEST_DELETE
54 COAP_REQUEST_FETCH
55 COAP_REQUEST_PATCH
56 COAP_REQUEST_IPATCH
57
58 The request handler function prototype is defined as:
59
60 typedef void (*coap_method_handler_t)(coap_resource_t *resource,
61 coap_session_t *session,
62 const coap_pdu_t *incoming_pdu,
63 const coap_string_t *query,
64 coap_pdu_t *response_pdu);
65
66 In handler, data from incoming_pdu can be abstracted as described in
67 coap_pdu_access(3) for analysis and then the handler updates
68 response_pdu as appropriate as described in coap_pdu_setup(3),
69 including the response code. If response_pdu's code is not updated,
70 then response_pdu will not get sent back to the client.
71
72 response_pdu is already pre-populated with the incoming_pdu's token and
73 the PDU type. If handler is called as a result of an unsolicited
74 Observe trigger, then the Observe option (and potentially Block2
75 option) are also added in. The response_pdu's response code should
76 always be updated.
77
78 This handler must not call coap_send(3) to send response_pdu.
79 response_pdu gets sent on return from handler, assuming the response
80 code has been updated. If the response code was not updated, then an
81 empty ACK packet will get sent for CON type requests or nothing for NON
82 type requests.
83
84 NOTE: Any data associated with incoming_pdu is no longer be available
85 after exiting this function as incoming_pdu is deleted. In particular
86 incoming_pdu's data must not be used if calling
87 coap_add_data_large_response(). However, it is safe to use the data if
88 coap_add_data() is used to update response_pdu where a copy of the data
89 is taken.
90
91 NOTE: A request callback handler can be called with a generic resource
92 (i.e. set up using coap_resource_unknown_init2(3)), so
93 coap_resource_get_uri_path(3) can be used to determine the URI in this
94 case.
95
96 Function: coap_register_response_handler()
97
98 The coap_register_response_handler() is a client side function that
99 registers a request’s response callback handler for traffic associated
100 with the context. The application can use this for handling any
101 response packets, including sending a RST packet if this response was
102 unexpected. If handler is NULL, then the handler is de-registered.
103
104 The response handler function prototype is defined as:
105
106 typedef enum coap_response_t {
107 COAP_RESPONSE_FAIL, /* Response not liked - send CoAP RST packet */
108 COAP_RESPONSE_OK /* Response is fine */
109 } coap_response_t;
110
111 typedef coap_response_t (*coap_response_handler_t)(coap_session_t *session,
112 const coap_pdu_t *sent,
113 const coap_pdu_t *received,
114 const coap_mid_t id);
115
116 In handler, data from received (and optionally sent if set) can be
117 abstracted as described in coap_pdu_access(3) for analysis.
118
119 NOTE: sent will only be non NULL when the request PDU is Confirmable
120 and this is an ACK or RST response to the request. In general, matching
121 of Requests and Responses whould be done by generating unique Tokens
122 for each Request and then matching up based on the Token in received
123 Response.
124
125 NOTE: If the returned value is COAP_RESPONSE_FAIL, then a CoAP RST
126 packet will get sent to the server by libcoap. The returned value of
127 COAP_RESPONSE_OK indicates that all is OK.
128
129 Function: coap_register_nack_handler()
130
131 The coap_register_nack_handler() is a client side function that
132 registers a request’s negative response callback handler for traffic
133 associated with the context. If handler is NULL, then the handler is
134 de-registered.
135
136 The nack handler function prototype is defined as:
137
138 typedef void (*coap_nack_handler_t)(coap_session_t *session,
139 const coap_pdu_t *sent,
140 const coap_nack_reason_t reason,
141 const coap_mid_t mid);
142
143 NACK reason can be one of the following
144
145 COAP_NACK_TOO_MANY_RETRIES
146 COAP_NACK_NOT_DELIVERABLE
147 COAP_NACK_RST
148 COAP_NACK_TLS_FAILED
149 COAP_NACK_ICMP_ISSUE
150 COAP_NACK_BAD_RESPONSE
151
152 sent can be NULL. mid can be used for determining which is the
153 transmitting request.
154
155 Function: coap_register_ping_handler()
156
157 The coap_register_ping_handler() function registers a callback handler
158 for tracking receipt of CoAP ping traffic associated with the context.
159 If handler is NULL, then the handler is de-registered. It can be used
160 both client and server side.
161
162 The ping handler function prototype is defined as:
163
164 typedef void (*coap_ping_handler_t)(coap_session_t *session,
165 const coap_pdu_t *received,
166 const coap_mid_t mid);
167
168 Function: coap_register_pong_handler()
169
170 The coap_register_pong_handler() function registers a callback handler
171 for tracking receipt of CoAP ping response traffic associated with the
172 context. If handler is NULL, then the handler is de-registered. It can
173 be used both client and server side.
174
175 The pong handler function prototype is defined as:
176
177 typedef void (*coap_pong_handler_t)(coap_session_t *session,
178 const coap_pdu_t *received,
179 const coap_mid_t mid);
180
181 Function: coap_register_event_handler()
182
183 The coap_register_event_handler() function registers a callback handler
184 for tracking network events associated with the context. If handler is
185 NULL, then the handler is de-registered. It can be used both client and
186 server side.
187
188 The event handler function prototype is defined as:
189
190 typedef void (*coap_event_handler_t)(coap_session_t *session,
191 const coap_event_t event);
192
193 Events can be one of the following
194
195 /**
196 * (D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS
197 */
198 COAP_EVENT_DTLS_CLOSED 0x0000
199 COAP_EVENT_DTLS_CONNECTED 0x01DE
200 COAP_EVENT_DTLS_RENEGOTIATE 0x01DF
201 COAP_EVENT_DTLS_ERROR 0x0200
202 /**
203 * TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS
204 */
205 COAP_EVENT_TCP_CONNECTED 0x1001
206 COAP_EVENT_TCP_CLOSED 0x1002
207 COAP_EVENT_TCP_FAILED 0x1003
208 /**
209 * CSM exchange events for reliable protocols only
210 */
211 COAP_EVENT_SESSION_CONNECTED 0x2001
212 COAP_EVENT_SESSION_CLOSED 0x2002
213 COAP_EVENT_SESSION_FAILED 0x2003
214 /**
215 * (Q-)BLOCK events
216 */
217 COAP_EVENT_PARTIAL_BLOCK 0x3001
218 COAP_EVENT_XMIT_BLOCK_FAIL 0x3002
219 /**
220 * Server session state management events
221 */
222 COAP_EVENT_SERVER_SESSION_NEW 0x4001
223 COAP_EVENT_SERVER_SESSION_DEL 0x4002
224 /**
225 * Message receive and transmit events
226 */
227 COAP_EVENT_BAD_PACKET 0x5001
228 COAP_EVENT_MSG_RETRANSMITTED 0x5002
229 /**
230 * OSCORE events
231 */
232 COAP_EVENT_OSCORE_DECRYPTION_FAILURE 0x6001
233 COAP_EVENT_OSCORE_NOT_ENABLED 0x6002
234 COAP_EVENT_OSCORE_NO_PROTECTED_PAYLOAD 0x6003
235 COAP_EVENT_OSCORE_NO_SECURITY 0x6004
236 COAP_EVENT_OSCORE_INTERNAL_ERROR 0x6005
237 COAP_EVENT_OSCORE_DECODE_ERROR 0x6006
238 /**
239 * WebSocket events
240 */
241 COAP_EVENT_WS_PACKET_SIZE 0x7001
242 COAP_EVENT_WS_CONNECTED 0x7002
243 COAP_EVENT_WS_CLOSE 0x7003
244 /**
245 * Keepalive events
246 */
247 COAP_EVENT_KEEPALIVE_FAILURE 0x8001
248
250 GET Resource Callback Handler
251
252 #include <coap3/coap.h>
253
254 #include <stdio.h>
255
256 static void
257 hnd_get_time(coap_resource_t *resource, coap_session_t *session,
258 coap_pdu_t *request, coap_string_t *query, coap_pdu_t *response) {
259
260 unsigned char buf[40];
261 size_t len;
262 time_t now;
263
264 /* ... Additional analysis code for resource, request pdu etc. ... */
265
266 /* After analysis, generate a suitable response */
267
268 now = time(NULL);
269
270 if (query != NULL && coap_string_equal(query, coap_make_str_const("secs"))) {
271 /* Output secs since Jan 1 1970 */
272 len = snprintf((char *)buf, sizeof(buf), "%lu", now);
273 }
274 else {
275 /* Output human-readable time */
276 struct tm *tmp;
277 tmp = gmtime(&now);
278 if (!tmp) {
279 /* If 'now' is not valid */
280 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
281 return;
282 }
283 len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp);
284 }
285 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
286 /*
287 * Invoke coap_add_data_large_response() to do all the hard work.
288 *
289 * Define the format - COAP_MEDIATYPE_TEXT_PLAIN - to add in
290 * Define how long this response is valid for (secs) - 1 - to add in.
291 *
292 * Observe Option added internally if needed within the function
293 * Block2 Option added internally if output too large
294 * ETag Option added internally
295 */
296 coap_add_data_large_response(resource, session, request, response,
297 query, COAP_MEDIATYPE_TEXT_PLAIN, 1, 0,
298 len,
299 buf, NULL, 0);
300
301 }
302
303 Packet Response Handler
304
305 #include <coap3/coap.h>
306
307 static int check_token(coap_pdu_t *received) {
308 /* Remove (void) definition if variable is used */
309 (void)received;
310
311 /* Code to validate the token is what we expect */
312
313 return 1;
314 }
315
316 static coap_response_t
317 response_handler(coap_context_t *ctx, coap_session_t *session,
318 coap_pdu_t *sent, coap_pdu_t *received, const coap_mid_t mid) {
319 /* Remove (void) definition if variable is used */
320 (void)ctx;
321 (void)session;
322 (void)mid;
323 coap_pdu_type_t rcv_type = coap_pdu_get_type(received);
324 coap_pdu_code_t rcv_code = coap_pdu_get_code(received);
325
326 /* check if this is a response to our original request */
327 if (!check_token(received)) {
328 /* drop if this was just some message, or send RST in case of notification */
329 if (!sent && (rcv_type == COAP_MESSAGE_CON ||
330 rcv_type == COAP_MESSAGE_NON)) {
331 /* Cause a CoAP RST to be sent */
332 return COAP_RESPONSE_FAIL;
333 }
334 return COAP_RESPONSE_OK;
335 }
336
337 if (rcv_type == COAP_MESSAGE_RST) {
338 coap_log_info("got RST\n");
339 return COAP_RESPONSE_OK;
340 }
341
342 /* Output the received data, if any */
343 if (COAP_RESPONSE_CLASS(rcv_code) == 2) {
344 /* Additional code to deal with the response */
345
346 }
347 return COAP_RESPONSE_OK;
348
349 }
350
352 coap_block(3), coap_observe(3), coap_pdu_access(3), coap_pdu_setup(3)
353 and coap_resource(3)
354
356 See
357
358 "RFC7252: The Constrained Application Protocol (CoAP)"
359
360 for further information.
361
363 Please report bugs on the mailing list for libcoap:
364 libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
365 https://github.com/obgm/libcoap/issues
366
368 The libcoap project <libcoap-developers@lists.sourceforge.net>
369
370
371
372coap_handler 4.3.4 10/09/2023 COAP_HANDLER(3)