• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * coap_resource.h -- generic resource handling
3  *
4  * Copyright (C) 2010,2011,2014-2023 Olaf Bergmann <bergmann@tzi.org>
5  *
6  * SPDX-License-Identifier: BSD-2-Clause
7  *
8  * This file is part of the CoAP library libcoap. Please see README for terms
9  * of use.
10  */
11 
12 /**
13  * @file coap_resource.h
14  * @brief Generic resource handling
15  */
16 
17 #ifndef COAP_RESOURCE_H_
18 #define COAP_RESOURCE_H_
19 
20 #ifndef COAP_RESOURCE_CHECK_TIME
21 /** The interval in seconds to check if resources have changed. */
22 #define COAP_RESOURCE_CHECK_TIME 2
23 #endif /* COAP_RESOURCE_CHECK_TIME */
24 
25 /**
26  * @ingroup application_api
27  * @defgroup coap_resource Resource Configuraton
28  * API for setting up resources
29  * @{
30  */
31 
32 /**
33  * Definition of message handler function
34  */
35 typedef void (*coap_method_handler_t)
36 (coap_resource_t *,
37  coap_session_t *,
38  const coap_pdu_t * /* request */,
39  const coap_string_t * /* query string */,
40  coap_pdu_t * /* response */);
41 
42 #define COAP_ATTR_FLAGS_RELEASE_NAME  0x1
43 #define COAP_ATTR_FLAGS_RELEASE_VALUE 0x2
44 
45 /** The URI passed to coap_resource_init() is free'd by coap_delete_resource(). */
46 #define COAP_RESOURCE_FLAGS_RELEASE_URI 0x1
47 
48 /**
49  * Observe Notifications will be sent non-confirmable by default. RFC 7641
50  * Section 4.5
51  * https://rfc-editor.org/rfc/rfc7641#section-4.5
52  * Libcoap will always send every fifth packet as confirmable.
53  */
54 #define COAP_RESOURCE_FLAGS_NOTIFY_NON  0x0
55 
56 /**
57  * Observe Notifications will be sent confirmable. RFC 7641 Section 4.5
58  * https://rfc-editor.org/rfc/rfc7641#section-4.5
59  */
60 #define COAP_RESOURCE_FLAGS_NOTIFY_CON  0x2
61 
62 /**
63  * Observe Notifications will always be sent non-confirmable. This is in
64  * violation of RFC 7641 Section 4.5
65  * https://rfc-editor.org/rfc/rfc7641#section-4.5
66  * but required by the DOTS signal channel protocol which needs to operate in
67  * lossy DDoS attack environments.
68  * https://rfc-editor.org/rfc/rfc8782#section-4.4.2.1
69  */
70 #define COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS  0x4
71 
72 /**
73  * This resource has support for multicast requests.
74  * https://rfc-editor.org/rfc/rfc7252#section-11.3
75  * https://rfc-editor.org/rfc/rfc7390#section-2.8
76  * https://datatracker.ietf.org/doc/html/draft-ietf-core-groupcomm-bis-06.txt#section-3.6
77  * Note: ".well-known/core" always supports multicast.
78  * Note: Only tested if coap_mcast_per_resource() has been called.
79  */
80 #define COAP_RESOURCE_FLAGS_HAS_MCAST_SUPPORT 0x8
81 
82 /**
83  * Disable libcoap library from adding in delays to multicast requests before
84  * releasing the response back to the client.  It is then the responsibility of
85  * the app to delay the responses for multicast requests.
86  * https://rfc-editor.org/rfc/rfc7252#section-8.2
87  * https://rfc-editor.org/rfc/rfc7390#section-2.8
88  * https://datatracker.ietf.org/doc/html/draft-ietf-core-groupcomm-bis-06.txt#section-3.6
89  * Note: Only tested if coap_mcast_per_resource() has been called.
90  */
91 #define COAP_RESOURCE_FLAGS_LIB_DIS_MCAST_DELAYS 0x10
92 
93 /**
94  * Enable libcoap library suppression of 205 multicast responses that are empty
95  * (overridden by RFC7969 No-Response option) for multicast requests.
96  * https://rfc-editor.org/rfc/rfc7390#section-2.7
97  * https://datatracker.ietf.org/doc/html/draft-ietf-core-groupcomm-bis-06.txt#section-3.1.2
98  * Note: Only tested if coap_mcast_per_resource() has been called.
99  */
100 #define COAP_RESOURCE_FLAGS_LIB_ENA_MCAST_SUPPRESS_2_05 0x20
101 
102 /**
103  * Enable libcoap library suppressing 2.xx multicast responses (overridden by
104  * RFC7969 No-Response option) for multicast requests.
105  * https://rfc-editor.org/rfc/rfc7390#section-2.7
106  * https://datatracker.ietf.org/doc/html/draft-ietf-core-groupcomm-bis-06.txt#section-3.1.2
107  * Note: Only tested if coap_mcast_per_resource() has been called.
108  */
109 #define COAP_RESOURCE_FLAGS_LIB_ENA_MCAST_SUPPRESS_2_XX 0x40
110 
111 /**
112  * Disable libcoap library suppressing 4.xx multicast responses (overridden by
113  * RFC7969 No-Response option) for multicast requests.
114  * https://rfc-editor.org/rfc/rfc7390#section-2.7
115  * https://datatracker.ietf.org/doc/html/draft-ietf-core-groupcomm-bis-06.txt#section-3.1.2
116  * Note: Only tested if coap_mcast_per_resource() has been called.
117  */
118 #define COAP_RESOURCE_FLAGS_LIB_DIS_MCAST_SUPPRESS_4_XX 0x80
119 
120 /**
121  * Disable libcoap library suppressing 5.xx multicast responses (overridden by
122  * RFC7969 No-Response option) for multicast requests.
123  * https://rfc-editor.org/rfc/rfc7390#section-2.7
124  * https://datatracker.ietf.org/doc/html/draft-ietf-core-groupcomm-bis-06.txt#section-3.1.2
125  * Note: Only tested if coap_mcast_per_resource() has been called.
126  */
127 #define COAP_RESOURCE_FLAGS_LIB_DIS_MCAST_SUPPRESS_5_XX 0x100
128 
129 #define COAP_RESOURCE_FLAGS_MCAST_LIST \
130   (COAP_RESOURCE_FLAGS_HAS_MCAST_SUPPORT | \
131    COAP_RESOURCE_FLAGS_LIB_DIS_MCAST_DELAYS | \
132    COAP_RESOURCE_FLAGS_LIB_ENA_MCAST_SUPPRESS_2_05 | \
133    COAP_RESOURCE_FLAGS_LIB_ENA_MCAST_SUPPRESS_2_XX | \
134    COAP_RESOURCE_FLAGS_LIB_DIS_MCAST_SUPPRESS_4_XX | \
135    COAP_RESOURCE_FLAGS_LIB_DIS_MCAST_SUPPRESS_5_XX)
136 
137 /**
138  * Force all large traffic to this resource to be presented as a single body
139  * to the request handler.
140  */
141 #define COAP_RESOURCE_FLAGS_FORCE_SINGLE_BODY 0x200
142 
143 /**
144  * Define this resource as an OSCORE enabled access only.
145  */
146 #define COAP_RESOURCE_FLAGS_OSCORE_ONLY 0x400
147 
148 /**
149  * Creates a new resource object and initializes the link field to the string
150  * @p uri_path. This function returns the new coap_resource_t object.
151  *
152  * If the string is going to be freed off by coap_delete_resource() when
153  * COAP_RESOURCE_FLAGS_RELEASE_URI is set in @p flags, then either the 's'
154  * variable of coap_str_const_t has to point to constant text, or point to data
155  * within the allocated coap_str_const_t parameter.
156  *
157  * @param uri_path The string URI path of the new resource. The leading '/' is
158  *                 not normally required - e.g. just "full/path/for/resource".
159  * @param flags    Flags for memory management, observe handling and multicast
160  *                 support, comprising of zero or more COAP_RESOURCE_FLAGS_*
161  *                 ored together.
162  *
163  *                 If flags does not have COAP_RESOURCE_FLAGS_NOTIFY_CON
164  *                 set, then COAP_RESOURCE_FLAGS_NOTIFY_NON is assumed and
165  *                 observe notifications will be sent as non-confirmable,
166  *                 except that every 5th notification will be confirmable.
167  *
168  *                 If COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS is set,
169  *                 observe notifications will always be sent
170  *                 non-confirmable.
171  *
172  * @return         A pointer to the new object or @c NULL on error.
173  */
174 coap_resource_t *coap_resource_init(coap_str_const_t *uri_path,
175                                     int flags);
176 
177 /**
178  * Creates a new resource object for the unknown resource handler with support
179  * for PUT.
180  *
181  * In the same way that additional handlers can be added to the resource
182  * created by coap_resource_init() by using coap_register_request_handler(),
183  * POST, GET, DELETE etc. handlers can be added to this resource. It is the
184  * responsibility of the application to manage the unknown resources by either
185  * creating new resources with coap_resource_init() (which should have a
186  * DELETE handler specified for the resource removal) or by maintaining an
187  * active resource list.
188  *
189  * Note: There can only be one unknown resource handler per context - attaching
190  *       a new one overrides the previous definition.
191  *
192  * Note: It is not possible to observe the unknown resource with a GET request
193  *       - a separate resource needs to be created by the PUT (or POST)
194  *       handler, and make that resource observable.
195  *
196  * This function returns the new coap_resource_t object.
197  *
198  * @param put_handler The PUT handler to register with @p resource for
199  *                    unknown Uri-Path.
200  *
201  * @return       A pointer to the new object or @c NULL on error.
202  */
203 coap_resource_t *coap_resource_unknown_init(coap_method_handler_t put_handler);
204 
205 /**
206  * Creates a new resource object for the unknown resource handler with support
207  * for PUT and configurable control over multicast requests packets.
208  *
209  * In the same way that additional handlers can be added to the resource
210  * created by coap_resource_init() by using coap_register_request_handler(),
211  * POST, GET, DELETE etc. handlers can be added to this resource. It is the
212  * responsibility of the application to manage the unknown resources by either
213  * creating new resources with coap_resource_init() (which should have a
214  * DELETE handler specified for the resource removal) or by maintaining an
215  * active resource list.
216  *
217  * Note: There can only be one unknown resource handler per context - attaching
218  *       a new one overrides the previous definition.
219  *
220  * Note: It is not possible to observe the unknown resource with a GET request
221  *       - a separate resource needs to be created by the PUT (or POST)
222  *       handler, and make that resource observable.
223  *
224  * This function returns the new coap_resource_t object.
225  *
226  * @param put_handler The PUT handler to register with @p resource for
227  *                    unknown Uri-Path.
228  * @param flags Zero or more COAP_RESOURCE_FLAGS_*MCAST* ored together to
229  *              indicate what to do with multicast packets.
230  *
231  * @return       A pointer to the new object or @c NULL on error.
232  */
233 coap_resource_t *coap_resource_unknown_init2(coap_method_handler_t put_handler,
234                                              int flags);
235 
236 /**
237  * Creates a new resource object for handling proxy URIs.
238  * This function returns the new coap_resource_t object.
239  *
240  * Note: There can only be one proxy resource handler per context - attaching
241  *       a new one overrides the previous definition.
242  *
243  * @param handler The PUT/POST/GET etc. handler that handles all request types.
244  * @param host_name_count The number of provided host_name_list entries. A
245  *                        minimum of 1 must be provided.
246  * @param host_name_list Array of depth host_name_count names that this proxy
247  *                       is known by.
248  *
249  * @return         A pointer to the new object or @c NULL on error.
250  */
251 coap_resource_t *coap_resource_proxy_uri_init(coap_method_handler_t handler,
252                                               size_t host_name_count, const char *host_name_list[]);
253 
254 /**
255  * Creates a new resource object for handling proxy URIs with configurable
256  * control over multicast request packets.
257  * This function returns the new coap_resource_t object.
258  *
259  * Note: There can only be one proxy resource handler per context - attaching
260  *       a new one overrides the previous definition.
261  *
262  * @param handler The PUT/POST/GET etc. handler that handles all request types.
263  * @param host_name_count The number of provided host_name_list entries. A
264  *                        minimum of 1 must be provided.
265  * @param host_name_list Array of depth host_name_count names that this proxy
266  *                       is known by.
267  * @param flags Zero or more COAP_RESOURCE_FLAGS_*MCAST* ored together to
268  *              indicate what to do with multicast packets.
269  *
270  * @return         A pointer to the new object or @c NULL on error.
271  */
272 coap_resource_t *coap_resource_proxy_uri_init2(coap_method_handler_t handler,
273                                                size_t host_name_count,
274                                                const char *host_name_list[],
275                                                int flags);
276 
277 /**
278  * Returns the resource identified by the unique string @p uri_path. If no
279  * resource was found, this function returns @c NULL.
280  *
281  * @param context  The context to look for this resource.
282  * @param uri_path  The unique string uri of the resource.
283  *
284  * @return         A pointer to the resource or @c NULL if not found.
285  */
286 coap_resource_t *coap_get_resource_from_uri_path(coap_context_t *context,
287                                                  coap_str_const_t *uri_path);
288 
289 /**
290  * Get the uri_path from a @p resource.
291  *
292  * @param resource The CoAP resource to check.
293  *
294  * @return         The uri_path if it exists or @c NULL otherwise.
295  */
296 coap_str_const_t *coap_resource_get_uri_path(coap_resource_t *resource);
297 
298 /**
299  * Sets the notification message type of resource @p resource to given
300  * @p mode
301 
302  * @param resource The resource to update.
303  * @param mode     Must be one of @c COAP_RESOURCE_FLAGS_NOTIFY_NON
304  *                 or @c COAP_RESOURCE_FLAGS_NOTIFY_CON.
305  */
306 void coap_resource_set_mode(coap_resource_t *resource, int mode);
307 
308 /**
309  * Sets the user_data. The user_data is exclusively used by the library-user
310  * and can be used as user defined context in the handler functions.
311  *
312  * @param resource Resource to attach the data to
313  * @param data     Data to attach to the user_data field. This pointer is
314  *                 only used for storage, the data remains under user control
315  */
316 void coap_resource_set_userdata(coap_resource_t *resource, void *data);
317 
318 /**
319  * Gets the user_data. The user_data is exclusively used by the library-user
320  * and can be used as context in the handler functions.
321  *
322  * @param resource Resource to retrieve the user_data from
323  *
324  * @return        The user_data pointer
325  */
326 void *coap_resource_get_userdata(coap_resource_t *resource);
327 
328 /**
329  * Definition of release resource user_data callback function
330  */
331 typedef void (*coap_resource_release_userdata_handler_t)(void *user_data);
332 
333 /**
334  * Defines the context wide callback to use to when the resource is deleted
335  * to release the data held in the resource's user_data.
336  *
337  * @param context  The context to associate the release callback with
338  * @param callback The callback to invoke when the resource is deleted or NULL
339  *
340  */
341 void coap_resource_release_userdata_handler(coap_context_t *context,
342                                             coap_resource_release_userdata_handler_t callback);
343 
344 /**
345  * Registers the given @p resource for @p context. The resource must have been
346  * created by coap_resource_init() or coap_resource_unknown_init(), the
347  * storage allocated for the resource will be released by coap_delete_resource().
348  *
349  * @param context  The context to use.
350  * @param resource The resource to store.
351  */
352 void coap_add_resource(coap_context_t *context, coap_resource_t *resource);
353 
354 /**
355  * Deletes a resource identified by @p resource. The storage allocated for that
356  * resource is freed, and removed from the context.
357  *
358  * @param context  This parameter is ignored, but kept for backward
359  *                 compatibility.
360  * @param resource The resource to delete.
361  *
362  * @return         @c 1 if the resource was found (and destroyed),
363  *                 @c 0 otherwise.
364  */
365 int coap_delete_resource(coap_context_t *context, coap_resource_t *resource);
366 
367 /**
368  * Registers the specified @p handler as message handler for the request type
369  * @p method
370  *
371  * @deprecated use coap_register_request_handler() instead.
372  *
373  * @param resource The resource for which the handler shall be registered.
374  * @param method   The CoAP request method to handle.
375  * @param handler  The handler to register with @p resource.
376  */
377 void coap_register_handler(coap_resource_t *resource,
378                            coap_request_t method,
379                            coap_method_handler_t handler);
380 
381 /**
382  * Registers the specified @p handler as message handler for the request type
383  * @p method
384  *
385  * @param resource The resource for which the handler shall be registered.
386  * @param method   The CoAP request method to handle.
387  * @param handler  The handler to register with @p resource.
388  */
389 void coap_register_request_handler(coap_resource_t *resource,
390                                    coap_request_t method,
391                                    coap_method_handler_t handler);
392 
393 /**
394  * Registers a new attribute with the given @p resource. As the
395  * attribute's coap_str_const_ fields will point to @p name and @p value the
396  * caller must ensure that these pointers are valid during the
397  * attribute's lifetime.
398 
399  * If the @p name and/or @p value string is going to be freed off at attribute
400  * removal time by the setting of COAP_ATTR_FLAGS_RELEASE_NAME or
401  * COAP_ATTR_FLAGS_RELEASE_VALUE in @p flags, then either the 's'
402  * variable of coap_str_const_t has to point to constant text, or point to data
403  * within the allocated coap_str_const_t parameter.
404  *
405  * @param resource The resource to register the attribute with.
406  * @param name     The attribute's name as a string.
407  * @param value    The attribute's value as a string or @c NULL if none.
408  * @param flags    Flags for memory management (in particular release of
409  *                 memory). Possible values:@n
410  *
411  *                 COAP_ATTR_FLAGS_RELEASE_NAME
412  *                  If this flag is set, the name passed to
413  *                  coap_add_attr_release() is free'd
414  *                  when the attribute is deleted@n
415  *
416  *                 COAP_ATTR_FLAGS_RELEASE_VALUE
417  *                  If this flag is set, the value passed to
418  *                  coap_add_attr_release() is free'd
419  *                  when the attribute is deleted@n
420  *
421  * @return         A pointer to the new attribute or @c NULL on error.
422  */
423 coap_attr_t *coap_add_attr(coap_resource_t *resource,
424                            coap_str_const_t *name,
425                            coap_str_const_t *value,
426                            int flags);
427 
428 /**
429  * Returns @p resource's coap_attr_t object with given @p name if found, @c NULL
430  * otherwise.
431  *
432  * @param resource The resource to search for attribute @p name.
433  * @param name     Name of the requested attribute as a string.
434  * @return         The first attribute with specified @p name or @c NULL if none
435  *                 was found.
436  */
437 coap_attr_t *coap_find_attr(coap_resource_t *resource,
438                             coap_str_const_t *name);
439 
440 /**
441  * Returns @p attribute's value.
442  *
443  * @param attribute Pointer to attribute.
444  *
445  * @return Attribute's value or @c NULL.
446  */
447 coap_str_const_t *coap_attr_get_value(coap_attr_t *attribute);
448 
449 /**
450  * Status word to encode the result of conditional print or copy operations such
451  * as coap_print_link(). The lower 28 bits of coap_print_status_t are used to
452  * encode the number of characters that has actually been printed, bits 28 to 31
453  * encode the status.  When COAP_PRINT_STATUS_ERROR is set, an error occurred
454  * during output. In this case, the other bits are undefined.
455  * COAP_PRINT_STATUS_TRUNC indicates that the output is truncated, i.e. the
456  * printing would have exceeded the current buffer.
457  */
458 typedef unsigned int coap_print_status_t;
459 
460 #define COAP_PRINT_STATUS_MASK  0xF0000000u
461 #define COAP_PRINT_OUTPUT_LENGTH(v) ((v) & ~COAP_PRINT_STATUS_MASK)
462 #define COAP_PRINT_STATUS_ERROR 0x80000000u
463 #define COAP_PRINT_STATUS_TRUNC 0x40000000u
464 
465 /**
466  * Writes a description of this resource in link-format to given text buffer. @p
467  * len must be initialized to the maximum length of @p buf and will be set to
468  * the number of characters actually written if successful. This function
469  * returns @c 1 on success or @c 0 on error.
470  *
471  * @param resource The resource to describe.
472  * @param buf      The output buffer to write the description to.
473  * @param len      Must be initialized to the length of @p buf and
474  *                 will be set to the length of the printed link description.
475  * @param offset   The offset within the resource description where to
476  *                 start writing into @p buf. This is useful for dealing
477  *                 with the Block2 option. @p offset is updated during
478  *                 output as it is consumed.
479  *
480  * @return If COAP_PRINT_STATUS_ERROR is set, an error occured. Otherwise,
481  *         the lower 28 bits will indicate the number of characters that
482  *         have actually been output into @p buffer. The flag
483  *         COAP_PRINT_STATUS_TRUNC indicates that the output has been
484  *         truncated.
485  */
486 coap_print_status_t coap_print_link(const coap_resource_t *resource,
487                                     unsigned char *buf,
488                                     size_t *len,
489                                     size_t *offset);
490 
491 /** @} */
492 
493 /**
494  * Returns the resource identified by the unique string @p uri_path. If no
495  * resource was found, this function returns @c NULL.
496  *
497  * @param context  The context to look for this resource.
498  * @param uri_path  The unique string uri of the resource.
499  *
500  * @return         A pointer to the resource or @c NULL if not found.
501  */
502 coap_resource_t *coap_get_resource_from_uri_path(coap_context_t *context,
503                                                  coap_str_const_t *uri_path);
504 
505 /**
506  * @deprecated use coap_resource_notify_observers() instead.
507  */
508 COAP_DEPRECATED int coap_resource_set_dirty(coap_resource_t *r,
509                                             const coap_string_t *query);
510 
511 #endif /* COAP_RESOURCE_H_ */
512