• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * coap_pdu.h -- CoAP message structure
3  *
4  * Copyright (C) 2010-2014 Olaf Bergmann <bergmann@tzi.org>
5  * Copyright (C) 2021-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
6  *
7  * SPDX-License-Identifier: BSD-2-Clause
8  *
9  * This file is part of the CoAP library libcoap. Please see README for terms
10  * of use.
11  */
12 
13 /**
14  * @file coap_pdu.h
15  * @brief Pre-defined constants that reflect defaults for CoAP
16  */
17 
18 #ifndef COAP_PDU_H_
19 #define COAP_PDU_H_
20 
21 #include "coap_option.h"
22 #include "coap_uri.h"
23 
24 #ifdef WITH_LWIP
25 #include <lwip/pbuf.h>
26 #endif
27 
28 #include <stdint.h>
29 
30 /**
31  * @ingroup application_api
32  * @defgroup pdu PDU
33  * API for PDUs
34  * @{
35  */
36 
37 #ifndef COAP_USER_DEFAULT_PORT
38 #define COAP_USER_DEFAULT_PORT 5683 /* CoAP default UDP/TCP port */
39 #endif
40 #define COAP_DEFAULT_PORT COAP_USER_DEFAULT_PORT
41 
42 #define COAPS_DEFAULT_PORT     5684 /* CoAP default UDP/TCP port for secure transmission */
43 #define COAP_DEFAULT_MAX_AGE     60 /* default maximum object lifetime in seconds */
44 #ifndef COAP_DEFAULT_MTU
45 #ifdef SUPPORT_OPTIC_ONT
46 #define COAP_DEFAULT_MTU       65535
47 #else
48 #define COAP_DEFAULT_MTU       1152
49 #endif
50 #endif /* COAP_DEFAULT_MTU */
51 
52 #define COAP_BERT_BASE 1152
53 
54 #ifndef COAP_DEFAULT_HOP_LIMIT
55 #define COAP_DEFAULT_HOP_LIMIT       16
56 #endif /* COAP_DEFAULT_HOP_LIMIT */
57 
58 #define COAP_DEFAULT_SCHEME  "coap" /* the default scheme for CoAP URIs */
59 
60 /** well-known resources URI */
61 #define COAP_DEFAULT_URI_WELLKNOWN ".well-known/core"
62 
63 /* Extended Token constants */
64 #define COAP_TOKEN_DEFAULT_MAX 8
65 #define COAP_TOKEN_EXT_MAX 65804 /* 13 + 256 + 65535 */
66 
67 /* CoAP message types */
68 
69 /**
70  * CoAP PDU message type definitions
71  */
72 typedef enum coap_pdu_type_t {
73   COAP_MESSAGE_CON,  /* 0 confirmable message (requires ACK/RST) */
74   COAP_MESSAGE_NON,  /* 1 non-confirmable message (one-shot message) */
75   COAP_MESSAGE_ACK,  /* 2 used to acknowledge confirmable messages */
76   COAP_MESSAGE_RST   /* 3 indicates error in received messages */
77 } coap_pdu_type_t;
78 
79 /**
80  * CoAP PDU Request methods
81  */
82 typedef enum coap_request_t {
83   COAP_REQUEST_GET = 1,
84   COAP_REQUEST_POST,      /* 2 */
85   COAP_REQUEST_PUT,       /* 3 */
86   COAP_REQUEST_DELETE,    /* 4 */
87   COAP_REQUEST_FETCH,     /* 5 RFC 8132 */
88   COAP_REQUEST_PATCH,     /* 6 RFC 8132 */
89   COAP_REQUEST_IPATCH,    /* 7 RFC 8132 */
90 } coap_request_t;
91 
92 /*
93  * CoAP option numbers (be sure to update coap_option_check_critical() and
94  * coap_add_option() when adding options
95  */
96 
97 /*
98  * The C, U, and N flags indicate the properties
99  * Critical, Unsafe, and NoCacheKey, respectively.
100  * If U is set, then N has no meaning as per
101  * https://rfc-editor.org/rfc/rfc7252#section-5.10
102  * and is set to a -.
103  *
104  * Separately, R is for the options that can be repeated
105  *
106  * The least significant byte of the option is set as followed
107  * as per https://rfc-editor.org/rfc/rfc7252#section-5.4.6
108  *
109  *   0   1   2   3   4   5   6   7
110  * --+---+---+---+---+---+---+---+
111  *           | NoCacheKey| U | C |
112  * --+---+---+---+---+---+---+---+
113  *
114  * https://rfc-editor.org/rfc/rfc8613#section-4 goes on to define E, I and U
115  * properties Encrypted and Integrity Protected, Integrity Protected Only, and
116  * Unprotected respectively.  Integrity Protected Only is not currently used.
117  *
118  * An Option is tagged with CUNREIU with any of the letters replaced with _ if
119  * not set, or - for N if U is set (see above) for aiding understanding of the
120  * Option.
121  */
122 
123 #define COAP_OPTION_IF_MATCH        1 /* C__RE__, opaque,    0-8 B, RFC7252 */
124 #define COAP_OPTION_URI_HOST        3 /* CU-___U, String,  1-255 B, RFC7252 */
125 #define COAP_OPTION_ETAG            4 /* ___RE__, opaque,    1-8 B, RFC7252 */
126 #define COAP_OPTION_IF_NONE_MATCH   5 /* C___E__, empty,       0 B, RFC7252 */
127 #define COAP_OPTION_OBSERVE         6 /* _U-_E_U, empty/uint,0/0-3 B, RFC7641 */
128 #define COAP_OPTION_URI_PORT        7 /* CU-___U, uint,      0-2 B, RFC7252 */
129 #define COAP_OPTION_LOCATION_PATH   8 /* ___RE__, String,  0-255 B, RFC7252 */
130 #define COAP_OPTION_OSCORE          9 /* C_____U, *,       0-255 B, RFC8613 */
131 #define COAP_OPTION_URI_PATH       11 /* CU-RE__, String,  0-255 B, RFC7252 */
132 #define COAP_OPTION_CONTENT_FORMAT 12 /* ____E__, uint,      0-2 B, RFC7252 */
133 #define COAP_OPTION_CONTENT_TYPE COAP_OPTION_CONTENT_FORMAT
134 /* COAP_OPTION_MAXAGE default 60 seconds if not set */
135 #define COAP_OPTION_MAXAGE         14 /* _U-_E_U, uint,      0-4 B, RFC7252 */
136 #define COAP_OPTION_URI_QUERY      15 /* CU-RE__, String,  1-255 B, RFC7252 */
137 #define COAP_OPTION_HOP_LIMIT      16 /* ______U, uint,        1 B, RFC8768 */
138 #define COAP_OPTION_ACCEPT         17 /* C___E__, uint,      0-2 B, RFC7252 */
139 #define COAP_OPTION_Q_BLOCK1       19 /* CU__E_U, uint,      0-3 B, RFC9177 */
140 #define COAP_OPTION_LOCATION_QUERY 20 /* ___RE__, String,  0-255 B, RFC7252 */
141 #define COAP_OPTION_BLOCK2         23 /* CU-_E_U, uint,      0-3 B, RFC7959 */
142 #define COAP_OPTION_BLOCK1         27 /* CU-_E_U, uint,      0-3 B, RFC7959 */
143 #define COAP_OPTION_SIZE2          28 /* __N_E_U, uint,      0-4 B, RFC7959 */
144 #define COAP_OPTION_Q_BLOCK2       31 /* CU_RE_U, uint,      0-3 B, RFC9177 */
145 #define COAP_OPTION_PROXY_URI      35 /* CU-___U, String, 1-1034 B, RFC7252 */
146 #define COAP_OPTION_PROXY_SCHEME   39 /* CU-___U, String,  1-255 B, RFC7252 */
147 #define COAP_OPTION_SIZE1          60 /* __N_E_U, uint,      0-4 B, RFC7252 */
148 #define COAP_OPTION_ECHO          252 /* _N__E_U, opaque,   0-40 B, RFC9175 */
149 #define COAP_OPTION_NORESPONSE    258 /* _U-_E_U, uint,      0-1 B, RFC7967 */
150 #define COAP_OPTION_RTAG          292 /* ___RE_U, opaque,    0-8 B, RFC9175 */
151 
152 #define COAP_OPTION_ACCESS_TOKEN_ID  2049
153 #define COAP_OPTION_REQ_ID           2050
154 #define COAP_OPTION_DEV_ID           2051
155 #define COAP_OPTION_USER_ID          2052
156 
157 #define COAP_MAX_OPT            65535 /**< the highest option number we know */
158 
159 /* CoAP result codes (HTTP-Code / 100 * 40 + HTTP-Code % 100) */
160 
161 /* As of draft-ietf-core-coap-04, response codes are encoded to base
162  * 32, i.e.  the three upper bits determine the response class while
163  * the remaining five fine-grained information specific to that class.
164  */
165 #define COAP_RESPONSE_CODE(N) (((N)/100 << 5) | (N)%100)
166 
167 /* Determines the class of response code C */
168 #define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF)
169 
170 #ifndef SHORT_ERROR_RESPONSE
171 /**
172  * Returns a human-readable response phrase for the specified CoAP response @p
173  * code. This function returns @c NULL if not found.
174  *
175  * @param code The response code for which the literal phrase should be
176  *             retrieved.
177  *
178  * @return     A zero-terminated string describing the error, or @c NULL if not
179  *             found.
180  */
181 const char *coap_response_phrase(unsigned char code);
182 
183 #define COAP_ERROR_PHRASE_LENGTH   32 /**< maximum length of error phrase */
184 
185 #else
186 #define coap_response_phrase(x) ((char *)NULL)
187 
188 #define COAP_ERROR_PHRASE_LENGTH    0 /**< maximum length of error phrase */
189 #endif /* SHORT_ERROR_RESPONSE */
190 
191 #define COAP_SIGNALING_CODE(N) (((N)/100 << 5) | (N)%100)
192 
193 typedef enum coap_pdu_signaling_proto_t {
194   COAP_SIGNALING_CSM =     COAP_SIGNALING_CODE(701),
195   COAP_SIGNALING_PING =    COAP_SIGNALING_CODE(702),
196   COAP_SIGNALING_PONG =    COAP_SIGNALING_CODE(703),
197   COAP_SIGNALING_RELEASE = COAP_SIGNALING_CODE(704),
198   COAP_SIGNALING_ABORT =   COAP_SIGNALING_CODE(705),
199 } coap_pdu_signaling_proto_t;
200 
201 /* Applies to COAP_SIGNALING_CSM */
202 #define COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE 2
203 #define COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER 4
204 #define COAP_SIGNALING_OPTION_EXTENDED_TOKEN_LENGTH 6
205 
206 /* Applies to COAP_SIGNALING_PING / COAP_SIGNALING_PONG */
207 #define COAP_SIGNALING_OPTION_CUSTODY 2
208 
209 /* Applies to COAP_SIGNALING_RELEASE */
210 #define COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS 2
211 #define COAP_SIGNALING_OPTION_HOLD_OFF 4
212 
213 /* Applies to COAP_SIGNALING_ABORT */
214 #define COAP_SIGNALING_OPTION_BAD_CSM_OPTION 2
215 
216 /* CoAP media type encoding */
217 
218 #define COAP_MEDIATYPE_TEXT_PLAIN                 0 /* text/plain (UTF-8) */
219 #define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT   40 /* application/link-format */
220 #define COAP_MEDIATYPE_APPLICATION_XML           41 /* application/xml */
221 #define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM  42 /* application/octet-stream */
222 #define COAP_MEDIATYPE_APPLICATION_RDF_XML       43 /* application/rdf+xml */
223 #define COAP_MEDIATYPE_APPLICATION_EXI           47 /* application/exi  */
224 #define COAP_MEDIATYPE_APPLICATION_JSON          50 /* application/json  */
225 #define COAP_MEDIATYPE_APPLICATION_CBOR          60 /* application/cbor  */
226 #define COAP_MEDIATYPE_APPLICATION_CWT           61 /* application/cwt, RFC 8392  */
227 
228 /* Content formats from RFC 7390 */
229 #define COAP_MEDIATYPE_APPLICATION_COAP_GROUP_JSON 256 /* application/coap-group+json */
230 
231 /* Content formats from RFC 8152 */
232 #define COAP_MEDIATYPE_APPLICATION_COSE_SIGN     98 /* application/cose; cose-type="cose-sign"     */
233 #define COAP_MEDIATYPE_APPLICATION_COSE_SIGN1    18 /* application/cose; cose-type="cose-sign1"    */
234 #define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT  96 /* application/cose; cose-type="cose-encrypt"  */
235 #define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0 16 /* application/cose; cose-type="cose-encrypt0" */
236 #define COAP_MEDIATYPE_APPLICATION_COSE_MAC      97 /* application/cose; cose-type="cose-mac"      */
237 #define COAP_MEDIATYPE_APPLICATION_COSE_MAC0     17 /* application/cose; cose-type="cose-mac0"     */
238 
239 #define COAP_MEDIATYPE_APPLICATION_COSE_KEY     101 /* application/cose-key  */
240 #define COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET 102 /* application/cose-key-set  */
241 
242 /* Content formats from RFC 8428 */
243 #define COAP_MEDIATYPE_APPLICATION_SENML_JSON   110 /* application/senml+json  */
244 #define COAP_MEDIATYPE_APPLICATION_SENSML_JSON  111 /* application/sensml+json */
245 #define COAP_MEDIATYPE_APPLICATION_SENML_CBOR   112 /* application/senml+cbor  */
246 #define COAP_MEDIATYPE_APPLICATION_SENSML_CBOR  113 /* application/sensml+cbor */
247 #define COAP_MEDIATYPE_APPLICATION_SENML_EXI    114 /* application/senml-exi   */
248 #define COAP_MEDIATYPE_APPLICATION_SENSML_EXI   115 /* application/sensml-exi  */
249 #define COAP_MEDIATYPE_APPLICATION_SENML_XML    310 /* application/senml+xml   */
250 #define COAP_MEDIATYPE_APPLICATION_SENSML_XML   311 /* application/sensml+xml  */
251 
252 /* Content formats from RFC 8782 */
253 #define COAP_MEDIATYPE_APPLICATION_DOTS_CBOR    271 /* application/dots+cbor */
254 
255 /* Content formats from RFC 9200 */
256 #define COAP_MEDIATYPE_APPLICATION_ACE_CBOR      19 /* application/ace+cbor  */
257 
258 /* Content formats from RFC9177 */
259 #define COAP_MEDIATYPE_APPLICATION_MB_CBOR_SEQ  272 /* application/missing-blocks+cbor-seq */
260 
261 /* Content formats from RFC 8613 */
262 #define COAP_MEDIATYPE_APPLICATION_OSCORE     10001 /* application/oscore */
263 
264 /**
265  * coap_mid_t is used to store the CoAP Message ID of a CoAP PDU.
266  * Valid message ids are 0 to 2^16.  Negative values are error codes.
267  */
268 typedef int coap_mid_t;
269 
270 /** Indicates an invalid message id. */
271 #define COAP_INVALID_MID -1
272 
273 /**
274  * Indicates an invalid message id.
275  * @deprecated Use COAP_INVALID_MID instead.
276  */
277 #define COAP_INVALID_TID COAP_INVALID_MID
278 
279 /**
280  * @deprecated Use coap_optlist_t instead.
281  *
282  * Structures for more convenient handling of options. (To be used with ordered
283  * coap_list_t.) The option's data will be added to the end of the coap_option
284  * structure (see macro COAP_OPTION_DATA).
285  */
286 COAP_DEPRECATED typedef struct {
287   uint16_t key;           /* the option key (no delta coding) */
288   unsigned int length;
289 } coap_option;
290 
291 #define COAP_OPTION_KEY(option) (option).key
292 #define COAP_OPTION_LENGTH(option) (option).length
293 #define COAP_OPTION_DATA(option) ((unsigned char *)&(option) + sizeof(coap_option))
294 
295 #ifdef WITH_LWIP
296 /**
297  * Creates a CoAP PDU from an lwIP @p pbuf, whose reference is passed on to this
298  * function.
299  *
300  * The pbuf is checked for being contiguous, and for having only one reference.
301  * The reference is stored in the PDU and will be freed when the PDU is freed.
302  *
303  * (For now, these are fatal errors; in future, a new pbuf might be allocated,
304  * the data copied and the passed pbuf freed).
305  *
306  * This behaves like coap_pdu_init(0, 0, 0, pbuf->tot_len), and afterwards
307  * copying the contents of the pbuf to the pdu.
308  *
309  * @return A pointer to the new PDU object or @c NULL on error.
310  */
311 coap_pdu_t *coap_pdu_from_pbuf(struct pbuf *pbuf);
312 #endif
313 
314 /**
315 * CoAP protocol types
316 */
317 typedef enum coap_proto_t {
318   COAP_PROTO_NONE = 0,
319   COAP_PROTO_UDP,
320   COAP_PROTO_DTLS,
321   COAP_PROTO_TCP,
322   COAP_PROTO_TLS,
323   COAP_PROTO_WS,
324   COAP_PROTO_WSS,
325   COAP_PROTO_LAST
326 } coap_proto_t;
327 
328 /**
329  * Set of codes available for a PDU.
330  */
331 typedef enum coap_pdu_code_t {
332   COAP_EMPTY_CODE          = 0,
333 
334   COAP_REQUEST_CODE_GET    = COAP_REQUEST_GET,
335   COAP_REQUEST_CODE_POST   = COAP_REQUEST_POST,
336   COAP_REQUEST_CODE_PUT    = COAP_REQUEST_PUT,
337   COAP_REQUEST_CODE_DELETE = COAP_REQUEST_DELETE,
338   COAP_REQUEST_CODE_FETCH  = COAP_REQUEST_FETCH,
339   COAP_REQUEST_CODE_PATCH  = COAP_REQUEST_PATCH,
340   COAP_REQUEST_CODE_IPATCH = COAP_REQUEST_IPATCH,
341 
342   COAP_RESPONSE_CODE_CREATED                    = COAP_RESPONSE_CODE(201),
343   COAP_RESPONSE_CODE_DELETED                    = COAP_RESPONSE_CODE(202),
344   COAP_RESPONSE_CODE_VALID                      = COAP_RESPONSE_CODE(203),
345   COAP_RESPONSE_CODE_CHANGED                    = COAP_RESPONSE_CODE(204),
346   COAP_RESPONSE_CODE_CONTENT                    = COAP_RESPONSE_CODE(205),
347   COAP_RESPONSE_CODE_CONTINUE                   = COAP_RESPONSE_CODE(231),
348   COAP_RESPONSE_CODE_BAD_REQUEST                = COAP_RESPONSE_CODE(400),
349   COAP_RESPONSE_CODE_UNAUTHORIZED               = COAP_RESPONSE_CODE(401),
350   COAP_RESPONSE_CODE_BAD_OPTION                 = COAP_RESPONSE_CODE(402),
351   COAP_RESPONSE_CODE_FORBIDDEN                  = COAP_RESPONSE_CODE(403),
352   COAP_RESPONSE_CODE_NOT_FOUND                  = COAP_RESPONSE_CODE(404),
353   COAP_RESPONSE_CODE_NOT_ALLOWED                = COAP_RESPONSE_CODE(405),
354   COAP_RESPONSE_CODE_NOT_ACCEPTABLE             = COAP_RESPONSE_CODE(406),
355   COAP_RESPONSE_CODE_INCOMPLETE                 = COAP_RESPONSE_CODE(408),
356   COAP_RESPONSE_CODE_CONFLICT                   = COAP_RESPONSE_CODE(409),
357   COAP_RESPONSE_CODE_PRECONDITION_FAILED        = COAP_RESPONSE_CODE(412),
358   COAP_RESPONSE_CODE_REQUEST_TOO_LARGE          = COAP_RESPONSE_CODE(413),
359   COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT = COAP_RESPONSE_CODE(415),
360   COAP_RESPONSE_CODE_UNPROCESSABLE              = COAP_RESPONSE_CODE(422),
361   COAP_RESPONSE_CODE_TOO_MANY_REQUESTS          = COAP_RESPONSE_CODE(429),
362   COAP_RESPONSE_CODE_INTERNAL_ERROR             = COAP_RESPONSE_CODE(500),
363   COAP_RESPONSE_CODE_NOT_IMPLEMENTED            = COAP_RESPONSE_CODE(501),
364   COAP_RESPONSE_CODE_BAD_GATEWAY                = COAP_RESPONSE_CODE(502),
365   COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE        = COAP_RESPONSE_CODE(503),
366   COAP_RESPONSE_CODE_GATEWAY_TIMEOUT            = COAP_RESPONSE_CODE(504),
367   COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED     = COAP_RESPONSE_CODE(505),
368   COAP_RESPONSE_CODE_HOP_LIMIT_REACHED          = COAP_RESPONSE_CODE(508),
369 
370   COAP_SIGNALING_CODE_CSM                       = COAP_SIGNALING_CSM,
371   COAP_SIGNALING_CODE_PING                      = COAP_SIGNALING_PING,
372   COAP_SIGNALING_CODE_PONG                      = COAP_SIGNALING_PONG,
373   COAP_SIGNALING_CODE_RELEASE                   = COAP_SIGNALING_RELEASE,
374   COAP_SIGNALING_CODE_ABORT                     = COAP_SIGNALING_ABORT
375 } coap_pdu_code_t;
376 
377 /**
378  * Creates a new CoAP PDU with at least enough storage space for the given
379  * @p size maximum message size. The function returns a pointer to the
380  * node coap_pdu_t object on success, or @c NULL on error. The storage allocated
381  * for the result must be released with coap_delete_pdu() if coap_send()
382  * is not called.
383  *
384  * @param type The type of the PDU (one of COAP_MESSAGE_CON, COAP_MESSAGE_NON,
385  *             COAP_MESSAGE_ACK, COAP_MESSAGE_RST).
386  * @param code The message code of the PDU.
387  * @param mid  The message id to set or 0 if unknown / not applicable.
388  * @param size The maximum allowed number of byte for the message.
389  * @return     A pointer to the new PDU object or @c NULL on error.
390  */
391 coap_pdu_t *coap_pdu_init(coap_pdu_type_t type, coap_pdu_code_t code,
392                           coap_mid_t mid, size_t size);
393 
394 /**
395  * Creates a new CoAP PDU.
396  *
397  * @param type The type of the PDU (one of COAP_MESSAGE_CON, COAP_MESSAGE_NON,
398  *             COAP_MESSAGE_ACK, COAP_MESSAGE_RST).
399  * @param code The message code of the PDU.
400  * @param session The session that will be using this PDU
401  *
402  * @return The skeletal PDU or @c NULL if failure.
403  */
404 coap_pdu_t *coap_new_pdu(coap_pdu_type_t type, coap_pdu_code_t code,
405                          coap_session_t *session);
406 
407 /**
408  * Dispose of an CoAP PDU and frees associated storage.
409  * Not that in general you should not call this function directly.
410  * When a PDU is sent with coap_send(), coap_delete_pdu() will be called
411  * automatically for you.
412  *
413  * @param pdu The PDU for free off.
414  */
415 void coap_delete_pdu(coap_pdu_t *pdu);
416 
417 /**
418  * Duplicate an existing PDU. Specific options can be ignored and not copied
419  * across.  The PDU data payload is not copied across.
420  *
421  * @param old_pdu      The PDU to duplicate
422  * @param session      The session that will be using this PDU.
423  * @param token_length The length of the token to use in this duplicated PDU.
424  * @param token        The token to use in this duplicated PDU.
425  * @param drop_options A list of options not to copy into the duplicated PDU.
426  *                     If @c NULL, then all options are copied across.
427  *
428  * @return The duplicated PDU or @c NULL if failure.
429  */
430 coap_pdu_t *coap_pdu_duplicate(const coap_pdu_t *old_pdu,
431                                coap_session_t *session,
432                                size_t token_length,
433                                const uint8_t *token,
434                                coap_opt_filter_t *drop_options);
435 
436 /**
437  * Parses @p data into the CoAP PDU structure given in @p result.
438  * The target pdu must be large enough to hold the token, options and data.
439  * This function returns @c 0 on error or a number greater than zero on success.
440  *
441  * @param proto   Session's protocol
442  * @param data    The raw data to parse as CoAP PDU.
443  * @param length  The actual size of @p data.
444  * @param pdu     The PDU structure to fill. Note that the structure must
445  *                provide space to hold the token, optional options and
446  *                optional data.
447  *
448  * @return       1 on success or @c 0 on error.
449  */
450 int coap_pdu_parse(coap_proto_t proto,
451                    const uint8_t *data,
452                    size_t length,
453                    coap_pdu_t *pdu);
454 
455 /**
456  * Adds token of length @p len to @p pdu.
457  *
458  * This function will fail if a token has already been added to the @p pdu.
459  *
460  * Hence options and data must be added after optional coap_add_token() has
461  * been called.
462  *
463  * @param pdu  The PDU where the token is to be added.
464  * @param len  The length of the new token.
465  * @param data The token to add.
466  *
467  * @return     A value greater than zero on success, or @c 0 on error.
468  */
469 int coap_add_token(coap_pdu_t *pdu,
470                    size_t len,
471                    const uint8_t *data);
472 
473 /**
474  * Adds option of given @p number to @p pdu that is passed as first
475  * parameter.
476  *
477  * This function will fail if data has already been added to the @p pdu.
478  *
479  * Hence data must be added after optional coap_add_option() has been called.
480  *
481  * Note: Where possible, the option data needs to be stripped of leading zeros
482  * (big endian) to reduce the amount of data needed in the PDU, as well as in
483  * some cases the maximum data size of an opton can be exceeded if not stripped
484  * and hence be illegal.  This is done by using coap_encode_var_safe() or
485  * coap_encode_var_safe8().
486  *
487  * @param pdu    The PDU where the option is to be added.
488  * @param number The number of the new option.
489  * @param len    The length of the new option.
490  * @param data   The data of the new option.
491  *
492  * @return The overall length of the option or @c 0 on failure.
493  */
494 size_t coap_add_option(coap_pdu_t *pdu,
495                        coap_option_num_t number,
496                        size_t len,
497                        const uint8_t *data);
498 
499 /**
500  * Adds given data to the pdu that is passed as first parameter.
501  *
502  * This function will fail if data has already been added to the @p pdu.
503  *
504  * @param pdu    The PDU where the data is to be added.
505  * @param len    The length of the data.
506  * @param data   The data to add.
507  *
508  * @return @c 1 if success, else @c 0 if failure.
509  */
510 int coap_add_data(coap_pdu_t *pdu,
511                   size_t len,
512                   const uint8_t *data);
513 
514 /**
515  * Adds given data to the pdu that is passed as first parameter but does not
516  *
517  * This function will fail if data has already been added to the @p pdu.
518  *
519  * The actual data must be copied at the returned location.
520  *
521  * @param pdu    The PDU where the data is to be added.
522  * @param len    The length of the data.
523  *
524  * @return Where to copy the data of len to, or @c NULL is error.
525  */
526 uint8_t *coap_add_data_after(coap_pdu_t *pdu, size_t len);
527 
528 /**
529  * Retrieves the length and data pointer of specified PDU. Returns 0 on error or
530  * 1 if *len and *data have correct values. Note that these values are destroyed
531  * with the pdu.
532  *
533  * @param pdu    The specified PDU.
534  * @param len    Returns the length of the current data
535  * @param data   Returns the ptr to the current data
536  *
537  * @return @c 1 if len and data are correctly filled in, else
538  *         @c 0 if there is no data.
539  */
540 int coap_get_data(const coap_pdu_t *pdu,
541                   size_t *len,
542                   const uint8_t **data);
543 
544 /**
545  * Retrieves the data from a PDU, with support for large bodies of data that
546  * spans multiple PDUs.
547  *
548  * Note: The data pointed to on return is destroyed when the PDU is destroyed.
549  *
550  * @param pdu    The specified PDU.
551  * @param len    Returns the length of the current data
552  * @param data   Returns the ptr to the current data
553  * @param offset Returns the offset of the current data from the start of the
554  *               body comprising of many blocks (RFC7959)
555  * @param total  Returns the total size of the body.
556  *               If offset + length < total, then there is more data to follow.
557  *
558  * @return @c 1 if len, data, offset and total are correctly filled in, else
559  *         @c 0 if there is no data.
560  */
561 int coap_get_data_large(const coap_pdu_t *pdu,
562                         size_t *len,
563                         const uint8_t **data,
564                         size_t *offset,
565                         size_t *total);
566 
567 /**
568  * Gets the PDU code associated with @p pdu.
569  *
570  * @param pdu The PDU object.
571  *
572  * @return The PDU code.
573  */
574 coap_pdu_code_t coap_pdu_get_code(const coap_pdu_t *pdu);
575 
576 /**
577  * Sets the PDU code in the @p pdu.
578  *
579  * @param pdu The PDU object.
580  * @param code The code to set in the PDU.
581  */
582 void coap_pdu_set_code(coap_pdu_t *pdu, coap_pdu_code_t code);
583 
584 /**
585  * Gets the PDU type associated with @p pdu.
586  *
587  * @param pdu The PDU object.
588  *
589  * @return The PDU type.
590  */
591 coap_pdu_type_t coap_pdu_get_type(const coap_pdu_t *pdu);
592 
593 /**
594  * Sets the PDU type in the @p pdu.
595  *
596  * @param pdu The PDU object.
597  * @param type The type to set for the PDU.
598  */
599 void coap_pdu_set_type(coap_pdu_t *pdu, coap_pdu_type_t type);
600 
601 /**
602  * Gets the token associated with @p pdu.
603  *
604  * @param pdu The PDU object.
605  *
606  * @return The token information.
607  */
608 coap_bin_const_t coap_pdu_get_token(const coap_pdu_t *pdu);
609 
610 /**
611  * Gets the message id associated with @p pdu.
612  *
613  * @param pdu The PDU object.
614  *
615  * @return The message id.
616  */
617 coap_mid_t coap_pdu_get_mid(const coap_pdu_t *pdu);
618 
619 size_t coap_pdu_get_used_size(const coap_pdu_t *pdu);
620 size_t coap_pdu_get_max_size(const coap_pdu_t *pdu);
621 
622 /**
623  * Sets the message id in the @p pdu.
624  *
625  * @param pdu The PDU object.
626  * @param mid The message id value to set in the PDU.
627  *
628  */
629 void coap_pdu_set_mid(coap_pdu_t *pdu, coap_mid_t mid);
630 
631 /** @} */
632 
633 #endif /* COAP_PDU_H_ */
634