mirror of
				https://github.com/0xFEEDC0DE64/arduino-esp32.git
				synced 2025-10-30 21:51:40 +01:00 
			
		
		
		
	
		
			
	
	
		
			409 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			409 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * resource.h -- generic resource handling | ||
|  |  * | ||
|  |  * Copyright (C) 2010,2011,2014,2015 Olaf Bergmann <bergmann@tzi.org> | ||
|  |  * | ||
|  |  * This file is part of the CoAP library libcoap. Please see README for terms | ||
|  |  * of use. | ||
|  |  */ | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * @file resource.h | ||
|  |  * @brief Generic resource handling | ||
|  |  */ | ||
|  | 
 | ||
|  | #ifndef _COAP_RESOURCE_H_
 | ||
|  | #define _COAP_RESOURCE_H_
 | ||
|  | 
 | ||
|  | # include <assert.h>
 | ||
|  | 
 | ||
|  | #ifndef COAP_RESOURCE_CHECK_TIME
 | ||
|  | /** The interval in seconds to check if resources have changed. */ | ||
|  | #define COAP_RESOURCE_CHECK_TIME 2
 | ||
|  | #endif /* COAP_RESOURCE_CHECK_TIME */
 | ||
|  | 
 | ||
|  | #ifdef COAP_RESOURCES_NOHASH
 | ||
|  | #  include "utlist.h"
 | ||
|  | #else
 | ||
|  | #  include "uthash.h"
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #include "hashkey.h"
 | ||
|  | #include "async.h"
 | ||
|  | #include "str.h"
 | ||
|  | #include "pdu.h"
 | ||
|  | #include "net.h"
 | ||
|  | #include "subscribe.h"
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Definition of message handler function (@sa coap_resource_t). | ||
|  |  */ | ||
|  | typedef void (*coap_method_handler_t) | ||
|  |   (coap_context_t  *, | ||
|  |    struct coap_resource_t *, | ||
|  |    const coap_endpoint_t *, | ||
|  |    coap_address_t *, | ||
|  |    coap_pdu_t *, | ||
|  |    str * /* token */, | ||
|  |    coap_pdu_t * /* response */); | ||
|  | 
 | ||
|  | #define COAP_ATTR_FLAGS_RELEASE_NAME  0x1
 | ||
|  | #define COAP_ATTR_FLAGS_RELEASE_VALUE 0x2
 | ||
|  | 
 | ||
|  | typedef struct coap_attr_t { | ||
|  |   struct coap_attr_t *next; | ||
|  |   str name; | ||
|  |   str value; | ||
|  |   int flags; | ||
|  | } coap_attr_t; | ||
|  | 
 | ||
|  | /** The URI passed to coap_resource_init() is free'd by coap_delete_resource(). */ | ||
|  | #define COAP_RESOURCE_FLAGS_RELEASE_URI 0x1
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Notifications will be sent non-confirmable by default. RFC 7641 Section 4.5 | ||
|  |  * https://tools.ietf.org/html/rfc7641#section-4.5
 | ||
|  |  */ | ||
|  | #define COAP_RESOURCE_FLAGS_NOTIFY_NON  0x0
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Notifications will be sent confirmable by default. RFC 7641 Section 4.5 | ||
|  |  * https://tools.ietf.org/html/rfc7641#section-4.5
 | ||
|  |  */ | ||
|  | #define COAP_RESOURCE_FLAGS_NOTIFY_CON  0x2
 | ||
|  | 
 | ||
