• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// -*- mode:doc; -*-
2// vim: set syntax=asciidoc,tw=0:
3
4coap_pdu_setup(3)
5=================
6:doctype: manpage
7:man source:   coap_pdu_setup
8:man version:  @PACKAGE_VERSION@
9:man manual:   libcoap Manual
10
11NAME
12----
13coap_pdu_setup,
14coap_new_pdu,
15coap_pdu_init,
16coap_session_init_token,
17coap_session_new_token,
18coap_add_token,
19coap_new_optlist,
20coap_insert_optlist,
21coap_delete_optlist,
22coap_encode_var_safe,
23coap_encode_var_safe8,
24coap_add_optlist_pdu,
25coap_add_option,
26coap_add_data,
27coap_add_data_blocked_response,
28coap_send,
29coap_split_path,
30coap_split_query,
31coap_pdu_set_mid,
32coap_pdu_set_code,
33coap_pdu_set_type
34- Setting up CoAP PDUs
35
36SYNOPSIS
37--------
38*#include <coap@LIBCOAP_API_VERSION@/coap.h>*
39
40*coap_pdu_t *coap_new_pdu(coap_pdu_type_t _type_, coap_pdu_code_t _code_,
41coap_session_t *_session_);*
42
43*coap_pdu_t *coap_pdu_init(coap_pdu_type_t _type_, coap_pdu_code_t _code_,
44coap_mid_t _message_id_, size_t _max_size_);*
45
46*void coap_session_init_token(coap_session_t *_session_, size_t _length_,
47const uint8_t *_token_);*
48
49*void coap_session_new_token(coap_session_t *_session_, size_t *_length_,
50uint8_t *_token_);*
51
52*int coap_add_token(coap_pdu_t *_pdu_, size_t _length_,
53const uint8_t *_data_);*
54
55*coap_optlist_t *coap_new_optlist(uint16_t _number_, size_t _length_,
56const uint8_t *_data_);*
57
58*int coap_insert_optlist(coap_optlist_t **_optlist_chain_,
59coap_optlist_t *_optlist_);*
60
61*void coap_delete_optlist(coap_optlist_t *_optlist_chain_);*
62
63*unsigned int coap_encode_var_safe(uint8_t *_buffer_, size_t _size_,
64unsigned int _value_);*
65
66*unsigned int coap_encode_var_safe8(uint8_t *_buffer_, size_t _size_,
67uint64_t _value_);*
68
69*int coap_add_optlist_pdu(coap_pdu_t *_pdu_, coap_optlist_t **_optlist_chain_);*
70
71*size_t coap_add_option(coap_pdu_t *_pdu_, uint16_t _number_, size_t _length_,
72const uint8_t *_data_);*
73
74*int coap_add_data(coap_pdu_t *_pdu_, size_t _length_, const uint8_t *_data_);*
75
76*void coap_add_data_blocked_response(const coap_pdu_t *_request_,
77coap_pdu_t *_response_, uint16_t _media_type_, int _maxage_, size_t _length_,
78const uint8_t *_data_);*
79
80*coap_mid_t coap_send(coap_session_t *_session_, coap_pdu_t *_pdu_);*
81
82*int coap_split_path(const uint8_t *_path_, size_t _length_, uint8_t *_buffer_,
83size_t *_buflen_);*
84
85*int coap_split_query(const uint8_t *_query_, size_t _length_,
86uint8_t *_buffer_, size_t *_buflen_);*
87
88*void coap_pdu_set_mid(coap_pdu_t *_pdu_, coap_mid_t _mid_);*
89
90*void coap_pdu_set_code(coap_pdu_t *_pdu_, coap_pdu_code_t _code_);*
91
92*void coap_pdu_set_type(coap_pdu_t *_pdu_, coap_pdu_type_t _type_);*
93
94For specific (D)TLS library support, link with
95*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*,
96*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls*
97or *-lcoap-@LIBCOAP_API_VERSION@-tinydtls*.   Otherwise, link with
98*-lcoap-@LIBCOAP_API_VERSION@* to get the default (D)TLS library support.
99
100DESCRIPTION
101-----------
102The CoAP PDU is of the form
103
104--header--|--optional token--|--optional options--|--optional payload--
105
106The terminology used is taken mainly from
107https://tools.ietf.org/html/rfc7252#section-1.2
108
109The PDU must be built in the correct order, from left to right.  In particular,
110the options need to be added in the correct numerical option order as they are
111stored in the PDU using relative numeric offsets from the previous option
112number.
113
114There are option list functions available where options can be added to a
115chained list of options and then the chain list is sorted and then be added to
116the PDU.
117
118Typically for clients, when creating a request, the PDU needs to be created
119before filling it with the appropriate information.
120
121Typically with a server, the response PDU, with the optional token already added
122in, will already be created before the response handler is called, and the
123response PDU will need to be updated as appropriate starting with the optional
124options.  Note that updating the response pdu's code variable will cause the
125response pdu to get transmitted.  If code does not get updated, and the PDU is
126of type CONFIRMABLE, then the response PDU is transmitted as an empty ACK
127packet. The response pdu is always freed off by the underlying library.
128
129For handling situations where the data to be transmitted does not fit into a
130single packet, see coap_block(3).
131
132*Create and Header:*
133
134The *coap_new_pdu*() function returns a newly created PDU of type
135_coap_pdu_t_*.  The _type_ is one of the following
136
137[source, c]
138----
139COAP_MESSAGE_CON Set the _PDU_ to be of type confirmable.
140COAP_MESSAGE_NON Set the _PDU_ to be of type non-confirmable.
141COAP_MESSAGE_ACK Set the _PDU_ to be of type acknowledge (for internal use).
142COAP_MESSAGE_RST Set the _PDU_ to be of type reset.
143----
144
145The _code_ is one of the following
146
147[source, c]
148----
149COAP_EMPTY_CODE                               0.00
150COAP_REQUEST_CODE_GET                         0.01
151COAP_REQUEST_CODE_POST                        0.02
152COAP_REQUEST_CODE_PUT                         0.03
153COAP_REQUEST_CODE_DELETE                      0.04
154COAP_REQUEST_CODE_FETCH                       0.05
155COAP_REQUEST_CODE_PATCH                       0.06
156COAP_REQUEST_CODE_IPATCH                      0.07
157COAP_RESPONSE_CODE_OK                         2.00
158COAP_RESPONSE_CODE_CREATED                    2.01
159COAP_RESPONSE_CODE_DELETED                    2.02
160COAP_RESPONSE_CODE_VALID                      2.03
161COAP_RESPONSE_CODE_CHANGED                    2.04
162COAP_RESPONSE_CODE_CONTENT                    2.05
163COAP_RESPONSE_CODE_CONTINUE                   2.31
164COAP_RESPONSE_CODE_BAD_REQUEST                4.00
165COAP_RESPONSE_CODE_UNAUTHORIZED               4.01
166COAP_RESPONSE_CODE_BAD_OPTION                 4.02
167COAP_RESPONSE_CODE_FORBIDDEN                  4.03
168COAP_RESPONSE_CODE_NOT_FOUND                  4.04
169COAP_RESPONSE_CODE_NOT_ALLOWED                4.05
170COAP_RESPONSE_CODE_NOT_ACCEPTABLE             4.06
171COAP_RESPONSE_CODE_INCOMPLETE                 4.08
172COAP_RESPONSE_CODE_CONFLICT                   4.09
173COAP_RESPONSE_CODE_PRECONDITION_FAILED        4.12
174COAP_RESPONSE_CODE_REQUEST_TOO_LARGE          4.13
175COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT 4.15
176COAP_RESPONSE_CODE_UNPROCESSABLE              4.22
177COAP_RESPONSE_CODE_TOO_MANY_REQUESTS          4.29
178COAP_RESPONSE_CODE_INTERNAL_ERROR             5.00
179COAP_RESPONSE_CODE_NOT_IMPLEMENTED            5.01
180COAP_RESPONSE_CODE_BAD_GATEWAY                5.02
181COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE        5.03
182COAP_RESPONSE_CODE_GATEWAY_TIMEOUT            5.04
183COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED     5.05
184COAP_RESPONSE_CODE_HOP_LIMIT_REACHED          5.08
185COAP_SIGNALING_CODE_CSM                       7.01
186COAP_SIGNALING_CODE_PING                      7.02
187COAP_SIGNALING_CODE_PONG                      7.03
188COAP_SIGNALING_CODE_RELEASE                   7.04
189COAP_SIGNALING_CODE_ABORT                     7.05
190----
191
192and _session_ is used to set up other default values.
193
194The *coap_pdu_init*() function does the same work as *coap_new_pdu*() but gives
195the additional ability to define the default values for _message_id_ and
196_max_size_ that *coap_new_pdu*() creates.
197
198The _message_id_ must be unique per request (which is not the same as the
199token), and must not be reused within EXCHANGE_LIFETIME (usually 247 seconds).
200To automate this, the function coap_new_message_id(session) should be called.
201
202At the CoAP protocol level, requests and responses are matched by _message_id_
203which is why it needs to be unique.  At the application level, for "separate"
204responses, the initial empty ACK response matches the _message_id_ of the
205request (handled by libcoap) but the actual response has the same token as the
206request and this must be used for the match.  For "piggybacked" responses the
207token must still be used as the valid match for request and response. and the
208_message_id_ just happens to match (but unsafe in case the server is sending
209back a "separate" response).
210
211The _max_size_ parameter defines the maximum size of a _PDU_ and is usually
212determined by calling coap_session_max_pdu_size(session);
213
214The *coap_pdu_set_mid*() function is used to set the message id _mid_ in the
215PDU _pdu_.
216
217The *coap_pdu_set_code*() function is used to set the code _code_ in the PDU
218_pdu_.
219
220The *coap_pdu_set_type*() function is used to set the _type_ of the PDU _pdu_.
221
222*Token:*
223
224The *coap_session_init_token*() function is used to initialize the starting
225_token_ of _length_ for the _session_.
226
227The *coap_session_new_token*() function is used to obtain the next available
228_token_ of _length_ for the _session_.  Note that the same token must be used
229for doing an observe cancellation that was used for doing the observe
230registration.  Otherwise tokens should be unique for each request/response so
231that they can be correctly matched.
232
233The *coap_add_token*() function adds in the specified token's _data_ of length
234_length_ to the PDU _pdu_.  The maximum length of the token is 8 bytes.
235Adding the token must be done before any options or data are added.
236This function must only be called once per _pdu_, and must not be called
237in the appropriate response handler.
238
239If a token is not added, then the token in the PDU is zero length, but still a
240valid token which is used for matching.  The exception is an empty ACK packet.
241
242*Options:*
243
244The *coap_new_optlist*() function returns a newly created _optlist_ entry of
245type _coap_optlist_t_*.  The _number_ specifies which CoAP option is to be
246used, and is one of the COAP_OPTION_* definitions.  The _length_ is the length
247of the data of the option, and _data_ points to the content of the option.
248
249*NOTE:* Where possible, the option data needs to be stripped of leading zeros
250(big endian) to reduce the amount of data needed in the PDU, as well as in
251some cases the maximum data size of an opton can be exceeded if not stripped
252and hence be illegal.  This is done by using coap_encode_var_safe() or
253coap_encode_var_safe8().
254
255The following is the current list of options with their numeric value
256----
257/*
258 * The C, U, and N flags indicate the properties
259 * Critical, Unsafe, and NoCacheKey, respectively.
260 * If U is set, then N has no meaning as per
261 * https://tools.ietf.org/html/rfc7252#section-5.10
262 * and is set to a -.
263 * Separately, R is for the options that can be repeated
264 *
265 * The least significant byte of the option is set as followed
266 * as per https://tools.ietf.org/html/rfc7252#section-5.4.6
267 *
268 *   0   1   2   3   4   5   6   7
269 * --+---+---+---+---+---+---+---+
270 *           | NoCacheKey| U | C |
271 * --+---+---+---+---+---+---+---+
272 *
273 * https://tools.ietf.org/html/rfc8613#section-4 goes on to define E, I and U
274 * properties Encrypted and Integrity Protected, Integrity Protected Only and
275 * Unprotected respectively.  Integrity Protected Only is not currently used.
276 *
277 * An Option is tagged with CUNREIU with any of the letters replaced with _ if
278 * not set, or - for N if U is set (see above) for aiding understanding of the
279 * Option.
280 */
281
282COAP_OPTION_IF_MATCH        1 /* C__RE__, opaque,    0-8 B, RFC7252 */
283COAP_OPTION_URI_HOST        3 /* CU-___U, String,  1-255 B, RFC7252 */
284COAP_OPTION_ETAG            4 /* ___RE__, opaque,    1-8 B, RFC7252 */
285ION_IF_NONE_MATCH   5 /* C___E__, empty,       0 B, RFC7252 */
286COAP_OPTION_OBSERVE         6 /* _U-_E_U, empty/uint,  0 B/0-3 B, RFC7641 */
287COAP_OPTION_URI_PORT        7 /* CU-___U, uint,      0-2 B, RFC7252 */
288COAP_OPTION_LOCATION_PATH   8 /* ___RE__, String,  0-255 B, RFC7252 */
289COAP_OPTION_OSCORE          9 /* C_____U, *,       0-255 B, RFC8613 */
290COAP_OPTION_URI_PATH       11 /* CU-RE__, String,  0-255 B, RFC7252 */
291COAP_OPTION_CONTENT_FORMAT 12 /* ____E__, uint,      0-2 B, RFC7252 */
292/* COAP_OPTION_MAXAGE default 60 seconds if not set */
293COAP_OPTION_MAXAGE         14 /* _U-_E_U, uint,      0-4 B, RFC7252 */
294COAP_OPTION_URI_QUERY      15 /* CU-RE__, String,  1-255 B, RFC7252 */
295COAP_OPTION_HOP_LIMIT      16 /* ______U, uint,        1 B, RFC8768 */
296COAP_OPTION_ACCEPT         17 /* C___E__, uint,      0-2 B, RFC7252 */
297COAP_OPTION_LOCATION_QUERY 20 /* ___RE__, String,  0-255 B, RFC7252 */
298COAP_OPTION_BLOCK2         23 /* CU-_E_U, uint,      0-3 B, RFC7959 */
299COAP_OPTION_BLOCK1         27 /* CU-_E_U, uint,      0-3 B, RFC7959 */
300COAP_OPTION_SIZE2          28 /* __N_E_U, uint,      0-4 B, RFC7959 */
301COAP_OPTION_PROXY_URI      35 /* CU-___U, String, 1-1034 B, RFC7252 */
302COAP_OPTION_PROXY_SCHEME   39 /* CU-___U, String,  1-255 B, RFC7252 */
303COAP_OPTION_SIZE1          60 /* __N_E_U, uint,      0-4 B, RFC7252 */
304COAP_OPTION_NORESPONSE    258 /* _U-_E_U, uint,      0-1 B, RFC7967 */
305----
306See FURTHER INFORMATION as to how to get the latest list.
307
308The *coap_insert_optlist*() function adds the _optlist_ entry onto the
309_optlist_chain_ and then sorts the _optlist_chain_ before returning.
310The initial _optlist_chain_ entry needs to be set to NULL before this function
311is first called.  The coap_delete_optlist() function has to be called to free
312off all the _optlist_chain_ entries.
313
314The *coap_delete_optlist*() function deletes and frees off all the optlist
315entries in the _optlist_chain_.
316
317The *coap_add_optlist_pdu*() function sorts all of the entries in
318_optlist_chain_ into ascending option numeric order and adds all the entries
319to the _pdu_.  This function does not free off the entries in _optlist_chain_.
320This function must be called after adding any token and before adding in the
321payload data.
322
323The *coap_add_option*() function adds in the specified option of type _number_
324with _data_ of length _length_ to the PDU _pdu_.
325It is important that options are added to the _pdu_ with _number_ either
326being the same or greater than the previous option _number_ that was added.
327
328*NOTE:* Where possible, the option data needs to be stripped of leading zeros
329(big endian) to reduce the amount of data needed in the PDU, as well as in
330some cases the maximum data size of an opton can be exceeded if not stripped
331and hence be illegal.  This is done by using coap_encode_var_safe() or
332coap_encode_var_safe8().
333
334The *coap_encode_var_safe*() function encodes _value_ into _buffer_ which has
335a size of _size_ in bytes.  Normally, the _buffer_ size should be at least
336the sizeof(int) bytes unless you definitely know less space is required.
337
338The *coap_encode_var_safe8*() function encodes 8 byte _value_ into _buffer_
339which has a size of _size_ in bytes.  Normally, the _buffer_ size should be at
340least 8 bytes unless you definitely know less space is required.
341
342The *coap_split_path*() function splits up _path_ of length _length_ and
343places the result in _buffer_ which has a size of _buflen_.  _buflen_ needs
344to be preset with the size of _buffer_ before the function call, and then
345_buflen_ is updated with the actual size of _buffer_ used.
346
347The *coap_split_query*() function splits up _query_ of length _length_ and
348places the result in _buffer_ which has a size of _buflen_.  _buflen_ needs
349to be preset with the size of _buffer_ before the function call, and then
350_buflen_ is updated with the actual size of _buffer_ used.
351
352*Payload Data:*
353
354The *coap_add_data*() function adds in the specified payload _data_ of length
355_length_ to the PDU _pdu_. Adding the payload data must be done after any
356token or options are added.  This function must only be called once per _pdu_.
357
358The *coap_add_data_blocked_response*() function adds in the appropriate part
359of the payload _data_ of length _length_ to the PDU _pdu_. It should be used
360as a direct replacement for *coap_add_data*() if it is possible that the data
361will not fit into a single pdu. It also adds in the appropriate
362CoAP options to handle Block-Wise transfer. This function is usually used for
363a server's GET / FETCH response.  The _request_ and _response_ are the same
364parameters for the registered GET / FETCH resource handler.
365The _media_type_ is for the format of the _data_ and _maxage_ defines the
366lifetime of the response.  If set to -1,  then the MAXAGE option does not get
367included.  This function must only be called once per _pdu_.
368It is the responsibility of the client to recognize that it has only
369received a part of the data and request the next block (with the appropriate
370Block options) from the server.  Returning the next requested block is handled
371by this function.
372
373*NOTE:* This function has been superseded by *coap_add_data_response_large*().
374See coap_block(3).
375
376*Transmit:*
377
378The *coap_send*() function is used to initiate the transmission of the _pdu_
379associated with the _session_.
380
381RETURN VALUES
382-------------
383The *coap_new_pdu*() and *coap_pdu_init*() function returns a newly created
384_PDU_ or NULL if there is a malloc or parameter failure.
385
386The *coap_new_optlist*() function returns a newly created _optlist_ or NULL
387if there is a malloc failure.
388
389The *coap_add_token*(), *coap_insert_optlist*(), *coap_delete_optlist*(),
390*coap_add_optlist_pdu*() and *coap_add_data*()
391functions return 0 on failure, 1 on success.
392
393The *coap_add_optlist*() function returns either the length of the option
394or 0 on failure.
395
396The *coap_encode_var_safe*() function returns either the length of bytes
397encoded or 0 on failure.
398
399The *coap_encode_var_safe8*() function returns either the length of bytes
400encoded or 0 on failure.
401
402The *coap_send*() function returns the CoAP message ID on success or
403COAP_INVALID_MID on failure.
404
405EXAMPLES
406--------
407*Setup PDU and Transmit*
408
409[source, c]
410----
411#include <coap@LIBCOAP_API_VERSION@/coap.h>
412
413static int
414build_send_pdu(coap_context_t *context, coap_session_t *session,
415uint8_t msgtype, uint8_t request_code, const char *uri, const char *query,
416unsigned char *data, size_t length, int observe) {
417
418  coap_pdu_t *pdu;
419  uint8_t buf[1024];
420  size_t buflen;
421  uint8_t *sbuf = buf;
422  int res;
423  coap_optlist_t *optlist_chain = NULL;
424  /* Remove (void) definition if variable is used */
425  (void)context;
426
427  /* Create the pdu with the appropriate options */
428  pdu = coap_pdu_init(msgtype, request_code, coap_new_message_id(session),
429                      coap_session_max_pdu_size(session));
430  if (!pdu)
431    return 0;
432
433  /*
434   * Create unique token for this request for handling unsolicited /
435   * delayed responses
436   */
437  coap_session_new_token(session, &buflen, buf);
438  if (!coap_add_token(pdu, buflen, buf)) {
439    coap_log(LOG_DEBUG, "cannot add token to request\n");
440    goto error;
441  }
442
443  if (uri) {
444    /* Add in the URI options */
445    buflen = sizeof(buf);
446    res = coap_split_path((const uint8_t*)uri, strlen(uri), sbuf, &buflen);
447    while (res--) {
448      if (!coap_insert_optlist(&optlist_chain,
449                               coap_new_optlist(COAP_OPTION_URI_PATH,
450                        coap_opt_length(sbuf), coap_opt_value(sbuf))))
451        goto error;
452      sbuf += coap_opt_size(sbuf);
453    }
454  }
455
456  if (query) {
457    /* Add in the QUERY options */
458    buflen = sizeof(buf);
459    res = coap_split_query((const uint8_t*)query, strlen(query), sbuf, &buflen);
460    while (res--) {
461      if (!coap_insert_optlist(&optlist_chain,
462                               coap_new_optlist(COAP_OPTION_URI_QUERY,
463                        coap_opt_length(sbuf), coap_opt_value(sbuf))))
464        goto error;
465      sbuf += coap_opt_size(sbuf);
466    }
467  }
468
469  if (request_code == COAP_REQUEST_GET && observe) {
470    /* Indicate that we want to observe this resource */
471    if (!coap_insert_optlist(&optlist_chain,
472                             coap_new_optlist(COAP_OPTION_OBSERVE,
473                               coap_encode_var_safe(buf, sizeof(buf),
474                               COAP_OBSERVE_ESTABLISH), buf)
475                             ))
476      goto error;
477  }
478
479  /* ... Other code / options etc. ... */
480
481  /* Add in all the options (after internal sorting) to the pdu */
482  if (!coap_add_optlist_pdu(pdu, &optlist_chain))
483    goto error;
484
485  if (data && length) {
486    /* Add in the specified data */
487    if (!coap_add_data(pdu, length, data))
488      goto error;
489  }
490
491  if (coap_send(session, pdu) == COAP_INVALID_MID)
492    goto error;
493  return 1;
494
495error:
496
497  if (pdu)
498    coap_delete_pdu(pdu);
499  return 0;
500
501}
502----
503
504*Resource Handler Response PDU Update*
505
506[source, c]
507----
508#include <coap@LIBCOAP_API_VERSION@/coap.h>
509
510#include <stdio.h>
511
512static void
513hnd_get_time(coap_resource_t *resource, coap_session_t *session,
514const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
515
516  unsigned char buf[40];
517  size_t len;
518  time_t now;
519
520  /* ... Additional analysis code for resource, request pdu etc.  ... */
521
522  /* After analysis, generate a suitable response */
523
524  now = time(NULL);
525
526  if (query != NULL && coap_string_equal(query, coap_make_str_const("secs"))) {
527    /* Output secs since Jan 1 1970 */
528    len = snprintf((char *)buf, sizeof(buf), "%lu", now);
529  }
530  else {
531    /* Output human-readable time */
532    struct tm *tmp;
533    tmp = gmtime(&now);
534    if (!tmp) {
535      /* If 'now' is not valid */
536      coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
537      return;
538    }
539    len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp);
540  }
541  coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
542  /*
543   * Invoke coap_add_data_large_response() to do all the hard work.
544   *
545   * Define the format - COAP_MEDIATYPE_TEXT_PLAIN - to add in
546   * Define how long this response is valid for (secs) - 1 - to add in.
547   * ETAG Option added internally with unique value as param set to 0
548   *
549   * OBSERVE Option added internally if needed within the function
550   * BLOCK2 Option added internally if output too large
551   * SIZE2 Option added internally
552   */
553  coap_add_data_large_response(resource, session, request, response,
554                               query, COAP_MEDIATYPE_TEXT_PLAIN, 1, 0,
555                               len,
556                               buf, NULL, NULL);
557
558}
559----
560
561SEE ALSO
562--------
563*coap_block*(3), *coap_observe*(3), *coap_pdu_access*(3) and *coap_resource*(3)
564
565FURTHER INFORMATION
566-------------------
567See
568
569"RFC7252: The Constrained Application Protocol (CoAP)"
570
571"RFC7959: Block-Wise Transfers in the Constrained Application Protocol (CoAP)"
572
573for further information.
574
575See https://www.iana.org/assignments/core-parameters/core-parameters.xhtml#option-numbers
576for the current set of defined CoAP Options.
577
578BUGS
579----
580Please report bugs on the mailing list for libcoap:
581libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
582https://github.com/obgm/libcoap/issues
583
584AUTHORS
585-------
586The libcoap project <libcoap-developers@lists.sourceforge.net>
587