Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
COAP_PDU_SETUP(3)		 libcoap Manual 	       COAP_PDU_SETUP(3)

NAME
     coap_pdu_setup, coap_new_pdu, coap_pdu_init, coap_new_message_id, coap_ses-
     sion_init_token,  coap_session_new_token, coap_add_token, coap_new_optlist,
     coap_insert_optlist,  coap_delete_optlist,  coap_encode_var_safe,	coap_en-
     code_var_safe8,   coap_add_optlist_pdu,   coap_add_option,   coap_add_data,
     coap_add_data_blocked_response,	 coap_send,	 coap_path_into_optlist,
     coap_split_path,	      coap_query_into_optlist,	       coap_split_query,
     coap_pdu_set_mid, coap_pdu_set_code, coap_pdu_set_type -  Setting	up  CoAP
     PDUs

SYNOPSIS
     #include <coap3/coap.h>

     coap_pdu_t   *coap_new_pdu(coap_pdu_type_t   type,   coap_pdu_code_t  code,
     coap_session_t *session);

     coap_pdu_t  *coap_pdu_init(coap_pdu_type_t  type,	 coap_pdu_code_t   code,
     coap_mid_t message_id, size_t max_size);

     uint16_t coap_new_message_id(coap_session_t *session);

     void  coap_session_init_token(coap_session_t *session, size_t length, const
     uint8_t *token);

     void  coap_session_new_token(coap_session_t   *session,   size_t	*length,
     uint8_t *token);

     int coap_add_token(coap_pdu_t *pdu, size_t length, const uint8_t *data);

     coap_optlist_t  *coap_new_optlist(uint16_t  number,  size_t  length,  const
     uint8_t *data);

     int  coap_insert_optlist(coap_optlist_t   **optlist_chain,   coap_optlist_t
     *optlist);

     void coap_delete_optlist(coap_optlist_t *optlist_chain);

     unsigned  int  coap_encode_var_safe(uint8_t  *buffer, size_t size, unsigned
     int value);

     unsigned int coap_encode_var_safe8(uint8_t *buffer, size_t  size,	uint64_t
     value);

     int coap_add_optlist_pdu(coap_pdu_t *pdu, coap_optlist_t **optlist_chain);

     size_t  coap_add_option(coap_pdu_t  *pdu,	uint16_t  number, size_t length,
     const uint8_t *data);

     int coap_add_data(coap_pdu_t *pdu, size_t length, const uint8_t *data);

     void coap_add_data_blocked_response(const coap_pdu_t  *request,  coap_pdu_t
     *response,  uint16_t  media_type,	int maxage, size_t length, const uint8_t
     *data);

     coap_mid_t coap_send(coap_session_t *session, coap_pdu_t *pdu);

     int coap_path_into_optlist(const uint8_t  *path,  size_t  length,	coap_op-
     tion_num_t optnum, coap_optlist_t **optlist_chain);

     int  coap_split_path(const  uint8_t  *path, size_t length, uint8_t *buffer,
     size_t *buflen);

     int coap_query_into_optlist(const uint8_t *path,  size_t  length,	coap_op-
     tion_num_t optnum, coap_optlist_t **optlist_chain);

     int  coap_split_query(const uint8_t *query, size_t length, uint8_t *buffer,
     size_t *buflen);

     void coap_pdu_set_mid(coap_pdu_t *pdu, coap_mid_t mid);

     void coap_pdu_set_code(coap_pdu_t *pdu, coap_pdu_code_t code);

     void coap_pdu_set_type(coap_pdu_t *pdu, coap_pdu_type_t type);

     For  specific   (D)TLS   library	support,   link   with	 -lcoap-3-notls,
     -lcoap-3-gnutls,  -lcoap-3-openssl,  -lcoap-3-mbedtls,  -lcoap-3-wolfssl or
     -lcoap-3-tinydtls. Otherwise, link with -lcoap-3 to get the default  (D)TLS
     library support.