|  | typedef struct coap_resource_t { | ||
|  |   unsigned int dirty:1;          /**< set to 1 if resource has changed */ | ||
|  |   unsigned int partiallydirty:1; /**< set to 1 if some subscribers have not yet
 | ||
|  |                                   *   been notified of the last change */ | ||
|  |   unsigned int observable:1;     /**< can be observed */ | ||
|  |   unsigned int cacheable:1;      /**< can be cached */ | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * Used to store handlers for the four coap methods @c GET, @c POST, @c PUT, | ||
|  |    * and @c DELETE. coap_dispatch() will pass incoming requests to the handler | ||
|  |    * that corresponds to its request method or generate a 4.05 response if no | ||
|  |    * handler is available. | ||
|  |    */ | ||
|  |   coap_method_handler_t handler[4]; | ||
|  | 
 | ||
|  |   coap_key_t key;                /**< the actual key bytes for this resource */ | ||
|  | 
 | ||
|  | #ifdef COAP_RESOURCES_NOHASH
 | ||
|  |   struct coap_resource_t *next; | ||
|  | #else
 | ||
|  |   UT_hash_handle hh; | ||
|  | #endif
 | ||
|  | 
 | ||
|  |   coap_attr_t *link_attr; /**< attributes to be included with the link format */ | ||
|  |   coap_subscription_t *subscribers;  /**< list of observers for this resource */ | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * Request URI for this resource. This field will point into the static | ||
|  |    * memory. | ||
|  |    */ | ||
|  |   str uri; | ||
|  |   int flags; | ||
|  | 
 | ||
|  | } coap_resource_t; | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Creates a new resource object and initializes the link field to the string | ||
|  |  * of length @p len. This function returns the new coap_resource_t object. | ||
|  |  * | ||
|  |  * @param uri    The URI path of the new resource. | ||
|  |  * @param len    The length of @p uri. | ||
|  |  * @param flags  Flags for memory management (in particular release of memory). | ||
|  |  * | ||
|  |  * @return       A pointer to the new object or @c NULL on error. | ||
|  |  */ | ||
|  | coap_resource_t *coap_resource_init(const unsigned char *uri, | ||
|  |                                     size_t len, int flags); | ||
|  | 
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Sets the notification message type of resource @p r to given | ||
|  |  * @p mode which must be one of @c COAP_RESOURCE_FLAGS_NOTIFY_NON | ||
|  |  * or @c COAP_RESOURCE_FLAGS_NOTIFY_CON. | ||
|  |  */ | ||
|  | static inline void | ||
|  | coap_resource_set_mode(coap_resource_t *r, int mode) { | ||
|  |   r->flags = (r->flags & !COAP_RESOURCE_FLAGS_NOTIFY_CON) | mode; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Registers the given @p resource for @p context. The resource must have been | ||
|  |  * created by coap_resource_init(), the storage allocated for the resource will | ||
|  |  * be released by coap_delete_resource(). | ||
|  |  * | ||
|  |  * @param context  The context to use. | ||
|  |  * @param resource The resource to store. | ||
|  |  */ | ||
|  | void coap_add_resource(coap_context_t *context, coap_resource_t *resource); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Deletes a resource identified by @p key. The storage allocated for that | ||
|  |  * resource is freed. | ||
|  |  * | ||
|  |  * @param context  The context where the resources are stored. | ||
|  |  * @param key      The unique key for the resource to delete. | ||
|  |  * | ||
|  |  * @return         @c 1 if the resource was found (and destroyed), | ||
|  |  *                 @c 0 otherwise. | ||
|  |  */ | ||
|  | int coap_delete_resource(coap_context_t *context, coap_key_t key); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Deletes all resources from given @p context and frees their storage. | ||
|  |  * | ||
|  |  * @param context The CoAP context with the resources to be deleted. | ||
|  |  */ | ||
|  | void coap_delete_all_resources(coap_context_t *context); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Registers a new attribute with the given @p resource. As the | ||
|  |  * attributes str fields will point to @p name and @p val the | ||
|  |  * caller must ensure that these pointers are valid during the | ||
|  |  * attribute's lifetime. | ||
|  |  * | ||
|  |  * @param resource The resource to register the attribute with. | ||
|  |  * @param name     The attribute's name. | ||
|  |  * @param nlen     Length of @p name. | ||
|  |  * @param val      The attribute's value or @c NULL if none. | ||
|  |  * @param vlen     Length of @p val if specified. | ||
|  |  * @param flags    Flags for memory management (in particular release of | ||
|  |  *                 memory). | ||
|  |  * | ||
|  |  * @return         A pointer to the new attribute or @c NULL on error. | ||
|  |  */ | ||
|  | coap_attr_t *coap_add_attr(coap_resource_t *resource, | ||
|  |                            const unsigned char *name, | ||
|  |                            size_t nlen, | ||
|  |                            const unsigned char *val, | ||
|  |                            size_t vlen, | ||
|  |                            int flags); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Returns @p resource's coap_attr_t object with given @p name if found, @c NULL | ||
|  |  * otherwise. | ||
|  |  * | ||
|  |  * @param resource The resource to search for attribute @p name. | ||
|  |  * @param name     Name of the requested attribute. | ||
|  |  * @param nlen     Actual length of @p name. | ||
|  |  * @return         The first attribute with specified @p name or @c NULL if none | ||
|  |  *                 was found. | ||
|  |  */ | ||
|  | coap_attr_t *coap_find_attr(coap_resource_t *resource, | ||
|  |                             const unsigned char *name, | ||
|  |                             size_t nlen); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Deletes an attribute. | ||
|  |  * | ||
|  |  * @param attr Pointer to a previously created attribute. | ||
|  |  * | ||
|  |  */ | ||
|  | void coap_delete_attr(coap_attr_t *attr); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Status word to encode the result of conditional print or copy operations such | ||
|  |  * as coap_print_link(). The lower 28 bits of coap_print_status_t are used to | ||
|  |  * encode the number of characters that has actually been printed, bits 28 to 31 | ||
|  |  * encode the status.  When COAP_PRINT_STATUS_ERROR is set, an error occurred | ||
|  |  * during output. In this case, the other bits are undefined. | ||
|  |  * COAP_PRINT_STATUS_TRUNC indicates that the output is truncated, i.e. the | ||
|  |  * printing would have exceeded the current buffer. | ||
|  |  */ | ||
|  | typedef unsigned int coap_print_status_t; | ||
|  | 
 | ||
|  | #define COAP_PRINT_STATUS_MASK  0xF0000000u
 | ||
|  | #define COAP_PRINT_OUTPUT_LENGTH(v) ((v) & ~COAP_PRINT_STATUS_MASK)
 | ||
|  | #define COAP_PRINT_STATUS_ERROR 0x80000000u
 | ||
|  | #define COAP_PRINT_STATUS_TRUNC 0x40000000u
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Writes a description of this resource in link-format to given text buffer. @p | ||
|  |  * len must be initialized to the maximum length of @p buf and will be set to | ||
|  |  * the number of characters actually written if successful. This function | ||
|  |  * returns @c 1 on success or @c 0 on error. | ||
|  |  * | ||
|  |  * @param resource The resource to describe. | ||
|  |  * @param buf      The output buffer to write the description to. | ||
|  |  * @param len      Must be initialized to the length of @p buf and | ||
|  |  *                 will be set to the length of the printed link description. | ||
|  |  * @param offset   The offset within the resource description where to | ||
|  |  *                 start writing into @p buf. This is useful for dealing | ||
|  |  *                 with the Block2 option. @p offset is updated during | ||
|  |  *                 output as it is consumed. | ||
|  |  * | ||
|  |  * @return If COAP_PRINT_STATUS_ERROR is set, an error occured. Otherwise, | ||
|  |  *         the lower 28 bits will indicate the number of characters that | ||
|  |  *         have actually been output into @p buffer. The flag | ||
|  |  *         COAP_PRINT_STATUS_TRUNC indicates that the output has been | ||
|  |  *         truncated. | ||
|  |  */ | ||
|  | coap_print_status_t coap_print_link(const coap_resource_t *resource, | ||
|  |                                     unsigned char *buf, | ||
|  |                                     size_t *len, | ||
|  |                                     size_t *offset); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Registers the specified @p handler as message handler for the request type @p | ||
|  |  * method | ||
|  |  * | ||
|  |  * @param resource The resource for which the handler shall be registered. | ||
|  |  * @param method   The CoAP request method to handle. | ||
|  |  * @param handler  The handler to register with @p resource. | ||
|  |  */ | ||
|  | static inline void | ||
|  | coap_register_handler(coap_resource_t *resource, | ||
|  |                       unsigned char method, | ||
|  |                       coap_method_handler_t handler) { | ||
|  |   assert(resource); | ||
|  |   assert(method > 0 && (size_t)(method-1) < sizeof(resource->handler)/sizeof(coap_method_handler_t)); | ||
|  |   resource->handler[method-1] = handler; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Returns the resource identified by the unique string @p key. If no resource | ||
|  |  * was found, this function returns @c NULL. | ||
|  |  * | ||
|  |  * @param context  The context to look for this resource. | ||
|  |  * @param key      The unique key of the resource. | ||
|  |  * | ||
|  |  * @return         A pointer to the resource or @c NULL if not found. | ||
|  |  */ | ||
|  | coap_resource_t *coap_get_resource_from_key(coap_context_t *context, | ||
|  |                                             coap_key_t key); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Calculates the hash key for the resource requested by the Uri-Options of @p | ||
|  |  * request. This function calls coap_hash() for every path segment. | ||
|  |  * | ||
|  |  * @param request The requesting pdu. | ||
|  |  * @param key     The resulting hash is stored in @p key. | ||
|  |  */ | ||
|  | void coap_hash_request_uri(const coap_pdu_t *request, coap_key_t key); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * @addtogroup observe | ||
|  |  */ | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Adds the specified peer as observer for @p resource. The subscription is | ||
|  |  * identified by the given @p token. This function returns the registered | ||
|  |  * subscription information if the @p observer has been added, or @c NULL on | ||
|  |  * error. | ||
|  |  * | ||
|  |  * @param resource        The observed resource. | ||
|  |  * @param local_interface The local network interface where the observer is | ||
|  |  *                        attached to. | ||
|  |  * @param observer        The remote peer that wants to received status updates. | ||
|  |  * @param token           The token that identifies this subscription. | ||
|  |  * @return                A pointer to the added/updated subscription | ||
|  |  *                        information or @c NULL on error. | ||
|  |  */ | ||
|  | coap_subscription_t *coap_add_observer(coap_resource_t *resource, | ||
|  |                                        const coap_endpoint_t *local_interface, | ||
|  |                                        const coap_address_t *observer, | ||
|  |                                        const str *token); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Returns a subscription object for given @p peer. | ||
|  |  * | ||
|  |  * @param resource The observed resource. | ||
|  |  * @param peer     The address to search for. | ||
|  |  * @param token    The token that identifies this subscription or @c NULL for | ||
|  |  *                 any token. | ||
|  |  * @return         A valid subscription if exists or @c NULL otherwise. | ||
|  |  */ | ||
|  | coap_subscription_t *coap_find_observer(coap_resource_t *resource, | ||
|  |                                         const coap_address_t *peer, | ||
|  |                                         const str *token); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Marks an observer as alive. | ||
|  |  * | ||
|  |  * @param context  The CoAP context to use. | ||
|  |  * @param observer The transport address of the observer. | ||
|  |  * @param token    The corresponding token that has been used for the | ||
|  |  *                 subscription. | ||
|  |  */ | ||
|  | void coap_touch_observer(coap_context_t *context, | ||
|  |                          const coap_address_t *observer, | ||
|  |                          const str *token); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Removes any subscription for @p observer from @p resource and releases the | ||
|  |  * allocated storage. The result is @c 1 if an observation relationship with @p | ||
|  |  * observer and @p token existed, @c 0 otherwise. | ||
|  |  * | ||
|  |  * @param resource The observed resource. | ||
|  |  * @param observer The observer's address. | ||
|  |  * @param token    The token that identifies this subscription or @c NULL for | ||
|  |  *                 any token. | ||
|  |  * @return         @c 1 if the observer has been deleted, @c 0 otherwise. | ||
|  |  */ | ||
|  | int coap_delete_observer(coap_resource_t *resource, | ||
|  |                          const coap_address_t *observer, | ||
|  |                          const str *token); | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Checks for all known resources, if they are dirty and notifies subscribed | ||
|  |  * observers. | ||
|  |  */ | ||
|  | void coap_check_notify(coap_context_t *context); | ||
|  | 
 | ||
|  | #ifdef COAP_RESOURCES_NOHASH
 | ||
|  | 
 | ||
|  | #define RESOURCES_ADD(r, obj) \
 | ||
|  |   LL_PREPEND((r), (obj)) | ||
|  | 
 | ||
|  | #define RESOURCES_DELETE(r, obj) \
 | ||
|  |   LL_DELETE((r), (obj)) | ||
|  | 
 | ||
|  | #define RESOURCES_ITER(r,tmp) \
 | ||
|  |   coap_resource_t *tmp;       \ | ||
|  |   LL_FOREACH((r), tmp) | ||
|  | 
 | ||
|  | #define RESOURCES_FIND(r, k, res) {                         \
 | ||
|  |     coap_resource_t *tmp;                                   \ | ||
|  |     (res) = tmp = NULL;                                     \ | ||
|  |     LL_FOREACH((r), tmp) {                                  \ | ||
|  |       if (memcmp((k), tmp->key, sizeof(coap_key_t)) == 0) { \ | ||
|  |         (res) = tmp;                                        \ | ||
|  |         break;                                              \ | ||
|  |       }                                                     \ | ||
|  |     }                                                       \ | ||
|  |   } | ||
|  | #else /* COAP_RESOURCES_NOHASH */
 | ||
|  | 
 | ||
|  | #define RESOURCES_ADD(r, obj) \
 | ||
|  |   HASH_ADD(hh, (r), key, sizeof(coap_key_t), (obj)) | ||
|  | 
 | ||
|  | #define RESOURCES_DELETE(r, obj) \
 | ||
|  |   HASH_DELETE(hh, (r), (obj)) | ||
|  | 
 | ||
|  | #define RESOURCES_ITER(r,tmp)  \
 | ||
|  |   coap_resource_t *tmp, *rtmp; \ | ||
|  |   HASH_ITER(hh, (r), tmp, rtmp) | ||
|  | 
 | ||
|  | #define RESOURCES_FIND(r, k, res) {                     \
 | ||
|  |     HASH_FIND(hh, (r), (k), sizeof(coap_key_t), (res)); \ | ||
|  |   } | ||
|  | 
 | ||
|  | #endif /* COAP_RESOURCES_NOHASH */
 | ||
|  | 
 | ||
|  | /** @} */ | ||
|  | 
 | ||
|  | coap_print_status_t coap_print_wellknown(coap_context_t *, | ||
|  |                                          unsigned char *, | ||
|  |                                          size_t *, size_t, | ||
|  |                                          coap_opt_t *); | ||
|  | 
 | ||
|  | void coap_handle_failed_notify(coap_context_t *, | ||
|  |                                const coap_address_t *, | ||
|  |                                const str *); | ||
|  | 
 | ||
|  | #endif /* _COAP_RESOURCE_H_ */
 |