|  | /* | 
|  | * Copyright (c) 2016 Intel Corporation | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * @file | 
|  | * | 
|  | * @brief CoAP implementation for Zephyr. | 
|  | */ | 
|  |  | 
|  | #ifndef __ZOAP_H__ | 
|  | #define __ZOAP_H__ | 
|  |  | 
|  | #include <stdint.h> | 
|  | #include <stddef.h> | 
|  | #include <stdbool.h> | 
|  |  | 
|  | #include <misc/slist.h> | 
|  |  | 
|  | /** | 
|  | * @brief COAP library | 
|  | * @defgroup zoap COAP Library | 
|  | * @{ | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * @brief Set of CoAP packet options we are aware of. | 
|  | * | 
|  | * Users may add options other than these to their packets, provided | 
|  | * they know how to format them correctly. The only restriction is | 
|  | * that all options must be added to a packet in numeric order. | 
|  | * | 
|  | * Refer to RFC 7252, section 12.2 for more information. | 
|  | */ | 
|  | enum zoap_option_num { | 
|  | ZOAP_OPTION_IF_MATCH = 1, | 
|  | ZOAP_OPTION_URI_HOST = 3, | 
|  | ZOAP_OPTION_ETAG = 4, | 
|  | ZOAP_OPTION_IF_NONE_MATCH = 5, | 
|  | ZOAP_OPTION_OBSERVE = 6, | 
|  | ZOAP_OPTION_URI_PORT = 7, | 
|  | ZOAP_OPTION_LOCATION_PATH = 8, | 
|  | ZOAP_OPTION_URI_PATH = 11, | 
|  | ZOAP_OPTION_CONTENT_FORMAT = 12, | 
|  | ZOAP_OPTION_MAX_AGE = 14, | 
|  | ZOAP_OPTION_URI_QUERY = 15, | 
|  | ZOAP_OPTION_ACCEPT = 17, | 
|  | ZOAP_OPTION_LOCATION_QUERY = 20, | 
|  | ZOAP_OPTION_BLOCK2 = 23, | 
|  | ZOAP_OPTION_BLOCK1 = 27, | 
|  | ZOAP_OPTION_SIZE2 = 28, | 
|  | ZOAP_OPTION_PROXY_URI = 35, | 
|  | ZOAP_OPTION_PROXY_SCHEME = 39, | 
|  | ZOAP_OPTION_SIZE1 = 60, | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Available request methods. | 
|  | * | 
|  | * To be used with zoap_header_set_code() when creating a request | 
|  | * or a response. | 
|  | */ | 
|  | enum zoap_method { | 
|  | ZOAP_METHOD_GET = 1, | 
|  | ZOAP_METHOD_POST = 2, | 
|  | ZOAP_METHOD_PUT = 3, | 
|  | ZOAP_METHOD_DELETE = 4, | 
|  | }; | 
|  |  | 
|  | #define ZOAP_REQUEST_MASK 0x07 | 
|  |  | 
|  | /** | 
|  | * @brief CoAP packets may be of one of these types. | 
|  | */ | 
|  | enum zoap_msgtype { | 
|  | /** | 
|  | * Confirmable message. | 
|  | * | 
|  | * The packet is a request or response the destination end-point must | 
|  | * acknowledge. | 
|  | */ | 
|  | ZOAP_TYPE_CON = 0, | 
|  | /** | 
|  | * Non-confirmable message. | 
|  | * | 
|  | * The packet is a request or response that doesn't | 
|  | * require acknowledgements. | 
|  | */ | 
|  | ZOAP_TYPE_NON_CON = 1, | 
|  | /** | 
|  | * Acknowledge. | 
|  | * | 
|  | * Response to a confirmable message. | 
|  | */ | 
|  | ZOAP_TYPE_ACK = 2, | 
|  | /** | 
|  | * Reset. | 
|  | * | 
|  | * Rejecting a packet for any reason is done by sending a message | 
|  | * of this type. | 
|  | */ | 
|  | ZOAP_TYPE_RESET = 3 | 
|  | }; | 
|  |  | 
|  | #define zoap_make_response_code(clas, det) ((clas << 5) | (det)) | 
|  |  | 
|  | /** | 
|  | * @brief Set of response codes available for a response packet. | 
|  | * | 
|  | * To be used with zoap_header_set_code() when creating a response. | 
|  | */ | 
|  | enum zoap_response_code { | 
|  | ZOAP_RESPONSE_CODE_OK = zoap_make_response_code(2, 0), | 
|  | ZOAP_RESPONSE_CODE_CREATED = zoap_make_response_code(2, 1), | 
|  | ZOAP_RESPONSE_CODE_DELETED = zoap_make_response_code(2, 2), | 
|  | ZOAP_RESPONSE_CODE_VALID = zoap_make_response_code(2, 3), | 
|  | ZOAP_RESPONSE_CODE_CHANGED = zoap_make_response_code(2, 4), | 
|  | ZOAP_RESPONSE_CODE_CONTENT = zoap_make_response_code(2, 5), | 
|  | ZOAP_RESPONSE_CODE_CONTINUE = zoap_make_response_code(2, 31), | 
|  | ZOAP_RESPONSE_CODE_BAD_REQUEST = zoap_make_response_code(4, 0), | 
|  | ZOAP_RESPONSE_CODE_UNAUTHORIZED = zoap_make_response_code(4, 1), | 
|  | ZOAP_RESPONSE_CODE_BAD_OPTION = zoap_make_response_code(4, 2), | 
|  | ZOAP_RESPONSE_CODE_FORBIDDEN = zoap_make_response_code(4, 3), | 
|  | ZOAP_RESPONSE_CODE_NOT_FOUND = zoap_make_response_code(4, 4), | 
|  | ZOAP_RESPONSE_CODE_NOT_ALLOWED = zoap_make_response_code(4, 5), | 
|  | ZOAP_RESPONSE_CODE_NOT_ACCEPTABLE = zoap_make_response_code(4, 6), | 
|  | ZOAP_RESPONSE_CODE_INCOMPLETE = zoap_make_response_code(4, 8), | 
|  | ZOAP_RESPONSE_CODE_PRECONDITION_FAILED = zoap_make_response_code(4, 12), | 
|  | ZOAP_RESPONSE_CODE_REQUEST_TOO_LARGE = zoap_make_response_code(4, 13), | 
|  | ZOAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT = zoap_make_response_code(4, 15), | 
|  | ZOAP_RESPONSE_CODE_INTERNAL_ERROR = zoap_make_response_code(5, 0), | 
|  | ZOAP_RESPONSE_CODE_NOT_IMPLEMENTED = zoap_make_response_code(5, 1), | 
|  | ZOAP_RESPONSE_CODE_BAD_GATEWAY = zoap_make_response_code(5, 2), | 
|  | ZOAP_RESPONSE_CODE_SERVICE_UNAVAILABLE = zoap_make_response_code(5, 3), | 
|  | ZOAP_RESPONSE_CODE_GATEWAY_TIMEOUT = zoap_make_response_code(5, 4), | 
|  | ZOAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED = zoap_make_response_code(5, 5) | 
|  | }; | 
|  |  | 
|  | #define ZOAP_CODE_EMPTY (0) | 
|  |  | 
|  | struct zoap_observer; | 
|  | struct zoap_packet; | 
|  | struct zoap_pending; | 
|  | struct zoap_reply; | 
|  | struct zoap_resource; | 
|  |  | 
|  | /** | 
|  | * @typedef zoap_method_t | 
|  | * @brief Type of the callback being called when a resource's method is | 
|  | * invoked by the remote entity. | 
|  | */ | 
|  | typedef int (*zoap_method_t)(struct zoap_resource *resource, | 
|  | struct zoap_packet *request, | 
|  | const struct sockaddr *from); | 
|  |  | 
|  | /** | 
|  | * @typedef zoap_notify_t | 
|  | * @brief Type of the callback being called when a resource's has observers | 
|  | * to be informed when an update happens. | 
|  | */ | 
|  | typedef void (*zoap_notify_t)(struct zoap_resource *resource, | 
|  | struct zoap_observer *observer); | 
|  |  | 
|  | /** | 
|  | * @brief Description of CoAP resource. | 
|  | * | 
|  | * CoAP servers often want to register resources, so that clients can act on | 
|  | * them, by fetching their state or requesting updates to them. | 
|  | */ | 
|  | struct zoap_resource { | 
|  | /** Which function to be called for each CoAP method */ | 
|  | zoap_method_t get, post, put, del; | 
|  | zoap_notify_t notify; | 
|  | const char * const *path; | 
|  | void *user_data; | 
|  | sys_slist_t observers; | 
|  | int age; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Represents a remote device that is observing a local resource. | 
|  | */ | 
|  | struct zoap_observer { | 
|  | sys_snode_t list; | 
|  | struct sockaddr addr; | 
|  | uint8_t token[8]; | 
|  | uint8_t tkl; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Representation of a CoAP packet. | 
|  | */ | 
|  | struct zoap_packet { | 
|  | struct net_buf *buf; | 
|  | uint8_t *start; /* Start of the payload */ | 
|  | uint16_t total_size; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @typedef zoap_reply_t | 
|  | * @brief Helper function to be called when a response matches the | 
|  | * a pending request. | 
|  | */ | 
|  | typedef int (*zoap_reply_t)(const struct zoap_packet *response, | 
|  | struct zoap_reply *reply, | 
|  | const struct sockaddr *from); | 
|  |  | 
|  | /** | 
|  | * @brief Represents a request awaiting for an acknowledgment (ACK). | 
|  | */ | 
|  | struct zoap_pending { | 
|  | struct zoap_packet request; | 
|  | int32_t timeout; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Represents the handler for the reply of a request, it is | 
|  | * also used when observing resources. | 
|  | */ | 
|  | struct zoap_reply { | 
|  | zoap_reply_t reply; | 
|  | void *user_data; | 
|  | int age; | 
|  | uint8_t token[8]; | 
|  | uint8_t tkl; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Indicates that the remote device referenced by @a addr, with | 
|  | * @a request, wants to observe a resource. | 
|  | * | 
|  | * @param observer Observer to be initialized | 
|  | * @param request Request on which the observer will be based | 
|  | * @param addr Address of the remote device | 
|  | */ | 
|  | void zoap_observer_init(struct zoap_observer *observer, | 
|  | const struct zoap_packet *request, | 
|  | const struct sockaddr *addr); | 
|  |  | 
|  | /** | 
|  | * @brief After the observer is initialized, associate the observer | 
|  | * with an resource. | 
|  | * | 
|  | * @param resource Resource to add an observer | 
|  | * @param observer Observer to be added | 
|  | * | 
|  | * @return true if this is the first observer added to this resource. | 
|  | */ | 
|  | bool zoap_register_observer(struct zoap_resource *resource, | 
|  | struct zoap_observer *observer); | 
|  |  | 
|  | /** | 
|  | * @brief Remove this observer from the list of registered observers | 
|  | * of that resource. | 
|  | * | 
|  | * @param resource Resource in which to remove the observer | 
|  | * @param observer Observer to be removed | 
|  | */ | 
|  | void zoap_remove_observer(struct zoap_resource *resource, | 
|  | struct zoap_observer *observer); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the observer that matches address @a addr. | 
|  | * | 
|  | * @param observers Pointer to the array of observers | 
|  | * @param len Size of the array of observers | 
|  | * @param addr Address of the endpoint observing a resource | 
|  | * | 
|  | * @return A pointer to a observer if a match is found, NULL | 
|  | * otherwise. | 
|  | */ | 
|  | struct zoap_observer *zoap_find_observer_by_addr( | 
|  | struct zoap_observer *observers, size_t len, | 
|  | const struct sockaddr *addr); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the next available observer representation. | 
|  | * | 
|  | * @param observers Pointer to the array of observers | 
|  | * @param len Size of the array of observers | 
|  | * | 
|  | * @return A pointer to a observer if there's an available observer, | 
|  | * NULL otherwise. | 
|  | */ | 
|  | struct zoap_observer *zoap_observer_next_unused( | 
|  | struct zoap_observer *observers, size_t len); | 
|  |  | 
|  | /** | 
|  | * @brief Indicates that a reply is expected for @a request. | 
|  | * | 
|  | * @param reply Reply structure to be initialized | 
|  | * @param request Request from which @a reply will be based | 
|  | */ | 
|  | void zoap_reply_init(struct zoap_reply *reply, | 
|  | const struct zoap_packet *request); | 
|  |  | 
|  | /** | 
|  | * @brief Represents the value of a CoAP option. | 
|  | * | 
|  | * To be used with zoap_find_options(). | 
|  | */ | 
|  | struct zoap_option { | 
|  | uint8_t *value; | 
|  | uint16_t len; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Parses the CoAP packet in @a buf, validating it and | 
|  | * initializing @a pkt. @a buf must remain valid while @a pkt is used. | 
|  | * | 
|  | * @param pkt Packet to be initialized from received @a buf. | 
|  | * @param buf Buffer containing a CoAP packet, its @a data pointer is | 
|  | * positioned on the start of the CoAP packet. | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_packet_parse(struct zoap_packet *pkt, struct net_buf *buf); | 
|  |  | 
|  | /** | 
|  | * @brief Creates a new CoAP packet from a net_buf. @a buf must remain | 
|  | * valid while @a pkt is used. | 
|  | * | 
|  | * @param pkt New packet to be initialized using the storage from @a | 
|  | * buf. | 
|  | * @param buf Buffer that will contain a CoAP packet | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_packet_init(struct zoap_packet *pkt, struct net_buf *buf); | 
|  |  | 
|  | /** | 
|  | * @brief Initialize a pending request with a request. | 
|  | * | 
|  | * The request's fields are copied into the pending struct, so @a | 
|  | * request doesn't have to live for as long as the pending struct | 
|  | * lives, but net_buf needs to live for at least that long. | 
|  | * | 
|  | * @param pending Structure representing the waiting for a | 
|  | * confirmation message, initialized with data from @a request | 
|  | * @param request Message waiting for confirmation | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_pending_init(struct zoap_pending *pending, | 
|  | const struct zoap_packet *request); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the next available pending struct, that can be used | 
|  | * to track the retransmission status of a request. | 
|  | * | 
|  | * @param pendings Pointer to the array of #zoap_pending structures | 
|  | * @param len Size of the array of #zoap_pending structures | 
|  | * | 
|  | * @return pointer to a free #zoap_pending structure, NULL in case | 
|  | * none could be found. | 
|  | */ | 
|  | struct zoap_pending *zoap_pending_next_unused( | 
|  | struct zoap_pending *pendings, size_t len); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the next available reply struct, so it can be used | 
|  | * to track replies and notifications received. | 
|  | * | 
|  | * @param replies Pointer to the array of #zoap_reply structures | 
|  | * @param len Size of the array of #zoap_reply structures | 
|  | * | 
|  | * @return pointer to a free #zoap_reply structure, NULL in case | 
|  | * none could be found. | 
|  | */ | 
|  | struct zoap_reply *zoap_reply_next_unused( | 
|  | struct zoap_reply *replies, size_t len); | 
|  |  | 
|  | /** | 
|  | * @brief After a response is received, clear all pending | 
|  | * retransmissions related to that response. | 
|  | * | 
|  | * @param response The received response | 
|  | * @param pendings Pointer to the array of #zoap_reply structures | 
|  | * @param len Size of the array of #zoap_reply structures | 
|  | * | 
|  | * @return pointer to the associated #zoap_pending structure, NULL in | 
|  | * case none could be found. | 
|  | */ | 
|  | struct zoap_pending *zoap_pending_received( | 
|  | const struct zoap_packet *response, | 
|  | struct zoap_pending *pendings, size_t len); | 
|  |  | 
|  | /** | 
|  | * @brief After a response is received, clear all pending | 
|  | * retransmissions related to that response. | 
|  | * | 
|  | * @param response A response received | 
|  | * @param from Address from which the response was received | 
|  | * @param replies Pointer to the array of #zoap_reply structures | 
|  | * @param len Size of the array of #zoap_reply structures | 
|  | * | 
|  | * @return Pointer to the reply matching the packet received, NULL if | 
|  | * none could be found. | 
|  | */ | 
|  | struct zoap_reply *zoap_response_received( | 
|  | const struct zoap_packet *response, | 
|  | const struct sockaddr *from, | 
|  | struct zoap_reply *replies, size_t len); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the next pending about to expire, pending->timeout | 
|  | * informs how many ms to next expiration. | 
|  | * | 
|  | * @param pendings Pointer to the array of #zoap_pending structures | 
|  | * @param len Size of the array of #zoap_pending structures | 
|  | * | 
|  | * @return The next #zoap_pending to expire, NULL if none is about to | 
|  | * expire. | 
|  | */ | 
|  | struct zoap_pending *zoap_pending_next_to_expire( | 
|  | struct zoap_pending *pendings, size_t len); | 
|  |  | 
|  | /** | 
|  | * @brief After a request is sent, user may want to cycle the pending | 
|  | * retransmission so the timeout is updated. | 
|  | * | 
|  | * @param pending Pending representation to have its timeout updated | 
|  | * | 
|  | * @return false if this is the last retransmission. | 
|  | */ | 
|  | bool zoap_pending_cycle(struct zoap_pending *pending); | 
|  |  | 
|  | /** | 
|  | * @brief Cancels the pending retransmission, so it again becomes | 
|  | * available. | 
|  | * | 
|  | * @param pending Pending representation to be canceled | 
|  | */ | 
|  | void zoap_pending_clear(struct zoap_pending *pending); | 
|  |  | 
|  | /** | 
|  | * @brief Cancels awaiting for this reply, so it becomes available | 
|  | * again. | 
|  | * | 
|  | * @param reply The reply to be cancelled | 
|  | */ | 
|  | void zoap_reply_clear(struct zoap_reply *reply); | 
|  |  | 
|  | /** | 
|  | * @brief When a request is received, call the appropriate methods of | 
|  | * the matching resources. | 
|  | * | 
|  | * @param pkt Packet received | 
|  | * @param resources Array of known resources | 
|  | * @param from Address from which the packet was received | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_handle_request(struct zoap_packet *pkt, | 
|  | struct zoap_resource *resources, | 
|  | const struct sockaddr *from); | 
|  |  | 
|  | /** | 
|  | * @brief Indicates that this resource was updated and that the @a | 
|  | * notify callback should be called for every registered observer. | 
|  | * | 
|  | * @param resource Resource that was updated | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_resource_notify(struct zoap_resource *resource); | 
|  |  | 
|  | /** | 
|  | * @brief Returns if this request is enabling observing a resource. | 
|  | * | 
|  | * @param request Request to be checked | 
|  | * | 
|  | * @return True if the request is enabling observing a resource, False | 
|  | * otherwise | 
|  | */ | 
|  | bool zoap_request_is_observe(const struct zoap_packet *request); | 
|  |  | 
|  | /** | 
|  | * @brief Returns a pointer to the start of the payload and its size | 
|  | * | 
|  | * It will insert the COAP_MARKER (0xFF), if its not set, and return the | 
|  | * available size for the payload. | 
|  | * | 
|  | * @param pkt Packet to get (or insert) the payload | 
|  | * @param len Amount of space for the payload | 
|  | * | 
|  | * @return pointer to the start of the payload, NULL in case of error. | 
|  | */ | 
|  | uint8_t *zoap_packet_get_payload(struct zoap_packet *pkt, uint16_t *len); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the internal buffer of the CoAP packet, appending | 
|  | * the COAP_MARKER to the buffer if necessary. | 
|  | * | 
|  | * @param pkt Packet to get (or insert) the payload | 
|  | * | 
|  | * @return pointer to the net_buf storing the payload. | 
|  | */ | 
|  | struct net_buf *zoap_packet_get_buf(struct zoap_packet *pkt); | 
|  |  | 
|  | /** | 
|  | * @brief Sets how much space was used by the payload. | 
|  | * | 
|  | * Used for outgoing packets, after zoap_packet_get_payload(), to | 
|  | * update the internal representation with the amount of data that was | 
|  | * added to the packet. | 
|  | * | 
|  | * @param pkt Packet to be updated | 
|  | * @param len Amount of data that was added to the payload | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_packet_set_used(struct zoap_packet *pkt, uint16_t len); | 
|  |  | 
|  | /** | 
|  | * @brief Adds an option to the packet. | 
|  | * | 
|  | * Note: ptions must be added in numeric order of their codes. | 
|  | * | 
|  | * @param pkt Packet to be updated | 
|  | * @param code Option code to add to the packet, see #zoap_option_num | 
|  | * @param value Pointer to the value of the option, will be copied to the packet | 
|  | * @param len Size of the data to be added | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_add_option(struct zoap_packet *pkt, uint16_t code, | 
|  | const void *value, uint16_t len); | 
|  |  | 
|  | /** | 
|  | * @brief Converts an option to its integer representation. | 
|  | * | 
|  | * Assumes that the number is encoded in the network byte order in the | 
|  | * option. | 
|  | * | 
|  | * @param option Pointer to the option value, retrieved by | 
|  | * zoap_find_options() | 
|  | * | 
|  | * @return The integer representation of the option | 
|  | */ | 
|  | unsigned int zoap_option_value_to_int(const struct zoap_option *option); | 
|  |  | 
|  | /** | 
|  | * @brief Adds an integer value option to the packet. | 
|  | * | 
|  | * The option must be added in numeric order of their codes, and the | 
|  | * least amount of bytes will be used to encode the value. | 
|  | * | 
|  | * @param pkt Packet to be updated | 
|  | * @param code Option code to add to the packet, see #zoap_option_num | 
|  | * @param val Integer value to be added | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_add_option_int(struct zoap_packet *pkt, uint16_t code, | 
|  | unsigned int val); | 
|  |  | 
|  | /** | 
|  | * @brief Return the values associated with the option of value @a | 
|  | * code. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * @param code Option number to look for | 
|  | * @param options Array of #zoap_option where to store the value | 
|  | * of the options found | 
|  | * @param veclen Number of elements in the options array | 
|  | * | 
|  | * @return The number of options found in packet matching code, | 
|  | * negative on error. | 
|  | */ | 
|  | int zoap_find_options(const struct zoap_packet *pkt, uint16_t code, | 
|  | struct zoap_option *options, uint16_t veclen); | 
|  |  | 
|  | /** | 
|  | * Represents the size of each block that will be transferred using | 
|  | * block-wise transfers [RFC7959]: | 
|  | * | 
|  | * Each entry maps directly to the value that is used in the wire. | 
|  | * | 
|  | * https://tools.ietf.org/html/rfc7959 | 
|  | */ | 
|  | enum zoap_block_size { | 
|  | ZOAP_BLOCK_16, | 
|  | ZOAP_BLOCK_32, | 
|  | ZOAP_BLOCK_64, | 
|  | ZOAP_BLOCK_128, | 
|  | ZOAP_BLOCK_256, | 
|  | ZOAP_BLOCK_512, | 
|  | ZOAP_BLOCK_1024, | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Helper for converting the enumeration to the size expressed | 
|  | * in bytes. | 
|  | * | 
|  | * @param block_size The block size to be converted | 
|  | * | 
|  | * @return The size in bytes that the block_size represents | 
|  | */ | 
|  | static inline uint16_t zoap_block_size_to_bytes( | 
|  | enum zoap_block_size block_size) | 
|  | { | 
|  | return (1 << (block_size + 4)); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief Represents the current state of a block-wise transaction. | 
|  | */ | 
|  | struct zoap_block_context { | 
|  | size_t total_size; | 
|  | size_t current; | 
|  | enum zoap_block_size block_size; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Initializes the context of a block-wise transfer. | 
|  | * | 
|  | * @param ctx The context to be initialized | 
|  | * @param block_size The size of the block | 
|  | * @param total_size The total size of the transfer, if known | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_block_transfer_init(struct zoap_block_context *ctx, | 
|  | enum zoap_block_size block_size, | 
|  | size_t total_size); | 
|  |  | 
|  | /** | 
|  | * @brief Add BLOCK1 option to the packet. | 
|  | * | 
|  | * @param pkt Packet to be updated | 
|  | * @param ctx Block context from which to retrieve the | 
|  | * information for the Block1 option | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_add_block1_option(struct zoap_packet *pkt, | 
|  | struct zoap_block_context *ctx); | 
|  |  | 
|  | /** | 
|  | * @brief Add BLOCK2 option to the packet. | 
|  | * | 
|  | * @param pkt Packet to be updated | 
|  | * @param ctx Block context from which to retrieve the | 
|  | * information for the Block2 option | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_add_block2_option(struct zoap_packet *pkt, | 
|  | struct zoap_block_context *ctx); | 
|  |  | 
|  | /** | 
|  | * @brief Add SIZE1 option to the packet. | 
|  | * | 
|  | * @param pkt Packet to be updated | 
|  | * @param ctx Block context from which to retrieve the | 
|  | * information for the Size1 option | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_add_size1_option(struct zoap_packet *pkt, | 
|  | struct zoap_block_context *ctx); | 
|  |  | 
|  | /** | 
|  | * @brief Add SIZE2 option to the packet. | 
|  | * | 
|  | * @param pkt Packet to be updated | 
|  | * @param ctx Block context from which to retrieve the | 
|  | * information for the Size2 option | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_add_size2_option(struct zoap_packet *pkt, | 
|  | struct zoap_block_context *ctx); | 
|  |  | 
|  | /** | 
|  | * @brief Retrieves BLOCK{1,2} and SIZE{1,2} from @a pkt and updates | 
|  | * @a ctx accordingly. | 
|  | * | 
|  | * @param pkt Packet in which to look for block-wise transfers options | 
|  | * @param ctx Block context to be updated | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_update_from_block(const struct zoap_packet *pkt, | 
|  | struct zoap_block_context *ctx); | 
|  |  | 
|  | /** | 
|  | * @brief Updates @a ctx so after this is called the current entry | 
|  | * indicates the correct offset in the body of data being | 
|  | * transferred. | 
|  | * | 
|  | * @param ctx Block context to be updated | 
|  | * | 
|  | * @return The offset in the block-wise transfer, 0 if the transfer | 
|  | * has finished. | 
|  | */ | 
|  | size_t zoap_next_block(struct zoap_block_context *ctx); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the version present in a CoAP packet. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * | 
|  | * @return the CoAP version in packet | 
|  | */ | 
|  | uint8_t zoap_header_get_version(const struct zoap_packet *pkt); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the type of the CoAP packet. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * | 
|  | * @return the type of the packet | 
|  | */ | 
|  | uint8_t zoap_header_get_type(const struct zoap_packet *pkt); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the token (if any) in the CoAP packet. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * @param len Where to store the length of the token | 
|  | * | 
|  | * @return pointer to the start of the token in the CoAP packet. | 
|  | */ | 
|  | const uint8_t *zoap_header_get_token(const struct zoap_packet *pkt, | 
|  | uint8_t *len); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the code of the CoAP packet. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * | 
|  | * @return the code present in the packet | 
|  | */ | 
|  | uint8_t zoap_header_get_code(const struct zoap_packet *pkt); | 
|  |  | 
|  | /** | 
|  | * @brief Returns the message id associated with the CoAP packet. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * | 
|  | * @return the message id present in the packet | 
|  | */ | 
|  | uint16_t zoap_header_get_id(const struct zoap_packet *pkt); | 
|  |  | 
|  | /** | 
|  | * @brief Sets the version of the CoAP packet. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * @param ver The CoAP version to set in the packet | 
|  | */ | 
|  | void zoap_header_set_version(struct zoap_packet *pkt, uint8_t ver); | 
|  |  | 
|  | /** | 
|  | * @brief Sets the type of the CoAP packet. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * @param type The packet type to set | 
|  | */ | 
|  | void zoap_header_set_type(struct zoap_packet *pkt, uint8_t type); | 
|  |  | 
|  | /** | 
|  | * @brief Sets the token in the CoAP packet. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * @param token Token to set in the packet, will be copied | 
|  | * @param tokenlen Size of the token to be set, 8 bytes maximum | 
|  | * | 
|  | * @return 0 in case of success or negative in case of error. | 
|  | */ | 
|  | int zoap_header_set_token(struct zoap_packet *pkt, const uint8_t *token, | 
|  | uint8_t tokenlen); | 
|  |  | 
|  | /** | 
|  | * @brief Sets the code present in the CoAP packet. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * @param code The code set in the packet | 
|  | */ | 
|  | void zoap_header_set_code(struct zoap_packet *pkt, uint8_t code); | 
|  |  | 
|  | /** | 
|  | * @brief Sets the message id present in the CoAP packet. | 
|  | * | 
|  | * @param pkt CoAP packet representation | 
|  | * @param id The message id to set in the packet | 
|  | */ | 
|  | void zoap_header_set_id(struct zoap_packet *pkt, uint16_t id); | 
|  |  | 
|  | /** | 
|  | * @brief Helper to generate message ids | 
|  | * | 
|  | * @return a new message id | 
|  | */ | 
|  | static inline uint16_t zoap_next_id(void) | 
|  | { | 
|  | static uint16_t message_id; | 
|  |  | 
|  | return ++message_id; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief Returns a randomly generated array of 8 bytes, that can be | 
|  | * used as a message's token. | 
|  | * | 
|  | * @return a 8-byte pseudo-random token. | 
|  | */ | 
|  | uint8_t *zoap_next_token(void); | 
|  |  | 
|  | /** | 
|  | * @} | 
|  | */ | 
|  |  | 
|  | #endif /* __ZOAP_H__ */ |