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