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