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

NAME

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

SYNOPSIS

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

DESCRIPTION

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

FUNCTIONS

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

RETURN VALUES

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

EXAMPLES

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

SEE ALSO

570       coap_attribute(3), coap_context(3), coap_handler(3) and coap_observe(3)
571

FURTHER INFORMATION

573       See "RFC7252: The Constrained Application Protocol (CoAP)" for further
574       information.
575

BUGS

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

AUTHORS

582       The libcoap project <libcoap-developers@lists.sourceforge.net>
583
584
585
586coap_resource 4.3.1               01/19/2023                  COAP_RESOURCE(3)
Impressum