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_proxy_uri_init, coap_add_resource, coap_delete_resource,
8       coap_resource_set_mode, coap_resource_set_userdata,
9       coap_resource_get_userdata - Work with CoAP resources
10

SYNOPSIS

12       #include <coap3/coap.h>
13
14       coap_resource_t *coap_resource_init(coap_str_const_t *uri_path, int
15       flags);
16
17       coap_resource_t *coap_resource_unknown_init(coap_method_handler_t
18       put_handler);
19
20       coap_resource_t *coap_resource_proxy_uri_init(coap_method_handler_t
21       proxy_handler, size_t host_name_count, const char *host_name_list[]);
22
23       void coap_add_resource(coap_context_t *context, coap_resource_t
24       *resource);
25
26       int coap_delete_resource(coap_context_t *context, coap_resource_t
27       *resource);
28
29       void coap_resource_set_mode(coap_resource_t *resource, int mode);
30
31       void coap_resource_set_userdata(coap_resource_t *resource, void *data);
32
33       void *coap_resource_get_userdata(coap_resource_t *resource);
34
35       void coap_resource_release_userdata_handler(coap_context_t *context,
36       coap_resource_release_userdata_handler_t callback);
37
38       coap_str_const_t *coap_resource_get_uri_path(coap_resource_t
39       *resource);
40
41       For specific (D)TLS library support, link with -lcoap-3-notls,
42       -lcoap-3-gnutls, -lcoap-3-openssl, -lcoap-3-mbedtls or
43       -lcoap-3-tinydtls. Otherwise, link with -lcoap-3 to get the default
44       (D)TLS library support.
45

DESCRIPTION

