• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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