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