47       CoAP Resources on a CoAP Server need to be created and updated etc. The
48       URI in the request packet defines the resource to work with, with
49       possibly the Query referring to a sub-resource.
50
51       When resources are configured on the CoAP server, the URI to match
52       against in the request packet is specified.
53
54       Callback Handlers are then added to the resource to handle the
55       different request methods.
56
57       Adding Attributes allows textual information to be added to the
58       resource which can then be reported back to any client doing a "GET
59       .well-known/core" request.
60
61       If an incoming packet request matches a resource’s URI and Method, then
62       the appropriate callback resource handler is invoked to process the
63       packet which then should update a suitable response packet for sending
64       back to the requester.
65
66       There is support for handling incoming packets where the URI is
67       unknown. This could, for example, happen when a PUT request is trying
68       to create a new resource. It is the responsibility of the unknown
69       resource callback handler to either create a new resource for the URI
70       or just manage things separately.
71
72       CoAP Observe (RFC 7641) is not supported for unknown resources, so a
73       new resource with GET handler must be created by the unknown resource
74       callback handle matching the URI which then can be Observable.
75
76       The coap_resource_init() function returns a newly created resource of
77       type coap_resource_t * . uri_path specifies the uri string path to
78       match against. flags is used to define whether the resource is of type
79       Confirmable Message or Non-Confirmable Message for any "observe"
80       responses. See coap_observe(3). flags can be one of the following
81       definitions or’ed together.
82
83
84       COAP_RESOURCE_FLAGS_NOTIFY_NON          Set the notification
85                                               message type to
86                                               non-confirmable for any
87                                               trigggered "observe"
88                                               responses with type set to
89                                               confirmable every 5
90                                               packets as required by
91                                               RFC7641 section-4.5.
92
93       COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS   Set the notification
94                                               message type to always
95                                               non-confirmable for any
96                                               trigggered "observe"
97                                               responses. This should
98                                               only be used if a upper
99                                               layer protocol requires
100                                               it.
101
102       COAP_RESOURCE_FLAGS_NOTIFY_CON          Set the notification
103                                               message type to
104                                               confirmable for any
105                                               trigggered "observe"
106                                               responses.
107
108       COAP_RESOURCE_FLAGS_RELEASE_URI         Free off the
109                                               coap_str_const_t for
110                                               uri_path when the resource
111                                               is deleted.
112
113
114       NOTE: uri_path, if not 7 bit readable ASCII, binary bytes must be hex
115       encoded according to the rules defined in RFC3968 Section 2.1.
116
117       The coap_resource_unknown_init() function returns a newly created
118       resource of type coap_resource_t *. put_handler is automatically added
119       to the resource to handle PUT requests to resources that are unknown.
120       Additional handlers can be added to this resource if required.
121
122       The coap_resource_proxy_uri_init() function returns a newly created
123       resource of type coap_resource_t *. proxy_handler is automatically
124       added to the resource to handle PUT/POST/GET etc. requests that use the
125       Proxy-Uri: option. There is no need to add explicit request type
126       handlers. One or more names by which the proxy is known by (IP address,
127       DNS name etc.) must be supplied in the array defined by
128       host_name_list[] which has a count of host_name_count. This is used to
129       check whether the current endpoint is the proxy target address.
130
131       The coap_add_resource() function registers the given resource with the
132       context. The resource must have been created by coap_resource_init(),
133       coap_resource_unknown_init() or coap_resource_proxy_uri_init(). The
134       storage allocated for the resource will be released by
135       coap_delete_resource().
136
137       As the uri_path of the resource has to be unique across all of the
138       resources associated with a context, coap_add_resource() (or
139       coap_add_resource_release()) will delete any previous resource with the
140       same uri_path before adding in the new resource.
141
142       The coap_delete_resource() function deletes a resource identified by
143       resource from context. The storage allocated for that resource is
144       freed, along with any attrigutes associated with the resource.
145
146       The coap_resource_set_mode() changes the notification message type of
147       resource to the given mode which must be one of
148       COAP_RESOURCE_FLAGS_NOTIFY_NON, COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS
149       or COAP_RESOURCE_FLAGS_NOTIFY_CON.
150
151       The coap_resource_set_userdata() function allows a pointer to user data
152       to be associated with a resource that can accessed in any callback that
153       includes resource as a parameter.
154
155       NOTE: data must point to a static, or allocated, block of memory.
156
157       The coap_resource_get_userdata() function obtains the user data pointer
158       from the resource that had previously been set up by
159       coap_resource_set_userdata().
160
161       The coap_resource_release_userdata_handler() function defines the
162       context wide callback handler to call to release the allocated user
163       data that has been added to the resource using
164       coap_resource_set_userdata() when the resource is deleted. callback can
165       be NULL (which is the default) if nothing needs to be freed off.
166
167       The coap_resource_get_uri_path() function is used to obtain the UriPath
168       of the resource definion.
169

RETURN VALUES

171       The coap_resource_init(), coap_resource_unknown_init() and
172       coap_resource_proxy_uri_init() functions return a newly created
173       resource or NULL if there is a malloc failure.
174
175       The coap_delete_resource() function return 0 on failure (resource not
176       found), 1 on success.
177
178       The coap_resource_get_userdata() function returns the value previously
179       set by the coap_resource_set_userdata() function or NULL.
180
181       The coap_resource_get_uri_path() function returns the uri_path or NULL
182       if there was a failure.
183

EXAMPLES