DESCRIPTION
     The CoAP PDU is of the form

     --header--|--optional token--|--optional options--|--optional payload--

     The terminology used is taken mainly from "RFC7252 1.2. Terminology".

     The PDU must be built in the correct order, from left to right. In particu-
     lar,  the options need to be added in the correct numerical option order as
     they are stored in the PDU using relative numeric offsets from the previous
     option number.

     There are option list functions available where options can be added  to  a
     chained list of options and then the chain list is sorted and then be added
     to the PDU.

     Typically for clients, when creating a request, the PDU needs to be created
     before filling it with the appropriate information.

     Typically	with a server, the response PDU, with the optional token already
     added in, will already be created before the response  handler  is  called,
     and  the  response PDU will need to be updated as appropriate starting with
     the optional options. Note that updating the response pdu's  code	variable
     will  cause  the  response pdu to get transmitted. If code does not get up-
     dated, and the PDU is of type CONFIRMABLE, then the response PDU is  trans-
     mitted  as an empty ACK packet. The response pdu is always freed off by the
     underlying library.

     For handling situations where the data to be transmitted does not fit  into
     a single packet, see coap_block(3).

PDU CREATE AND HEADER FUNCTIONS
     Function: coap_new_pdu()

     The coap_new_pdu() function returns a newly created PDU of type coap_pdu_t.

     The type is one of the following

	 COAP_MESSAGE_CON Set the _PDU_ to be of type confirmable.
	 COAP_MESSAGE_NON Set the _PDU_ to be of type non-confirmable.
	 COAP_MESSAGE_ACK Set the _PDU_ to be of type acknowledge (for internal use).
	 COAP_MESSAGE_RST Set the _PDU_ to be of type reset.

     The code is one of the following

	 COAP_EMPTY_CODE			       0.00
	 COAP_REQUEST_CODE_GET			       0.01
	 COAP_REQUEST_CODE_POST 		       0.02
	 COAP_REQUEST_CODE_PUT			       0.03
	 COAP_REQUEST_CODE_DELETE		       0.04
	 COAP_REQUEST_CODE_FETCH		       0.05
	 COAP_REQUEST_CODE_PATCH		       0.06
	 COAP_REQUEST_CODE_IPATCH		       0.07
	 COAP_RESPONSE_CODE_OK			       2.00
	 COAP_RESPONSE_CODE_CREATED		       2.01
	 COAP_RESPONSE_CODE_DELETED		       2.02
	 COAP_RESPONSE_CODE_VALID		       2.03
	 COAP_RESPONSE_CODE_CHANGED		       2.04
	 COAP_RESPONSE_CODE_CONTENT		       2.05
	 COAP_RESPONSE_CODE_CONTINUE		       2.31
	 COAP_RESPONSE_CODE_BAD_REQUEST 	       4.00
	 COAP_RESPONSE_CODE_UNAUTHORIZED	       4.01
	 COAP_RESPONSE_CODE_BAD_OPTION		       4.02
	 COAP_RESPONSE_CODE_FORBIDDEN		       4.03
	 COAP_RESPONSE_CODE_NOT_FOUND		       4.04
	 COAP_RESPONSE_CODE_NOT_ALLOWED 	       4.05
	 COAP_RESPONSE_CODE_NOT_ACCEPTABLE	       4.06
	 COAP_RESPONSE_CODE_INCOMPLETE		       4.08
	 COAP_RESPONSE_CODE_CONFLICT		       4.09
	 COAP_RESPONSE_CODE_PRECONDITION_FAILED        4.12
	 COAP_RESPONSE_CODE_REQUEST_TOO_LARGE	       4.13
	 COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT 4.15
	 COAP_RESPONSE_CODE_UNPROCESSABLE	       4.22
	 COAP_RESPONSE_CODE_TOO_MANY_REQUESTS	       4.29
	 COAP_RESPONSE_CODE_INTERNAL_ERROR	       5.00
	 COAP_RESPONSE_CODE_NOT_IMPLEMENTED	       5.01
	 COAP_RESPONSE_CODE_BAD_GATEWAY 	       5.02
	 COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE        5.03
	 COAP_RESPONSE_CODE_GATEWAY_TIMEOUT	       5.04
	 COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED     5.05
	 COAP_RESPONSE_CODE_HOP_LIMIT_REACHED	       5.08
	 COAP_SIGNALING_CODE_CSM		       7.01
	 COAP_SIGNALING_CODE_PING		       7.02
	 COAP_SIGNALING_CODE_PONG		       7.03
	 COAP_SIGNALING_CODE_RELEASE		       7.04
	 COAP_SIGNALING_CODE_ABORT		       7.05

     and session is used to set up other default values.

     Function: coap_pdu_init()

     The coap_pdu_init() function does the same work as coap_new_pdu() but gives
     the  additional  ability  to  define  the default values for message_id and
     max_size that coap_new_pdu() creates.

     The message_id must be unique per request (which is not the same as the to-
     ken), and must not be reused within  EXCHANGE_LIFETIME  (usually  247  sec-
     onds).  To  automate this, the function coap_new_message_id(session) should
     be called.

     At the CoAP protocol level, requests and  responses  are  matched	by  mes-
     sage_id  which  is why it needs to be unique. At the application level, for
     "separate" responses, the initial empty ACK response matches the message_id
     of the request (handled by libcoap) but the actual response  has  the  same
     token as the request and this must be used for the match. For "piggybacked"
     responses	the  token must still be used as the valid match for request and
     response. and the message_id just happens to match (but unsafe in case  the
     server is sending back a "separate" response).

     The max_size parameter defines the maximum size of a PDU and is usually de-
     termined by calling coap_session_max_pdu_size(session);

     Function: coap_new_message_id()

     The  coap_new_message_id()  function returns the next message id to use for
     sending a new request message.

     NOTE: For reliable messages RFC8323, this will always return 0.

     Function: coap_pdu_set_mid()

     The coap_pdu_set_mid() function is used to set the message id  mid  in  the
     PDU pdu.

     Function: coap_pdu_set_code()

     The  coap_pdu_set_code()  function  is used to set the code code in the PDU
     pdu.

     Function: coap_pdu_set_type()

     The coap_pdu_set_type() function is used to set the type of the PDU pdu.

     NOTE: A PDU does not need to be created by the server application	to  send
     back  a  response.  The  libcoap  server logic creates the initial PDU with
     COAP_EMPTY_CODE, appropriate message_id,  matching  token	and  potentially
     some  other  options  before  calling  the appropriate request handler (See
     coap_register_request_handler(3)).

