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 size_t coap_pdu_get_fix_header_size(void); 196 197 /** 198 * Parses @p data to extract the message size. 199 * @p length must be at least coap_pdu_parse_header_size(proto, data). 200 * This function returns @c 0 on error or a number greater than zero on success. 201 * 202 * @param proto Session's protocol 203 * @param data The raw data to parse as CoAP PDU. 204 * @param length The actual size of @p data. 205 * 206 * @return PDU size including token on success or @c 0 on error. 207 */ 208 size_t coap_pdu_parse_size(coap_proto_t proto, 209 const uint8_t *data, 210 size_t length); 211 212 /** 213 * Decode the protocol specific header for the specified PDU. 214 * @param pdu A newly received PDU. 215 * @param proto The target wire protocol. 216 * @return 1 for success or 0 on error. 217 */ 218 219 int coap_pdu_parse_header(coap_pdu_t *pdu, coap_proto_t proto); 220 221 /** 222 * Verify consistency in the given CoAP PDU structure and locate the data. 223 * This function returns @c 0 on error or a number greater than zero on 224 * success. 225 * This function only parses the token and options, up to the payload start 226 * marker. 227 * 228 * @param pdu The PDU structure to check. 229 * 230 * @return 1 on success or @c 0 on error. 231 */ 232 int coap_pdu_parse_opt(coap_pdu_t *pdu); 233 234 /** 235 * Clears any contents from @p pdu and resets @c used_size, 236 * and @c data pointers. @c max_size is set to @p size, any 237 * other field is set to @c 0. Note that @p pdu must be a valid 238 * pointer to a coap_pdu_t object created e.g. by coap_pdu_init(). 239 * 240 * @param pdu The PDU to clear. 241 * @param size The maximum size of the PDU. 242 */ 243 void coap_pdu_clear(coap_pdu_t *pdu, size_t size); 244 245 /** 246 * Adds option of given @p number to @p pdu that is passed as first 247 * parameter. 248 * 249 * The internal version of coap_add_option() may cause an @p option to be 250 * inserted, even if there is any data in the @p pdu. 251 * 252 * Note: Where possible, the option @p data needs to be stripped of leading 253 * zeros (big endian) to reduce the amount of data needed in the PDU, as well 254 * as in some cases the maximum data size of an option can be exceeded if not 255 * stripped and hence be illegal. This is done by using coap_encode_var_safe() 256 * or coap_encode_var_safe8(). 257 * 258 * @param pdu The PDU where the option is to be added. 259 * @param number The number of the new option. 260 * @param len The length of the new option. 261 * @param data The data of the new option. 262 * 263 * @return The overall length of the option or @c 0 on failure. 264 */ 265 size_t coap_add_option_internal(coap_pdu_t *pdu, 266 coap_option_num_t number, 267 size_t len, 268 const uint8_t *data); 269 /** 270 * Removes (first) option of given number from the @p pdu. 271 * 272 * @param pdu The PDU to remove the option from. 273 * @param number The number of the CoAP option to remove (first only removed). 274 * 275 * @return @c 1 if success else @c 0 if error. 276 */ 277 int coap_remove_option(coap_pdu_t *pdu, coap_option_num_t number); 278 279 /** 280 * Inserts option of given number in the @p pdu with the appropriate data. 281 * The option will be inserted in the appropriate place in the options in 282 * the pdu. 283 * 284 * @param pdu The PDU where the option is to be inserted. 285 * @param number The number of the new option. 286 * @param len The length of the new option. 287 * @param data The data of the new option. 288 * 289 * @return The overall length of the option or @c 0 on failure. 290 */ 291 size_t coap_insert_option(coap_pdu_t *pdu, coap_option_num_t number, 292 size_t len, const uint8_t *data); 293 294 /** 295 * Updates existing first option of given number in the @p pdu with the new 296 * data. 297 * 298 * @param pdu The PDU where the option is to be updated. 299 * @param number The number of the option to update (first only updated). 300 * @param len The length of the updated option. 301 * @param data The data of the updated option. 302 * 303 * @return The overall length of the updated option or @c 0 on failure. 304 */ 305 size_t coap_update_option(coap_pdu_t *pdu, 306 coap_option_num_t number, 307 size_t len, 308 const uint8_t *data); 309 310 /** 311 * Compose the protocol specific header for the specified PDU. 312 * 313 * @param pdu A newly composed PDU. 314 * @param proto The target wire protocol. 315 * 316 * @return Number of header bytes prepended before pdu->token or 0 on error. 317 */ 318 319 size_t coap_pdu_encode_header(coap_pdu_t *pdu, coap_proto_t proto); 320 321 /** 322 * Updates token in @p pdu with length @p len and @p data. 323 * This function returns @c 0 on error or a value greater than zero on success. 324 * 325 * @param pdu The PDU where the token is to be updated. 326 * @param len The length of the new token. 327 * @param data The token to add. 328 * 329 * @return A value greater than zero on success, or @c 0 on error. 330 */ 331 int coap_update_token(coap_pdu_t *pdu, 332 size_t len, 333 const uint8_t *data); 334 335 /** 336 * Check whether the option is allowed to be repeated or not. 337 * This function returns @c 0 if not repeatable or @c 1 if repeatable 338 * 339 * @param number The option number to check for repeatability. 340 * 341 * @return @c 0 if not repeatable or @c 1 if repeatable. 342 */ 343 int coap_option_check_repeatable(coap_option_num_t number); 344 345 /** @} */ 346 347 #endif /* COAP_COAP_PDU_INTERNAL_H_ */ 348