1 /* 2 * coap_pdu_internal.h -- CoAP PDU structure 3 * 4 * Copyright (C) 2010-2021 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_pdu_internal.h 14 * @brief CoAP PDU internal information 15 */ 16 17 #ifndef COAP_COAP_PDU_INTERNAL_H_ 18 #define COAP_COAP_PDU_INTERNAL_H_ 19 20 #ifdef WITH_LWIP 21 #include <lwip/pbuf.h> 22 #endif 23 24 #include <stdint.h> 25 26 /** 27 * @defgroup pdu_internal PDU (Internal) 28 * CoAP PDU Structures, Enums and Functions that are not exposed to 29 * applications 30 * @{ 31 */ 32 33 #define COAP_DEFAULT_VERSION 1 /* version of CoAP supported */ 34 35 /* TCP Message format constants, do not modify */ 36 #define COAP_MESSAGE_SIZE_OFFSET_TCP8 13 37 #define COAP_MESSAGE_SIZE_OFFSET_TCP16 269 /* 13 + 256 */ 38 #define COAP_MESSAGE_SIZE_OFFSET_TCP32 65805 /* 269 + 65536 */ 39 40 /* Derived message size limits */ 41 #define COAP_MAX_MESSAGE_SIZE_TCP0 (COAP_MESSAGE_SIZE_OFFSET_TCP8-1) /* 12 */ 42 #define COAP_MAX_MESSAGE_SIZE_TCP8 (COAP_MESSAGE_SIZE_OFFSET_TCP16-1) /* 268 */ 43 #define COAP_MAX_MESSAGE_SIZE_TCP16 (COAP_MESSAGE_SIZE_OFFSET_TCP32-1) /* 65804 */ 44 #define COAP_MAX_MESSAGE_SIZE_TCP32 (COAP_MESSAGE_SIZE_OFFSET_TCP32+0xFFFFFFFF) 45 46 #ifndef COAP_DEBUG_BUF_SIZE 47 #if defined(WITH_CONTIKI) || defined(WITH_LWIP) 48 #define COAP_DEBUG_BUF_SIZE 128 49 #else /* defined(WITH_CONTIKI) || defined(WITH_LWIP) */ 50 /* 1024 derived from RFC7252 4.6. Message Size max payload */ 51 #define COAP_DEBUG_BUF_SIZE (8 + 1024 * 2) 52 #endif /* defined(WITH_CONTIKI) || defined(WITH_LWIP) */ 53 #endif /* COAP_DEBUG_BUF_SIZE */ 54 55 #ifndef COAP_DEFAULT_MAX_PDU_RX_SIZE 56 #if defined(WITH_CONTIKI) || defined(WITH_LWIP) 57 #define COAP_DEFAULT_MAX_PDU_RX_SIZE (COAP_MAX_MESSAGE_SIZE_TCP16+4UL) 58 #else 59 /* 8 MiB max-message-size plus some space for options */ 60 #define COAP_DEFAULT_MAX_PDU_RX_SIZE (8UL*1024*1024+256) 61 #endif 62 #endif /* COAP_DEFAULT_MAX_PDU_RX_SIZE */ 63 64 /** 65 * Indicates that a response is suppressed. This will occur for error 66 * responses if the request was received via IP multicast. 67 */ 68 #define COAP_DROPPED_RESPONSE -2 69 70 #define COAP_PDU_DELAYED -3 71 72 #define COAP_PAYLOAD_START 0xFF /* payload marker */ 73 74 #define COAP_PDU_IS_EMPTY(pdu) ((pdu)->code == 0) 75 #define COAP_PDU_IS_REQUEST(pdu) (!COAP_PDU_IS_EMPTY(pdu) && (pdu)->code < 32) 76 #define COAP_PDU_IS_RESPONSE(pdu) ((pdu)->code >= 64 && (pdu)->code < 224) 77 #define COAP_PDU_IS_SIGNALING(pdu) ((pdu)->code >= 224) 78 79 #define COAP_PDU_MAX_UDP_HEADER_SIZE 4 80 #define COAP_PDU_MAX_TCP_HEADER_SIZE 6 81 82 /** 83 * structure for CoAP PDUs 84 * token, if any, follows the fixed size header, then options until 85 * payload marker (0xff), then the payload if stored inline. 86 * Memory layout is: 87 * <---header--->|<---token---><---options--->0xff<---payload---> 88 * header is addressed with a negative offset to token, its maximum size is 89 * max_hdr_size. 90 * options starts at token + token_length 91 * payload starts at data, its length is used_size - (data - token) 92 */ 93 94 struct coap_pdu_t { 95 coap_pdu_type_t type; /**< message type */ 96 coap_pdu_code_t code; /**< request method (value 1--31) or response code 97 (value 64-255) */ 98 coap_mid_t mid; /**< message id, if any, in regular host byte 99 order */ 100 uint8_t max_hdr_size; /**< space reserved for protocol-specific header */ 101 uint8_t hdr_size; /**< actual size used for protocol-specific 102 header */ 103 uint8_t token_length; /**< length of Token */ 104 uint16_t max_opt; /**< highest option number in PDU */ 105 size_t alloc_size; /**< allocated storage for token, options and 106 payload */ 107 size_t used_size; /**< used bytes of storage for token, options and 108 payload */ 109 size_t max_size; /**< maximum size for token, options and payload, 110 or zero for variable size pdu */ 111 uint8_t *token; /**< first byte of token, if any, or options */ 112 uint8_t *data; /**< first byte of payload, if any */ 113 #ifdef WITH_LWIP 114 struct pbuf *pbuf; /**< lwIP PBUF. The package data will always reside 115 * inside the pbuf's payload, but this pointer 116 * has to be kept because no exact offset can be 117 * given. This field must not be accessed from 118 * outside, because the pbuf's reference count 119 * is checked to be 1 when the pbuf is assigned 120 * to the pdu, and the pbuf stays exclusive to 121 * this pdu. */ 122 #endif 123 const uint8_t *body_data; /**< Holds ptr to re-assembled data or NULL */ 124 size_t body_length; /**< Holds body data length */ 125 size_t body_offset; /**< Holds body data offset */ 126 size_t body_total; /**< Holds body data total size */ 127 coap_lg_xmit_t *lg_xmit; /**< Holds ptr to lg_xmit if sending a set of 128 blocks */ 129 }; 130 131 /** 132 * Dynamically grows the size of @p pdu to @p new_size. The new size 133 * must not exceed the PDU's configure maximum size. On success, this 134 * function returns 1, otherwise 0. 135 * 136 * @param pdu The PDU to resize. 137 * @param new_size The new size in bytes. 138 * @return 1 if the operation succeeded, 0 otherwise. 139 */ 140 int coap_pdu_resize(coap_pdu_t *pdu, size_t new_size); 141 142 /** 143 * Dynamically grows the size of @p pdu to @p new_size if needed. The new size 144 * must not exceed the PDU's configured maximum size. On success, this 145 * function returns 1, otherwise 0. 146 * 147 * @param pdu The PDU to resize. 148 * @param new_size The new size in bytes. 149 * @return 1 if the operation succeeded, 0 otherwise. 150 */ 151 int coap_pdu_check_resize(coap_pdu_t *pdu, size_t new_size); 152 153 /** 154 * Interprets @p data to determine the number of bytes in the header. 155 * This function returns @c 0 on error or a number greater than zero on success. 156 * 157 * @param proto Session's protocol 158 * @param data The first byte of raw data to parse as CoAP PDU. 159 * 160 * @return A value greater than zero on success or @c 0 on error. 161 */ 162 size_t coap_pdu_parse_header_size(coap_proto_t proto, 163 const uint8_t *data); 164 165 /** 166 * Parses @p data to extract the message size. 167 * @p length must be at least coap_pdu_parse_header_size(proto, data). 168 * This function returns @c 0 on error or a number greater than zero on success. 169 * 170 * @param proto Session's protocol 171 * @param data The raw data to parse as CoAP PDU. 172 * @param length The actual size of @p data. 173 * 174 * @return A value greater than zero on success or @c 0 on error. 175 */ 176 size_t coap_pdu_parse_size(coap_proto_t proto, 177 const uint8_t *data, 178 size_t length); 179 180 /** 181 * Decode the protocol specific header for the specified PDU. 182 * @param pdu A newly received PDU. 183 * @param proto The target wire protocol. 184 * @return 1 for success or 0 on error. 185 */ 186 187 int coap_pdu_parse_header(coap_pdu_t *pdu, coap_proto_t proto); 188 189 /** 190 * Verify consistency in the given CoAP PDU structure and locate the data. 191 * This function returns @c 0 on error or a number greater than zero on 192 * success. 193 * This function only parses the token and options, up to the payload start 194 * marker. 195 * 196 * @param pdu The PDU structure to check. 197 * 198 * @return 1 on success or @c 0 on error. 199 */ 200 int coap_pdu_parse_opt(coap_pdu_t *pdu); 201 202 /** 203 * Parses @p data into the CoAP PDU structure given in @p result. 204 * The target pdu must be large enough to 205 * This function returns @c 0 on error or a number greater than zero on success. 206 * 207 * @param proto Session's protocol 208 * @param data The raw data to parse as CoAP PDU. 209 * @param length The actual size of @p data. 210 * @param pdu The PDU structure to fill. Note that the structure must 211 * provide space to hold at least the token and options 212 * part of the message. 213 * 214 * @return 1 on success or @c 0 on error. 215 */ 216 int coap_pdu_parse(coap_proto_t proto, 217 const uint8_t *data, 218 size_t length, 219 coap_pdu_t *pdu); 220 221 /** 222 * Clears any contents from @p pdu and resets @c used_size, 223 * and @c data pointers. @c max_size is set to @p size, any 224 * other field is set to @c 0. Note that @p pdu must be a valid 225 * pointer to a coap_pdu_t object created e.g. by coap_pdu_init(). 226 * 227 * @param pdu The PDU to clear. 228 * @param size The maximum size of the PDU. 229 */ 230 void coap_pdu_clear(coap_pdu_t *pdu, size_t size); 231 232 /** 233 * Removes (first) option of given number from the @p pdu. 234 * 235 * @param pdu The PDU to remove the option from. 236 * @param number The number of the CoAP option to remove (first only removed). 237 * 238 * @return @c 1 if success else @c 0 if error. 239 */ 240 int coap_remove_option(coap_pdu_t *pdu, coap_option_num_t number); 241 242 /** 243 * Inserts option of given number in the @p pdu with the appropriate data. 244 * The option will be inserted in the appropriate place in the options in 245 * the pdu. 246 * 247 * @param pdu The PDU where the option is to be inserted. 248 * @param number The number of the new option. 249 * @param len The length of the new option. 250 * @param data The data of the new option. 251 * 252 * @return The overall length of the option or @c 0 on failure. 253 */ 254 size_t coap_insert_option(coap_pdu_t *pdu, coap_option_num_t number, 255 size_t len, const uint8_t *data); 256 257 /** 258 * Updates existing first option of given number in the @p pdu with the new 259 * data. 260 * 261 * @param pdu The PDU where the option is to be updated. 262 * @param number The number of the option to update (first only updated). 263 * @param len The length of the updated option. 264 * @param data The data of the updated option. 265 * 266 * @return The overall length of the updated option or @c 0 on failure. 267 */ 268 size_t coap_update_option(coap_pdu_t *pdu, 269 coap_option_num_t number, 270 size_t len, 271 const uint8_t *data); 272 273 /** 274 * Compose the protocol specific header for the specified PDU. 275 * 276 * @param pdu A newly composed PDU. 277 * @param proto The target wire protocol. 278 * 279 * @return Number of header bytes prepended before pdu->token or 0 on error. 280 */ 281 282 size_t coap_pdu_encode_header(coap_pdu_t *pdu, coap_proto_t proto); 283 284 /** 285 * Updates token in @p pdu with length @p len and @p data. 286 * This function returns @c 0 on error or a value greater than zero on success. 287 * 288 * @param pdu The PDU where the token is to be updated. 289 * @param len The length of the new token. 290 * @param data The token to add. 291 * 292 * @return A value greater than zero on success, or @c 0 on error. 293 */ 294 int coap_update_token(coap_pdu_t *pdu, 295 size_t len, 296 const uint8_t *data); 297 298 /** @} */ 299 300 #endif /* COAP_COAP_PDU_INTERNAL_H_ */ 301