PDU TOKEN FUNCTIONS
     Function: coap_session_init_token()

     The coap_session_init_token() function is used to initialize  the	starting
     token of length for the session.

     NOTE: this only takes the first 8 bytes of the token if extended tokens are
     being used (RFC8974).

     Function: coap_session_new_token()

     The  coap_session_new_token() function is used to obtain the next available
     token of length for the session. Note that the same token must be used  for
     doing an observe cancellation that was used for doing the observe registra-
     tion.  Otherwise  tokens should be unique for each request/response so that
     they can be correctly matched.

     NOTE: Only a token of up to 8 bytes is returned.

     Function: coap_add_token()

     The coap_add_token() function adds in the specified token's data of  length
     length  to  the  PDU  pdu.  The  maximum (but impractical due to PDU sizes)
     length of the token is 65804 bytes. If anything more  than  8,  the  remote
     peer  needs  to  support extended tokens for this to work. Adding the token
     must be done before any options or data are added. This function must  only
     be  called  once per pdu, and must not be called in the appropriate request
     handler as the token has already been added into the skeletal response PDU.

     If a token is not added, then the token in the  PDU  is  zero  length,  but
     still  a  valid token which is used for matching. The exception is an empty
     ACK packet.

     NOTE: The token provided by the client application may not be the	same  as
     used internally by libcoap - for example when doing data transmission where
     the body of data is spread over multiple payloads (see coap_block(3)). How-
     ever,  when  the  data transfers complete, the application will receive the
     corrected token in the response PDU.

