1COAP_RESOURCE(3) libcoap Manual COAP_RESOURCE(3)
2
3
4
6 coap_resource, coap_resource_init, coap_resource_unknown_init,
7 coap_resource_unknown_init2, coap_resource_proxy_uri_init,
8 coap_resource_proxy_uri_init2, coap_add_resource, coap_delete_resource,
9 coap_resource_set_mode, coap_resource_set_userdata,
10 coap_resource_get_userdata, coap_resource_release_userdata_handler,
11 coap_resource_get_uri_path - Work with CoAP resources
12
14 #include <coap3/coap.h>
15
16 coap_resource_t *coap_resource_init(coap_str_const_t *uri_path, int
17 flags);
18
19 coap_resource_t *coap_resource_unknown_init(coap_method_handler_t
20 put_handler);
21
22 coap_resource_t *coap_resource_unknown_init2(coap_method_handler_t
23 put_handler, int flags);
24
25 coap_resource_t *coap_resource_proxy_uri_init(coap_method_handler_t
26 proxy_handler, size_t host_name_count, const char *host_name_list[]);
27
28 coap_resource_t *coap_resource_proxy_uri_init2(coap_method_handler_t
29 proxy_handler, size_t host_name_count, const char *host_name_list[],
30 int flags);
31
32 void coap_add_resource(coap_context_t *context, coap_resource_t
33 *resource);
34
35 int coap_delete_resource(coap_context_t *context, coap_resource_t
36 *resource);
37
38 void coap_resource_set_mode(coap_resource_t *resource, int mode);
39
40 void coap_resource_set_userdata(coap_resource_t *resource, void *data);
41
42 void *coap_resource_get_userdata(coap_resource_t *resource);
43
44 void coap_resource_release_userdata_handler(coap_context_t *context,
45 coap_resource_release_userdata_handler_t callback);
46
47 coap_str_const_t *coap_resource_get_uri_path(coap_resource_t
48 *resource);
49
50 For specific (D)TLS library support, link with -lcoap-3-notls,
51 -lcoap-3-gnutls, -lcoap-3-openssl, -lcoap-3-mbedtls or
52 -lcoap-3-tinydtls. Otherwise, link with -lcoap-3 to get the default
53 (D)TLS library support.
54
56 CoAP Resources on a CoAP Server need to be created and updated etc. The
57 URI in the request packet defines the resource to work with, with
58 possibly the Query referring to a sub-resource.
59
60 When resources are configured on the CoAP server, the URI to match
61 against in the request packet is specified.
62
63 Callback Handlers are then added to the resource to handle the
64 different request methods. See coap_register_request_handler(3) for
65 further information.
66
67 Adding Attributes allows textual information to be added to the
68 resource which can then be reported back to any client doing a "GET
69 .well-known/core" request. See coap_add_attr(3) for further
70 information.
71
72 If an incoming packet request matches a resource’s URI and Method, then
73 the appropriate callback resource handler is invoked to process the
74 packet which should then update a suitable response packet for
75 returning back to the requester.
76
77 There is support for handling incoming packets where the URI is unknown
78 (no specific resource has been created). This could, for example,
79 happen when a PUT request is trying to create a new resource. It is the
80 responsibility of the unknown resource callback handler to either
81 create a new resource for the URI or just manage things separately.
82
83 CoAP Observe (RFC 7641) is not supported for unknown resources, so a
84 new resource with GET handler must be created by the unknown resource
85 callback handle matching the URI which then can be Observable.
86
87 There is support for handling incoming proxy based requests using the
88 Proxy-Uri or Proxy-Scheme options.
89
91 Function: coap_resource_init()
92
93 The coap_resource_init() function returns a newly created resource of
94 type coap_resource_t * . uri_path specifies the uri string path to
95 match against. Normally there is no need for the leading / - e.g. just
96 "full/path/for/resource". flags is used to define whether the resource
97 is of type Confirmable Message or Non-Confirmable Message for any
98 "observe" responses. See coap_observe(3). flags can be one of the
99 following definitions ored together.
100
101
102 COAP_RESOURCE_FLAGS_NOTIFY_NON Set the notification
103 message type to
104 non-confirmable for any
105 trigggered "observe"
106 responses with type set to
107 confirmable every 5
108 packets as required by
109 RFC7641 section-4.5.
110
111 COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS Set the notification
112 message type to always
113 non-confirmable for any
114 trigggered "observe"
115 responses. This should
116 only be used if a upper
117 layer protocol requires
118 it.
119
120 COAP_RESOURCE_FLAGS_NOTIFY_CON Set the notification
121 message type to
122 confirmable for any
123 trigggered "observe"
124 responses.
125
126 COAP_RESOURCE_FLAGS_RELEASE_URI Free off the
127 coap_str_const_t for
128 uri_path when the resource
129 is deleted.
130
131
132 NOTE: The following flags are only tested against if
133 coap_mcast_per_resource() has been called. If coap_mcast_per_resource()
134 has not been called, then all resources have multicast support, libcoap
135 adds in random delays to the responses, and 4.xx / 5.xx responses are
136 dropped.
137
138
139 COAP_RESOURCE_FLAGS_HAS_MCAST_SUPPORT This resource has support
140 for multicast requests.
141
142 COAP_RESOURCE_FLAGS_LIB_DIS_MCAST_DELAYS Disable libcoap library
143 from adding in delays to
144 multicast requests before
145 releasing the response
146 back to the client. It is
147 then the responsibility of
148 the app to delay the
149 responses for multicast
150 requests. See
151 https://datatracker.ietf.org/doc/html/rfc7252#section-8.2.
152 However, the pseudo
153 resource for
154 ".well-known/core" always
155 has multicast support
156 enabled.
157
158 COAP_RESOURCE_FLAGS_LIB_ENA_MCAST_SUPPRESS_2_05 Enable libcoap library suppression of 205 multicast
159 responses that are empty (overridden by RFC7969
160 No-Response option) for multicast requests.
161
162 COAP_RESOURCE_FLAGS_LIB_ENA_MCAST_SUPPRESS_2_XX Enable libcoap library suppressing 2.xx multicast
163 responses (overridden by RFC7969 No-Response option) for
164 multicast requests.
165
166 COAP_RESOURCE_FLAGS_LIB_DIS_MCAST_SUPPRESS_4_XX Disable libcoap library suppressing 4.xx multicast
167 responses (overridden by RFC7969 No-Response option) for
168 multicast requests.
169
170 COAP_RESOURCE_FLAGS_LIB_DIS_MCAST_SUPPRESS_5_XX Disable libcoap library suppressing 5.xx multicast
171 responses (overridden by RFC7969 No-Response option) for
172 multicast requests.
173
174
175 NOTE: uri_path, if not 7 bit readable ASCII, binary bytes must be hex
176 encoded according to the rules defined in RFC3968 Section 2.1.
177
178 Function: coap_resource_unknown_init()
179
180 The coap_resource_unknown_init() function returns a newly created
181 resource of type coap_resource_t *. put_handler is automatically added
182 to the resource to handle PUT requests to resources that are unknown.
183 Additional handlers can be added to this resource if required.
184
185 Function: coap_resource_unknown_init2()
186
187 The coap_resource_unknown_init2() function returns a newly created
188 resource of type coap_resource_t *. put_handler is automatically added
189 to the resource to handle PUT requests to resources that are unknown.
190 Additional handlers can be added to this resource if required. flags
191 can be zero or more COAP_RESOURCE_FLAGS MCAST definitions.
192
193 Function: coap_resource_proxy_uri_init()
194
195 The coap_resource_proxy_uri_init() function returns a newly created
196 resource of type coap_resource_t *. proxy_handler is automatically
197 added to the resource to handle PUT/POST/GET etc. requests that use the
198 Proxy-Uri option. There is no need to add explicit request type
199 handlers. One or more names by which the proxy is known by (IP address,
200 DNS name etc.) must be supplied in the array defined by
201 host_name_list[] which has a count of host_name_count. This is used to
202 check whether the current endpoint is the proxy target address, or the
203 request has to be passed on to an upstream server.
204
205 Function: coap_resource_proxy_uri_init2()
206
207 The coap_resource_proxy_uri_init2() function returns a newly created
208 resource of type coap_resource_t *. proxy_handler is automatically
209 added to the resource to handle PUT/POST/GET etc. requests that use the
210 Proxy-Uri option. There is no need to add explicit request type
211 handlers. One or more names by which the proxy is known by (IP address,
212 DNS name etc.) must be supplied in the array defined by
213 host_name_list[] which has a count of host_name_count. This is used to
214 check whether the current endpoint is the proxy target address, or the
215 request has to be passed on to an upstream server. flags can be zero or
216 more COAP_RESOURCE_FLAGS MCAST definitions.
217
218 Function: coap_add_resource()
219
220 The coap_add_resource() function registers the given resource with the
221 context. The resource must have been created by coap_resource_init(),
222 coap_resource_unknown_init(), coap_resource_unknown_init2(),
223 coap_resource_proxy_uri_init() or coap_resource_proxy_uri_init2(). The
224 storage allocated for the resource will be released by
225 coap_delete_resource().
226
227 As the uri_path of the resource has to be unique across all of the
228 resources associated with a context, coap_add_resource() will delete
229 any previous resource with the same uri_path before adding in the new
230 resource.
231
232 Function: coap_delete_resource()
233
234 The coap_delete_resource() function deletes a resource identified by
235 resource. The context parameter is ignored. The storage allocated for
236 that resource is freed, along with any attributes associated with the
237 resource.
238
239 Function: coap_resource_set_mode()
240
241 The coap_resource_set_mode() changes the notification message type of
242 resource to the given mode which must be one of
243 COAP_RESOURCE_FLAGS_NOTIFY_NON, COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS
244 or COAP_RESOURCE_FLAGS_NOTIFY_CON.
245
246 Function: coap_resource_set_userdata()
247
248 The coap_resource_set_userdata() function allows a pointer to user data
249 to be associated with a resource that can accessed in any callback that
250 includes resource as a parameter.
251
252 NOTE: data must point to a static, or allocated, block of memory.
253
254 Function: coap_resource_get_userdata()
255
256 The coap_resource_get_userdata() function obtains the user data pointer
257 from the resource that had previously been set up by
258 coap_resource_set_userdata().
259
260 Function: coap_resource_release_userdata_handler()
261
262 The coap_resource_release_userdata_handler() function defines the
263 context wide callback handler to call to release the allocated user
264 data that has been added to the resource using
265 coap_resource_set_userdata() when the resource is deleted. callback can
266 be NULL (which is the default) if nothing needs to be freed off.
267
268 Function: coap_resource_get_uri_path()
269
270 The coap_resource_get_uri_path() function is used to obtain the UriPath
271 of the resource definion.
272
274 The coap_resource_init(), coap_resource_unknown_init(),
275 coap_resource_unknown_init2(), coap_resource_proxy_uri_init() and
276 coap_resource_proxy_uri_init2() functions return a newly created
277 resource or NULL if there is a malloc failure.
278
279 The coap_delete_resource() function return 0 on failure (resource not
280 found), 1 on success.
281
282 The coap_resource_get_userdata() function returns the value previously
283 set by the coap_resource_set_userdata() function or NULL.
284
285 The coap_resource_get_uri_path() function returns the uri_path or NULL
286 if there was a failure.
287
289 Fixed Resources Set Up
290
291 #include <coap3/coap.h>
292
293 #define INDEX "This is an example server using libcoap\n"
294
295 static void
296 hnd_get_index(coap_resource_t *resource, coap_session_t *session,
297 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
298 unsigned char buf[3];
299 /* Remove (void) definition if variable is used */
300 (void)resource;
301 (void)session;
302 (void)request;
303 (void)query;
304
305 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
306
307 coap_add_option(response,
308 COAP_OPTION_CONTENT_TYPE,
309 coap_encode_var_safe(buf, sizeof(buf),
310 COAP_MEDIATYPE_TEXT_PLAIN),
311 buf);
312
313 coap_add_option(response,
314 COAP_OPTION_MAXAGE,
315 coap_encode_var_safe(buf, sizeof(buf), 0x2ffff), buf);
316
317 coap_add_data(response, strlen(INDEX), (const uint8_t *)INDEX);
318
319 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
320 }
321
322 static void
323 hnd_delete_time(coap_resource_t *resource, coap_session_t *session,
324 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
325 /* Remove (void) definition if variable is used */
326 (void)resource;
327 (void)session;
328 (void)request;
329 (void)query;
330
331 /* .. code .. */
332
333 coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
334 }
335
336 static void
337 hnd_get_time(coap_resource_t *resource, coap_session_t *session,
338 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
339 /* Remove (void) definition if variable is used */
340 (void)resource;
341 (void)session;
342 (void)request;
343 (void)query;
344 (void)response;
345
346 /* .. code .. */
347
348 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
349 }
350
351 static void
352 hnd_put_time(coap_resource_t *resource, coap_session_t *session,
353 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
354 /* Remove (void) definition if variable is used */
355 (void)resource;
356 (void)session;
357 (void)request;
358 (void)query;
359 (void)response;
360
361 /* .. code .. */
362
363 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
364 }
365
366 static void
367 init_resources(coap_context_t *ctx) {
368
369 coap_resource_t *r;
370
371 /* Create a resource to return general information */
372 r = coap_resource_init(NULL, 0);
373 coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_index);
374
375 /* Document resource for '.well-known/core' request */
376 coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
377 coap_add_attr(r, coap_make_str_const("title"),
378 coap_make_str_const("\"General Info\""), 0);
379
380 coap_add_resource(ctx, r);
381
382 /* Create a resource to return return or update time */
383 r = coap_resource_init(coap_make_str_const("time"),
384 COAP_RESOURCE_FLAGS_NOTIFY_CON);
385 coap_resource_set_get_observable(r, 1);
386 coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_time);
387 coap_register_request_handler(r, COAP_REQUEST_PUT, hnd_put_time);
388 coap_register_request_handler(r, COAP_REQUEST_DELETE, hnd_delete_time);
389
390 /* Document resource for 'time' request */
391 coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
392 coap_add_attr(r, coap_make_str_const("title"),
393 coap_make_str_const("\"Internal Clock\""), 0);
394 coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("\"secs\""),
395 0);
396 coap_add_attr(r, coap_make_str_const("if"), coap_make_str_const("\"clock\""),
397 0);
398
399 coap_add_resource(ctx, r);
400
401 }
402
403 Dynamic Resources Set Up
404
405 #include <coap3/coap.h>
406
407 /* Regular DELETE handler - used by resources created by the
408 * Unknown Resource PUT handler */
409
410 static void
411 hnd_delete(coap_resource_t *resource, coap_session_t *session,
412 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
413 /* Remove (void) definition if variable is used */
414 (void)session;
415 (void)request;
416 (void)query;
417 (void)response;
418
419 /* .. code .. */
420
421 /* Dynamic resource no longer required - delete it */
422 coap_delete_resource(NULL, resource);
423
424 coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
425 }
426
427 /* Regular GET handler - used by resources created by the
428 * Unknown Resource PUT handler */
429
430 static void
431 hnd_get(coap_resource_t *resource, coap_session_t *session,
432 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
433
434 coap_str_const_t *get_uri_path;
435
436 /* Remove (void) definition if variable is used */
437 (void)resource;
438 (void)session;
439 (void)request;
440 (void)query;
441
442 /*
443 * Get the specific resouce being requested to determine what the response is
444 * The uri_path string is a const pointer
445 */
446
447 get_uri_path = coap_resource_get_uri_path(resource);
448
449 /* .. code .. */
450
451 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
452 }
453
454 /* Regular PUT handler - used by resources created by the
455 * Unknown Resource PUT handler */
456
457 static void
458 hnd_put(coap_resource_t *resource, coap_session_t *session,
459 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
460 /* Remove (void) definition if variable is used */
461 (void)resource;
462 (void)session;
463 (void)query;
464
465 coap_string_t *put_uri_path;
466 size_t length;
467 const uint8_t *data;
468 size_t offset;
469 size_t total;
470 int new_resource = 0;
471
472 /* get the uri_path */
473 put_uri_path = coap_get_uri_path(request);
474 if (!put_uri_path) {
475 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
476 return;
477 }
478 coap_get_data_large(request, &length, &data, &offset, &total);
479
480 /* .. code .. */
481
482 /* Need to do this as coap_get_uri_path() created it */
483 coap_delete_string(put_uri_path);
484
485 if (length + offset < total)
486 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTINUE);
487 else if (new_resource)
488 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CREATED);
489 else
490 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
491 }
492
493 static int
494 check_url_fn(coap_string_t *uri_path, uint8_t code) {
495 /* Remove (void) definition if variable is used */
496 (void)uri_path;
497 (void)code;
498
499 /* Code to determine whether the uri is valid or not */
500
501 return 1;
502 }
503
504 /* Unknown Resource PUT handler */
505
506 static void
507 hnd_put_unknown(coap_resource_t *resource, coap_session_t *session,
508 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
509 /* Remove (void) definition if variable is used */
510 (void)resource;
511 coap_pdu_code_t req_code = coap_pdu_get_code(request);
512
513 coap_resource_t *r;
514 coap_string_t *uri_path;
515
516 /* get the uri_path - which will get used by coap_resource_init() */
517 uri_path = coap_get_uri_path(request);
518 if (!uri_path) {
519 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
520 return;
521 }
522
523 /* Check if new URI Path is valid */
524 if (!check_url_fn (uri_path, req_code)) {
525 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
526 coap_delete_string(uri_path);
527 return;
528 }
529
530 /*
531 * Create a resource to handle the new URI
532 * uri_path will get deleted when the resource is removed
533 */
534 r = coap_resource_init((coap_str_const_t*)uri_path,
535 COAP_RESOURCE_FLAGS_RELEASE_URI | COAP_RESOURCE_FLAGS_NOTIFY_NON);
536 coap_register_request_handler(r, COAP_REQUEST_PUT, hnd_put);
537 coap_register_request_handler(r, COAP_REQUEST_DELETE, hnd_delete);
538 /* We possibly want to Observe the GETs */
539 coap_resource_set_get_observable(r, 1);
540 coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get);
541 coap_add_resource(coap_session_get_context(session), r);
542
543 /* Do the PUT for this first call */
544 hnd_put(r, session, request, query, response);
545
546 return;
547
548 }
549
550 /* Initialize single Unknown Resource PUT handler */
551
552 static void
553 init_resources(coap_context_t *ctx) {
554
555 coap_resource_t *r;
556
557 /* Create a resource to handle PUTs to unknown URIs */
558 r = coap_resource_unknown_init2(hnd_put_unknown, 0);
559 /*
560 * Additional handlers can be added - for example
561 * coap_register_request_handler(r, COAP_REQUEST_POST, hnd_post_unknown);
562 * coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_unknown);
563 * coap_register_request_handler(r, COAP_REQUEST_DELETE, hnd_delete_unknown);
564 */
565 coap_add_resource(ctx, r);
566
567 }
568
570 coap_attribute(3), coap_context(3), coap_handler(3) and coap_observe(3)
571
573 See "RFC7252: The Constrained Application Protocol (CoAP)" for further
574 information.
575
577 Please report bugs on the mailing list for libcoap:
578 libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
579 https://github.com/obgm/libcoap/issues
580
582 The libcoap project <libcoap-developers@lists.sourceforge.net>
583
584
585
586coap_resource 4.3.1 01/19/2023 COAP_RESOURCE(3)