185       Fixed Resources Set Up
186
187           #include <coap3/coap.h>
188
189           #define INDEX "This is an example server using libcoap\n"
190
191           static void
192           hnd_get_index(coap_resource_t *resource, coap_session_t *session,
193           const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
194             unsigned char buf[3];
195             /* Remove (void) definition if variable is used */
196             (void)resource;
197             (void)session;
198             (void)request;
199             (void)query;
200
201             coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
202
203             coap_add_option(response,
204                             COAP_OPTION_CONTENT_TYPE,
205                             coap_encode_var_safe(buf, sizeof(buf),
206                                                  COAP_MEDIATYPE_TEXT_PLAIN),
207                             buf);
208
209             coap_add_option(response,
210                             COAP_OPTION_MAXAGE,
211                             coap_encode_var_safe(buf, sizeof(buf), 0x2ffff), buf);
212
213             coap_add_data(response, strlen(INDEX), (const uint8_t *)INDEX);
214
215             coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
216           }
217
218           static void
219           hnd_delete_time(coap_resource_t *resource, coap_session_t *session,
220           const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
221             /* Remove (void) definition if variable is used */
222             (void)resource;
223             (void)session;
224             (void)request;
225             (void)query;
226
227             /* .. code .. */
228
229             coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
230           }
231
232           static void
233           hnd_get_time(coap_resource_t *resource, coap_session_t *session,
234           const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
235             /* Remove (void) definition if variable is used */
236             (void)resource;
237             (void)session;
238             (void)request;
239             (void)query;
240             (void)response;
241
242             /* .. code .. */
243
244             coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
245           }
246
247           static void
248           hnd_put_time(coap_resource_t *resource, coap_session_t *session,
249           const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
250             /* Remove (void) definition if variable is used */
251             (void)resource;
252             (void)session;
253             (void)request;
254             (void)query;
255             (void)response;
256
257             /* .. code .. */
258
259             coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
260           }
261
262           static void
263           init_resources(coap_context_t *ctx) {
264
265             coap_resource_t *r;
266
267             /* Create a resource to return general information */
268             r = coap_resource_init(NULL, 0);
269             coap_register_handler(r, COAP_REQUEST_GET, hnd_get_index);
270
271             /* Document resource for '.well-known/core' request */
272             coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
273             coap_add_attr(r, coap_make_str_const("title"),
274                           coap_make_str_const("\"General Info\""), 0);
275
276             coap_add_resource(ctx, r);
277
278             /* Create a resource to return return or update time */
279             r = coap_resource_init(coap_make_str_const("time"),
280                                    COAP_RESOURCE_FLAGS_NOTIFY_CON);
281             coap_resource_set_get_observable(r, 1);
282             coap_register_handler(r, COAP_REQUEST_GET, hnd_get_time);
283             coap_register_handler(r, COAP_REQUEST_PUT, hnd_put_time);
284             coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_time);
285
286             /* Document resource for 'time' request */
287             coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
288             coap_add_attr(r, coap_make_str_const("title"),
289                           coap_make_str_const("\"Internal Clock\""), 0);
290             coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("\"secs\""),
291                           0);
292             coap_add_attr(r, coap_make_str_const("if"), coap_make_str_const("\"clock\""),
293                           0);
294
295             coap_add_resource(ctx, r);
296
297           }
298
299       Dynamic Resources Set Up
300
301           #include <coap3/coap.h>
302
303           /* Regular DELETE handler - used by resources created by the
304            * Unknown Resource PUT handler */
305
306           static void
307           hnd_delete(coap_resource_t *resource, coap_session_t *session,
308           const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
309             /* Remove (void) definition if variable is used */
310             (void)session;
311             (void)request;
312             (void)query;
313             (void)response;
314
315             /* .. code .. */
316
317             /* Dynamic resource no longer required - delete it */
318             coap_delete_resource(coap_session_get_context(session), resource);
319
320             coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
321           }
322
323           /* Regular GET handler - used by resources created by the
324            * Unknown Resource PUT handler */
325
326           static void
327           hnd_get(coap_resource_t *resource, coap_session_t *session,
328           const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
329
330             coap_str_const_t *get_uri_path;
331             /* Remove (void) definition if variable is used */
332             (void)resource;
333             (void)session;
334             (void)request;
335             (void)query;
336             (void)response;
337
338             /*
339              * request will be NULL if an Observe triggered request, so the uri_path,
340              * if needed, must be abstracted from the resource.
341              * The uri_path string is a const pointer
342              */
343
344             get_uri_path = coap_resource_get_uri_path(resource);
345
346             /* .. code .. */
347
348             coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
349           }
350
351           /* Regular PUT handler - used by resources created by the
352            * Unknown Resource PUT handler */
353
354           static void
355           hnd_put(coap_resource_t *resource, coap_session_t *session,
356           const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
357             /* Remove (void) definition if variable is used */
358             (void)resource;
359             (void)session;
360             (void)query;
361
362             coap_string_t *put_uri_path;
363             size_t length;
364             const uint8_t *data;
365             size_t offset;
366             size_t total;
367             int new_resource = 0;
368
369             /* get the uri_path */
370             put_uri_path = coap_get_uri_path(request);
371             if (!put_uri_path) {
372               coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
373               return;
374             }
375             coap_get_data_large(request, &length, &data, &offset, &total);
376
377             /* .. code .. */
378
379             /* Need to do this as coap_get_uri_path() created it */
380             coap_delete_string(put_uri_path);
381
382             if (length + offset < total)
383               coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTINUE);
384             else if (new_resource)
385               coap_pdu_set_code(response, COAP_RESPONSE_CODE_CREATED);
386             else
387               coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
388           }
389
390           static int
391           check_url_fn(coap_string_t *uri_path, uint8_t code) {
392             /* Remove (void) definition if variable is used */
393             (void)uri_path;
394             (void)code;
395
396             /* Code to determine whether the uri is valid or not */
397
398             return 1;
399           }
400
401           /* Unknown Resource PUT handler */
402
403           static void
404           hnd_unknown_put(coap_resource_t *resource, coap_session_t *session,
405           const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
406             /* Remove (void) definition if variable is used */
407             (void)resource;
408             coap_pdu_code_t req_code = coap_pdu_get_code(request);
409
410             coap_resource_t *r;
411             coap_string_t *uri_path;
412
413             /* get the uri_path - which will get used by coap_resource_init() */
414             uri_path = coap_get_uri_path(request);
415             if (!uri_path) {
416               coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
417               return;
418             }
419
420             /* Check if new URI Path is valid */
421             if (!check_url_fn (uri_path, req_code)) {
422               coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
423               coap_delete_string(uri_path);
424               return;
425             }
426
427             /*
428              * Create a resource to handle the new URI
429              * uri_path will get deleted when the resource is removed
430              */
431             r = coap_resource_init((coap_str_const_t*)uri_path,
432                   COAP_RESOURCE_FLAGS_RELEASE_URI | COAP_RESOURCE_FLAGS_NOTIFY_NON);
433             coap_register_handler(r, COAP_REQUEST_PUT, hnd_put);
434             coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete);
435             /* We possibly want to Observe the GETs */
436             coap_resource_set_get_observable(r, 1);
437             coap_register_handler(r, COAP_REQUEST_GET, hnd_get);
438             coap_add_resource(coap_session_get_context(session), r);
439
440             /* Do the PUT for this first call */
441             hnd_put(r, session, request, query, response);
442
443             return;
444
445           }
446
447           /* Initialize single Unknown Resource PUT handler */
448
449           static void
450           init_resources(coap_context_t *ctx) {
451
452             coap_resource_t *r;
453
454             /* Create a resource to handle PUTs to unknown URIs */
455             r = coap_resource_unknown_init(hnd_unknown_put);
456             /*
457              * Additional handlers can be added - for example
458              *  coap_register_handler(r, COAP_REQUEST_POST, hnd_post_unknown);
459              *  coap_register_handler(r, COAP_REQUEST_GET, hnd_get_unknown);
460              *  coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_unknown);
461              */
462             coap_add_resource(ctx, r);
463
464           }
465

SEE ALSO

467       coap_attribute(3), coap_context(3), coap_observe(3) and coap_handler(3)
468

FURTHER INFORMATION

470       See "RFC7252: The Constrained Application Protocol (CoAP)" for further
471       information.
472

BUGS

474       Please report bugs on the mailing list for libcoap:
475       libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
476       https://github.com/obgm/libcoap/issues
477

AUTHORS

479       The libcoap project <libcoap-developers@lists.sourceforge.net>
480
481
482
483coap_resource 4.3.0               07/22/2021                  COAP_RESOURCE(3)
Impressum