PDU OPTIONS FUNCTIONS
     The following is the current list of options with their numeric value

	 /*
	  * The C, U, and N flags indicate the properties
	  * Critical, Unsafe, and NoCacheKey, respectively.
	  * If U is set, then N has no meaning as per
	  * https://rfc-editor.org/rfc/rfc7252#section-5.10
	  * and is set to a -.
	  * Separately, R is for the options that can be repeated
	  *
	  * The least significant byte of the option is set as followed
	  * as per https://rfc-editor.org/rfc/rfc7252#section-5.4.6
	  *
	  *   0   1   2   3   4   5   6   7
	  * --+---+---+---+---+---+---+---+
	  *	      | NoCacheKey| U | C |
	  * --+---+---+---+---+---+---+---+
	  *
	  * https://rfc-editor.org/rfc/rfc8613#section-4 goes on to define E, I and U
	  * properties Encrypted and Integrity Protected, Integrity Protected Only and
	  * Unprotected respectively.  Integrity Protected Only is not currently used.
	  *
	  * An Option is tagged with CUNREIU with any of the letters replaced with _ if
	  * not set, or - for N if U is set (see above) for aiding understanding of the
	  * Option.
	  */

	 COAP_OPTION_IF_MATCH	     1 /* C__RE__, opaque,    0-8 B, RFC7252 */
	 COAP_OPTION_URI_HOST	     3 /* CU-___U, String,  1-255 B, RFC7252 */
	 COAP_OPTION_ETAG	     4 /* ___RE__, opaque,    1-8 B, RFC7252 */
	 COAP_OPTION_IF_NONE_MATCH   5 /* C___E__, empty,	0 B, RFC7252 */
	 COAP_OPTION_OBSERVE	     6 /* _U-_E_U, empty/uint,	0 B/0-3 B, RFC7641 */
	 COAP_OPTION_URI_PORT	     7 /* CU-___U, uint,      0-2 B, RFC7252 */
	 COAP_OPTION_LOCATION_PATH   8 /* ___RE__, String,  0-255 B, RFC7252 */
	 COAP_OPTION_OSCORE	     9 /* C_____U, *,	    0-255 B, RFC8613 */
	 COAP_OPTION_URI_PATH	    11 /* CU-RE__, String,  0-255 B, RFC7252 */
	 COAP_OPTION_CONTENT_FORMAT 12 /* ____E__, uint,      0-2 B, RFC7252 */
	 /* COAP_OPTION_MAXAGE default 60 seconds if not set */
	 COAP_OPTION_MAXAGE	    14 /* _U-_E_U, uint,      0-4 B, RFC7252 */
	 COAP_OPTION_URI_QUERY	    15 /* CU-RE__, String,  1-255 B, RFC7252 */
	 COAP_OPTION_HOP_LIMIT	    16 /* ______U, uint,	1 B, RFC8768 */
	 COAP_OPTION_ACCEPT	    17 /* C___E__, uint,      0-2 B, RFC7252 */
	 COAP_OPTION_Q_BLOCK1	    19 /* CU__E_U, uint,      0-3 B, RFC8177 */
	 COAP_OPTION_LOCATION_QUERY 20 /* ___RE__, String,  0-255 B, RFC7252 */
	 COAP_OPTION_BLOCK2	    23 /* CU-_E_U, uint,      0-3 B, RFC7959 */
	 COAP_OPTION_BLOCK1	    27 /* CU-_E_U, uint,      0-3 B, RFC7959 */
	 COAP_OPTION_SIZE2	    28 /* __N_E_U, uint,      0-4 B, RFC7959 */
	 COAP_OPTION_Q_BLOCK2	    31 /* CU_RE_U, uint,      0-3 B, RFC9177 */
	 COAP_OPTION_PROXY_URI	    35 /* CU-___U, String, 1-1034 B, RFC7252 */
	 COAP_OPTION_PROXY_SCHEME   39 /* CU-___U, String,  1-255 B, RFC7252 */
	 COAP_OPTION_SIZE1	    60 /* __N_E_U, uint,      0-4 B, RFC7252 */
	 COAP_OPTION_ECHO	   252 /* _N__E_U, opaque,   0-40 B, RFC9175 */
	 COAP_OPTION_NORESPONSE    258 /* _U-_E_U, uint,      0-1 B, RFC7967 */
	 COAP_OPTION_RTAG	   292 /* ___RE_U, opaque,    0-8 B, RFC9175 */

     See FURTHER INFORMATION as to how to get the latest list.

     Function: coap_new_optlist()

     The coap_new_optlist() function returns a newly created  optlist  entry  of
     type coap_optlist_t*. The number specifies which CoAP option is to be used,
     and  is  one  of the COAP_OPTION_* definitions. The length is the length of
     the data of the option, and data points to the content of the option.

     NOTE: Where possible, the option data needs to be stripped of leading zeros
     (big endian) to reduce the amount of data needed in the PDU, as well as  in
     some  cases  the  maximum	data  size  of	an option can be exceeded if not
     stripped and hence be illegal. This is done by using coap_encode_var_safe()
     or coap_encode_var_safe8().

     Function: coap_insert_optlist()

     The coap_insert_optlist() function adds the optlist entry onto the  end  of
     the  optlist_chain. The initial optlist_chain entry needs to be set to NULL
     before this function is first called.  The  coap_delete_optlist()	function
     has to be called to free off all the optlist_chain entries.

     Function: coap_delete_optlist()

     The  coap_delete_optlist()  function  deletes and frees off all the optlist
     entries in the optlist_chain.

     Function: coap_add_optlist_pdu()

     The  coap_add_optlist_pdu()  function  sorts  all	 of   the   entries   in
     optlist_chain  into ascending option numeric order and adds all the entries
     to the pdu. This function does not free off the entries  in  optlist_chain.
     This  function  must  be called after adding any token and before adding in
     the payload data.

     Function: coap_add_option()

     The coap_add_option() function adds in the specified option of type  number
     with data of length length to the PDU pdu. It is important that options are
     added to the pdu with number either being the same or greater than the pre-
     vious option number that was added.

     NOTE: Where possible, the option data needs to be stripped of leading zeros
     (big  endian) to reduce the amount of data needed in the PDU, as well as in
     some cases the maximum data size of  an  option  can  be  exceeded  if  not
     stripped and hence be illegal. This is done by using coap_encode_var_safe()
     or coap_encode_var_safe8().

     Function: coap_encode_var_safe()

     The  coap_encode_var_safe()  function encodes value into buffer which has a
     size of size in bytes. Normally, the buffer size should  be  at  least  the
     sizeof(int) bytes unless you definitely know less space is required.

     Function: coap_encode_var_safe8()

     The coap_encode_var_safe8() function encodes 8 byte value into buffer which
     has a size of size in bytes. Normally, the buffer size should be at least 8
     bytes unless you definitely know less space is required.

     Function: coap_path_into_optlist()

     The  coap_path_into_optlist() function splits up path of length length into
     / separated segments and then appends the optnum option for each segment to
     optlist_chain. optlist_chain can contain previous optlist	entries  or  the
     parent  has  to be initialized to NULL. Any segment that is just "." is not
     appended. Any segment that is just ".." causes  the  previous  segment  (if
     just  added  by coap_path_into_optlist()) to be removed from optlist_chain.
     Any %<hex><hex> definitions are replaced by the actual byte. optnum  should
     be one of COAP_OPTION_URI_PATH or COAP_OPTION_LOCATION_PATH.

     Function: coap_split_path()

     The coap_split_path() function splits up path of length length into / sepa-
     rated  segments  and places the result in buffer which has a size of buflen
     with a dummy option separating each path segment. buflen needs to be preset
     with the size of buffer before the function call, and then  buflen  is  up-
     dated  with  the  actual  size  of buffer used. buflen needs to be at least
     length with an extra 2 bytes per segment to handle long segments. Any  seg-
     ment that is just "." is not appended. Any segment that is just ".." causes
     the  previous  segment  (if any) to be removed from buffer. Any %<hex><hex>
     definitions are replaced by the actual byte. The return value indicates the
     number of components  that  individual  COAP_OPTION_URI_PATH  (or	COAP_OP-
     TION_LOCATION_PATH) options need to be created for.

     Note: For simplicity, use coap_path_into_optlist() instead.

     Function: coap_query_into_optlist()

     The  coap_query_into_optlist()  function  splits  up query of length length
     into & separated segments and then appends the optnum option for each  seg-
     ment  to  optlist_chain. optlist_chain can contain previous optlist entries
     or the parent has to be initialized  to  NULL.  optnum  should  be  one  of
     COAP_OPTION_URI_QUERY or COAP_OPTION_LOCATION_QUERY.

     Function: coap_split_query()

     The  coap_split_query()  function	splits	up query of length length into &
     separated segments and places the result in buffer which has a size of  bu-
     flen  with a dummy option separating each query segment. buflen needs to be
     preset with the size of buffer before the function call, and then buflen is
     updated with the actual size of buffer used. buflen needs to  be  at  least
     length  with  an extra 2 bytes per segment to handle long segments. The re-
     turn value indicates the number  of  components  that  individual	COAP_OP-
     TION_URI_QUERY  (or  COAP_OPTION_LOCATION_QUERY) options need to be created
     for.

     Note: For simplicity, use coap_query_into_optlist() instead.

