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