PDU OPTIONS - LIBCOAP HANDLING
     Most of the options are under the control of the applications, but the fol-
     lowing are primarily used internally by libcoap.

     COAP_OPTION_BLOCK1 and COAP_OPTION_BLOCK2

     These Block options are used when a large body needs to be  split	up  into
     multiple	 payloads.    Following    the	  introduction	  of   coap_con-
     text_set_block_mode(3), libcoap can internally handle the setting of  these
     options (see coap_block(3)). Applications can continue to include these op-
     tions to set hint block size values.

     It     is	   recommended	   that     coap_context_set_block_mode(context,
     COAP_BLOCK_USE_LIBCOAP|COAP_BLOCK_SINGLE_BODY) is used to reduce  the  pro-
     gramming requirements for block handling within the applications.

     COAP_OPTION_ECHO

     This option can be set by the server application to indicate that the state
     of  the  client's freshness is confirmed. The libcoap client logic will de-
     tect the use of the Echo option by the server and	reflect  back  the  Echo
     value  in	the  next  request without involving the client application. The
     opaque option Echo may be seen by the client application.

     COAP_OPTION_ETAG

     This option is normally set by the server libcoap logic when  sending  back
     multiple  payloads  so  that the (libcoap logic) client can re-assemble the
     correct body.

     COAP_OPTION_HOP_LIMIT

     When using proxy logic, the value of the Hop-Limit option is decremented by
     one for each proxy hop. If the count decrements to zero, then a  5.08  (Hop
     Limit  Reached)  error code is returned to the sender. The initial count is
     16, unless the client application sets its own limit  using  the  Hop-Limit
     option.

     COAP_OPTION_RTAG

     This  option  is set by the libcoap client logic when transmitting multiple
     bodies with multiple payloads so that the (libcoap logic) server  can  dif-
     ferentiate and re-assemble the correct body.

     COAP_OPTION_SIZE1 and COAP_OPTION_SIZE2

     These  options  are  added by the libcoap logic to provide a size (Size1 by
     libcoap client logic, Size2 by libcoap server logic) indication to the  re-
     cipient  of  the  size  of  the  large  body that is to be transferred. See
     coap_block(3).

     COAP_OPTION_OSCORE

     This option is used during OSCORE enabled communications. It should not  be
     set by any application, but is used internally. See coap_oscore(3) for fur-
     ther information on how to set up OSCORE.

PDU PAYLOAD FUNCTIONS
     Function: coap_add_data()

     The  coap_add_data()  function adds in the specified payload data of length
     length to the PDU pdu. Adding the payload data must be done after any token
     or options are added. This function must only be called once per pdu.

     Function: coap_add_data_blocked_response()

     The coap_add_data_blocked_response() function adds in the appropriate  part
     of the payload data of length length to the PDU pdu. It should be used as a
     direct replacement for coap_add_data() if it is possible that the data will
     not  fit into a single pdu. It also adds in the appropriate CoAP options to
     handle Block-Wise transfer. This function is usually used	for  a	server's
     GET  / FETCH response. The request and response are the same parameters for
     the registered GET / FETCH resource handler. The media_type is for the for-
     mat of the data and maxage defines the lifetime of the response. If set  to
     -1,  then the Max-Age option does not get included. This function must only
     be called once per pdu. It is the responsibility of the client to recognize
     that it has only received a part of the data and  request	the  next  block
     (with  the  appropriate  Block options) from the server. Returning the next
     requested block is handled by this function.

     NOTE: This function has been superseded by  coap_add_data_large_response().
     See coap_block(3).

PDU TRANSMIT FUNCTIONS
     Function: coap_send()

     The  coap_send()  function  is used to initiate the transmission of the pdu
     associated with the session. The caller must not access or delete pdu after
     calling coap_send() - even if there is a return error.

     NOTE: For request handlers, returning from the request handler  will  cause
     the  response  PDU to be transmitted as appropriate and there is no need to
     call coap_send() to do this.

RETURN VALUES
     coap_new_pdu() and coap_pdu_init() return a newly created PDU  or	NULL  if
     there is a malloc or parameter failure.

     coap_new_optlist()  returns  a  newly created optlist or NULL if there is a
     malloc failure.

     coap_add_token(),	 coap_insert_optlist(),    coap_add_optlist_pdu()    and
     coap_add_data() return 0 on failure, 1 on success.

     coap_encode_var_safe()  returns  either  the length of bytes encoded (which
     can be 0 when encoding 0) or 0 on failure.

     coap_encode_var_safe8() returns either the length of bytes  encoded  (which
     can be 0 when encoding 0) or 0 on failure.

     coap_add_option() returns the size of option added, or 0 on failure.

     coap_send()  returns  the CoAP message ID on success or COAP_INVALID_MID on
     failure.

     coap_path_into_optlist() and coap_query_into_optlist() return 1 on  success
     or 0 on failure.

     coap_split_path()	and  coap_split_query()  return the number of components
     found.

     coap_new_message_id() returns the next CoAP message ID to use.

EXAMPLES
     Setup PDU and Transmit

	 #include <coap3/coap.h>

	 static int
	 build_send_pdu(coap_context_t *context, coap_session_t *session,
			uint8_t msgtype, uint8_t request_code, const char *path,
			const char *query, unsigned char *data, size_t length,
			int observe) {
	   coap_pdu_t *pdu;
	   uint8_t buf[8];
	   size_t buflen;
	   coap_optlist_t *optlist_chain = NULL;
	   /* Remove (void) definition if variable is used */
	   (void)context;

	   /* Create the pdu with the appropriate options */
	   pdu = coap_pdu_init(msgtype, request_code, coap_new_message_id(session),
			       coap_session_max_pdu_size(session));
	   if (!pdu)
	     return 0;

	   /*
	    * Create unique token for this request for handling unsolicited /
	    * delayed responses
	    */
	   coap_session_new_token(session, &buflen, buf);
	   if (!coap_add_token(pdu, buflen, buf)) {
	     coap_log_debug("cannot add token to request\n");
	     goto error;
	   }

	   if (path) {
	     /* Add in the Uri-Path options */
	     if (!coap_path_into_optlist((const uint8_t *)path, strlen(path),
					 COAP_OPTION_URI_PATH, &optlist_chain))
	       goto error;
	   }

	   if (query) {
	     /* Add in the Uri-Query options */
	     if (!coap_query_into_optlist((const uint8_t *)query, strlen(query),
					  COAP_OPTION_URI_QUERY, &optlist_chain))
	       goto error;
	   }

	   if (request_code == COAP_REQUEST_GET && observe) {
	     /* Indicate that we want to observe this resource */
	     if (!coap_insert_optlist(&optlist_chain,
				      coap_new_optlist(COAP_OPTION_OBSERVE,
						       coap_encode_var_safe(buf, sizeof(buf),
							   COAP_OBSERVE_ESTABLISH), buf)
				     ))
	       goto error;
	   }

	   /* ... Other code / options etc. ... */

	   /* Add in all the options (after internal sorting) to the pdu */
	   if (!coap_add_optlist_pdu(pdu, &optlist_chain))
	     goto error;

	   if (data && length) {
	     /* Add in the specified data */
	     if (!coap_add_data(pdu, length, data))
	       goto error;
	   }

	   if (coap_send(session, pdu) == COAP_INVALID_MID)
	     goto error;
	   return 1;

	 error:

	   if (pdu)
	     coap_delete_pdu(pdu);
	   return 0;

	 }

     Resource Request Handler Response PDU Update

	 #include <coap3/coap.h>

	 #include <stdio.h>

	 static void
	 hnd_get_time(coap_resource_t *resource, coap_session_t *session,
		      const coap_pdu_t *request, const coap_string_t *query,
		      coap_pdu_t *response) {
	   unsigned char buf[40];
	   size_t len;
	   time_t now;

	   /* ... Additional analysis code for resource, request pdu etc.  ... */

	   /* After analysis, generate a suitable response */

	   now = time(NULL);

	   if (query != NULL && coap_string_equal(query, coap_make_str_const("secs"))) {
	     /* Output secs since Jan 1 1970 */
	     len = snprintf((char *)buf, sizeof(buf), "%lu", now);
	   } else {
	     /* Output human-readable time */
	     struct tm *tmp;
	     tmp = gmtime(&now);
	     if (!tmp) {
	       /* If 'now' is not valid */
	       coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
	       return;
	     }
	     len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp);
	   }
	   coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
	   /*
	    * Invoke coap_add_data_large_response() to do all the hard work.
	    *
	    * Define the format - COAP_MEDIATYPE_TEXT_PLAIN - to add in
	    * Define how long this response is valid for (secs) - 1 - to add in.
	    * Etag Option added internally with unique value as param set to 0
	    *
	    * Observe Option added internally if needed within the function
	    * Block2 Option added internally if output too large
	    * Size2 Option added internally
	    */
	   coap_add_data_large_response(resource, session, request, response,
					query, COAP_MEDIATYPE_TEXT_PLAIN, 1, 0,
					len,
					buf, NULL, NULL);

	   /*
	    * Returning from the request handler will cause the response to be
	    * sent off (assuming coap_pdu_set_code() has been called), unless
	    * the response is confirmable and the code is COAP_EMPTY_CODE which
	    * will cause an empty ACK packet to be returned).
	    */

	 }

SEE ALSO
     coap_block(3),  coap_observe(3),  coap_oscore(3),	coap_pdu_access(3)   and
     coap_resource(3)

FURTHER INFORMATION
     See

     "RFC7252: The Constrained Application Protocol (CoAP)"

     "RFC7959:	Block-Wise  Transfers  in  the	Constrained Application Protocol
     (CoAP)"

     "RFC8613: Object Security for Constrained RESTful Environments (OSCORE)"

     "RFC8974: Extended Tokens and Stateless Clients in the Constrained Applica-
     tion Protocol (CoAP)"

     for further information.

     See	   https://www.iana.org/assignments/core-parameters/core-parame-
     ters.xhtml#option-numbers for the current set of defined CoAP Options.

BUGS
     Please  raise  an issue on GitHub at https://github.com/obgm/libcoap/issues
     to report any bugs.

     Please raise a Pull Request  at  https://github.com/obgm/libcoap/pulls  for
     any fixes.

AUTHORS
     The libcoap project <libcoap-developers@lists.sourceforge.net>

coap_pdu_setup 4.3.5		   08/02/2026		       COAP_PDU_SETUP(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=coap_path_into_optlist&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help