1COAP_PDU_SETUP(3) libcoap Manual COAP_PDU_SETUP(3)
2
3
4
6 coap_pdu_setup, coap_new_pdu, coap_pdu_init, coap_new_message_id,
7 coap_session_init_token, coap_session_new_token, coap_add_token,
8 coap_new_optlist, coap_insert_optlist, coap_delete_optlist,
9 coap_encode_var_safe, coap_encode_var_safe8, coap_add_optlist_pdu,
10 coap_add_option, coap_add_data, coap_add_data_blocked_response,
11 coap_send, coap_split_path, coap_split_query, coap_pdu_set_mid,
12 coap_pdu_set_code, coap_pdu_set_type - Setting up CoAP PDUs
13
15 #include <coap3/coap.h>
16
17 coap_pdu_t *coap_new_pdu(coap_pdu_type_t type, coap_pdu_code_t code,
18 coap_session_t *session);
19
20 coap_pdu_t *coap_pdu_init(coap_pdu_type_t type, coap_pdu_code_t code,
21 coap_mid_t message_id, size_t max_size);
22
23 uint16_t coap_new_message_id(coap_session_t *session);
24
25 void coap_session_init_token(coap_session_t *session, size_t length,
26 const uint8_t *token);
27
28 void coap_session_new_token(coap_session_t *session, size_t *length,
29 uint8_t *token);
30
31 int coap_add_token(coap_pdu_t *pdu, size_t length, const uint8_t
32 *data);
33
34 coap_optlist_t *coap_new_optlist(uint16_t number, size_t length, const
35 uint8_t *data);
36
37 int coap_insert_optlist(coap_optlist_t **optlist_chain, coap_optlist_t
38 *optlist);
39
40 void coap_delete_optlist(coap_optlist_t *optlist_chain);
41
42 unsigned int coap_encode_var_safe(uint8_t *buffer, size_t size,
43 unsigned int value);
44
45 unsigned int coap_encode_var_safe8(uint8_t *buffer, size_t size,
46 uint64_t value);
47
48 int coap_add_optlist_pdu(coap_pdu_t *pdu, coap_optlist_t
49 **optlist_chain);
50
51 size_t coap_add_option(coap_pdu_t *pdu, uint16_t number, size_t length,
52 const uint8_t *data);
53
54 int coap_add_data(coap_pdu_t *pdu, size_t length, const uint8_t *data);
55
56 void coap_add_data_blocked_response(const coap_pdu_t *request,
57 coap_pdu_t *response, uint16_t media_type, int maxage, size_t length,
58 const uint8_t *data);
59
60 coap_mid_t coap_send(coap_session_t *session, coap_pdu_t *pdu);
61
62 int coap_split_path(const uint8_t *path, size_t length, uint8_t
63 *buffer, size_t *buflen);
64
65 int coap_split_query(const uint8_t *query, size_t length, uint8_t
66 *buffer, size_t *buflen);
67
68 void coap_pdu_set_mid(coap_pdu_t *pdu, coap_mid_t mid);
69
70 void coap_pdu_set_code(coap_pdu_t *pdu, coap_pdu_code_t code);
71
72 void coap_pdu_set_type(coap_pdu_t *pdu, coap_pdu_type_t type);
73
74 For specific (D)TLS library support, link with -lcoap-3-notls,
75 -lcoap-3-gnutls, -lcoap-3-openssl, -lcoap-3-mbedtls or
76 -lcoap-3-tinydtls. Otherwise, link with -lcoap-3 to get the default
77 (D)TLS library support.
78
80 The CoAP PDU is of the form
81
82 --header--|--optional token--|--optional options--|--optional payload--
83
84 The terminology used is taken mainly from "RFC7252 1.2. Terminology".
85
86 The PDU must be built in the correct order, from left to right. In
87 particular, the options need to be added in the correct numerical
88 option order as they are stored in the PDU using relative numeric
89 offsets from the previous option number.
90
91 There are option list functions available where options can be added to
92 a chained list of options and then the chain list is sorted and then be
93 added to the PDU.
94
95 Typically for clients, when creating a request, the PDU needs to be
96 created before filling it with the appropriate information.
97
98 Typically with a server, the response PDU, with the optional token
99 already added in, will already be created before the response handler
100 is called, and the response PDU will need to be updated as appropriate
101 starting with the optional options. Note that updating the response
102 pdu’s code variable will cause the response pdu to get transmitted. If
103 code does not get updated, and the PDU is of type CONFIRMABLE, then the
104 response PDU is transmitted as an empty ACK packet. The response pdu is
105 always freed off by the underlying library.
106
107 For handling situations where the data to be transmitted does not fit
108 into a single packet, see coap_block(3).
109
111 Function: coap_new_pdu()
112
113 The coap_new_pdu() function returns a newly created PDU of type
114 coap_pdu_t.
115
116 The type is one of the following
117
118 COAP_MESSAGE_CON Set the _PDU_ to be of type confirmable.
119 COAP_MESSAGE_NON Set the _PDU_ to be of type non-confirmable.
120 COAP_MESSAGE_ACK Set the _PDU_ to be of type acknowledge (for internal use).
121 COAP_MESSAGE_RST Set the _PDU_ to be of type reset.
122
123 The code is one of the following
124
125 COAP_EMPTY_CODE 0.00
126 COAP_REQUEST_CODE_GET 0.01
127 COAP_REQUEST_CODE_POST 0.02
128 COAP_REQUEST_CODE_PUT 0.03
129 COAP_REQUEST_CODE_DELETE 0.04
130 COAP_REQUEST_CODE_FETCH 0.05
131 COAP_REQUEST_CODE_PATCH 0.06
132 COAP_REQUEST_CODE_IPATCH 0.07
133 COAP_RESPONSE_CODE_OK 2.00
134 COAP_RESPONSE_CODE_CREATED 2.01
135 COAP_RESPONSE_CODE_DELETED 2.02
136 COAP_RESPONSE_CODE_VALID 2.03
137 COAP_RESPONSE_CODE_CHANGED 2.04
138 COAP_RESPONSE_CODE_CONTENT 2.05
139 COAP_RESPONSE_CODE_CONTINUE 2.31
140 COAP_RESPONSE_CODE_BAD_REQUEST 4.00
141 COAP_RESPONSE_CODE_UNAUTHORIZED 4.01
142 COAP_RESPONSE_CODE_BAD_OPTION 4.02
143 COAP_RESPONSE_CODE_FORBIDDEN 4.03
144 COAP_RESPONSE_CODE_NOT_FOUND 4.04
145 COAP_RESPONSE_CODE_NOT_ALLOWED 4.05
146 COAP_RESPONSE_CODE_NOT_ACCEPTABLE 4.06
147 COAP_RESPONSE_CODE_INCOMPLETE 4.08
148 COAP_RESPONSE_CODE_CONFLICT 4.09
149 COAP_RESPONSE_CODE_PRECONDITION_FAILED 4.12
150 COAP_RESPONSE_CODE_REQUEST_TOO_LARGE 4.13
151 COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT 4.15
152 COAP_RESPONSE_CODE_UNPROCESSABLE 4.22
153 COAP_RESPONSE_CODE_TOO_MANY_REQUESTS 4.29
154 COAP_RESPONSE_CODE_INTERNAL_ERROR 5.00
155 COAP_RESPONSE_CODE_NOT_IMPLEMENTED 5.01
156 COAP_RESPONSE_CODE_BAD_GATEWAY 5.02
157 COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE 5.03
158 COAP_RESPONSE_CODE_GATEWAY_TIMEOUT 5.04
159 COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED 5.05
160 COAP_RESPONSE_CODE_HOP_LIMIT_REACHED 5.08
161 COAP_SIGNALING_CODE_CSM 7.01
162 COAP_SIGNALING_CODE_PING 7.02
163 COAP_SIGNALING_CODE_PONG 7.03
164 COAP_SIGNALING_CODE_RELEASE 7.04
165 COAP_SIGNALING_CODE_ABORT 7.05
166
167 and session is used to set up other default values.
168
169 Function: coap_pdu_init()
170
171 The coap_pdu_init() function does the same work as coap_new_pdu() but
172 gives the additional ability to define the default values for
173 message_id and max_size that coap_new_pdu() creates.
174
175 The message_id must be unique per request (which is not the same as the
176 token), and must not be reused within EXCHANGE_LIFETIME (usually 247
177 seconds). To automate this, the function coap_new_message_id(session)
178 should be called.
179
180 At the CoAP protocol level, requests and responses are matched by
181 message_id which is why it needs to be unique. At the application
182 level, for "separate" responses, the initial empty ACK response matches
183 the message_id of the request (handled by libcoap) but the actual
184 response has the same token as the request and this must be used for
185 the match. For "piggybacked" responses the token must still be used as
186 the valid match for request and response. and the message_id just
187 happens to match (but unsafe in case the server is sending back a
188 "separate" response).
189
190 The max_size parameter defines the maximum size of a PDU and is usually
191 determined by calling coap_session_max_pdu_size(session);
192
193 Function: coap_new_message_id()
194
195 The coap_new_message_id() function returns the next message id to use
196 for sending a new request message.
197
198 NOTE: For reliable messages RFC8323, this will always return 0.
199
200 Function: coap_pdu_set_mid()
201
202 The coap_pdu_set_mid() function is used to set the message id mid in
203 the PDU pdu.
204
205 Function: coap_pdu_set_code()
206
207 The coap_pdu_set_code() function is used to set the code code in the
208 PDU pdu.
209
210 Function: coap_pdu_set_type()
211
212 The coap_pdu_set_type() function is used to set the type of the PDU
213 pdu.
214
215 NOTE: A PDU does not need to be created by the server application to
216 send back a response. The libcoap server logic creates the initial PDU
217 with COAP_EMPTY_CODE, appropriate message_id, matching token and
218 potentially some other options before calling the appropriate request
219 handler (See coap_register_request_handler(3)).
220
222 Function: coap_session_init_token()
223
224 The coap_session_init_token() function is used to initialize the
225 starting token of length for the session.
226
227 NOTE: this only takes the first 8 bytes of the token if extended tokens
228 are being used (RFC8974).
229
230 Function: coap_session_new_token()
231
232 The coap_session_new_token() function is used to obtain the next
233 available token of length for the session. Note that the same token
234 must be used for doing an observe cancellation that was used for doing
235 the observe registration. Otherwise tokens should be unique for each
236 request/response so that they can be correctly matched.
237
238 NOTE: Only a token of up to 8 bytes is returned.
239
240 Function: coap_add_token()
241
242 The coap_add_token() function adds in the specified token’s data of
243 length length to the PDU pdu. The maximum (but impractical due to PDU
244 sizes) length of the token is 65804 bytes. If anything more than 8, the
245 remote peer needs to support extended tokens for this to work. Adding
246 the token must be done before any options or data are added. This
247 function must only be called once per pdu, and must not be called in
248 the appropriate request handler as the token has already been added
249 into the skeletal response PDU.
250
251 If a token is not added, then the token in the PDU is zero length, but
252 still a valid token which is used for matching. The exception is an
253 empty ACK packet.
254
255 NOTE: The token provided by the client application may not be the same
256 as used internally by libcoap - for example when doing data
257 transmission where the body of data is spread over multiple payloads
258 (see coap_block(3)). However, when the data transfers complete, the
259 application will receive the corrected token in the response PDU.
260
262 The following is the current list of options with their numeric value
263
264 /*
265 * The C, U, and N flags indicate the properties
266 * Critical, Unsafe, and NoCacheKey, respectively.
267 * If U is set, then N has no meaning as per
268 * https://rfc-editor.org/rfc/rfc7252#section-5.10
269 * and is set to a -.
270 * Separately, R is for the options that can be repeated
271 *
272 * The least significant byte of the option is set as followed
273 * as per https://rfc-editor.org/rfc/rfc7252#section-5.4.6
274 *
275 * 0 1 2 3 4 5 6 7
276 * --+---+---+---+---+---+---+---+
277 * | NoCacheKey| U | C |
278 * --+---+---+---+---+---+---+---+
279 *
280 * https://rfc-editor.org/rfc/rfc8613#section-4 goes on to define E, I and U
281 * properties Encrypted and Integrity Protected, Integrity Protected Only and
282 * Unprotected respectively. Integrity Protected Only is not currently used.
283 *
284 * An Option is tagged with CUNREIU with any of the letters replaced with _ if
285 * not set, or - for N if U is set (see above) for aiding understanding of the
286 * Option.
287 */
288
289 COAP_OPTION_IF_MATCH 1 /* C__RE__, opaque, 0-8 B, RFC7252 */
290 COAP_OPTION_URI_HOST 3 /* CU-___U, String, 1-255 B, RFC7252 */
291 COAP_OPTION_ETAG 4 /* ___RE__, opaque, 1-8 B, RFC7252 */
292 COAP_OPTION_IF_NONE_MATCH 5 /* C___E__, empty, 0 B, RFC7252 */
293 COAP_OPTION_OBSERVE 6 /* _U-_E_U, empty/uint, 0 B/0-3 B, RFC7641 */
294 COAP_OPTION_URI_PORT 7 /* CU-___U, uint, 0-2 B, RFC7252 */
295 COAP_OPTION_LOCATION_PATH 8 /* ___RE__, String, 0-255 B, RFC7252 */
296 COAP_OPTION_OSCORE 9 /* C_____U, *, 0-255 B, RFC8613 */
297 COAP_OPTION_URI_PATH 11 /* CU-RE__, String, 0-255 B, RFC7252 */
298 COAP_OPTION_CONTENT_FORMAT 12 /* ____E__, uint, 0-2 B, RFC7252 */
299 /* COAP_OPTION_MAXAGE default 60 seconds if not set */
300 COAP_OPTION_MAXAGE 14 /* _U-_E_U, uint, 0-4 B, RFC7252 */
301 COAP_OPTION_URI_QUERY 15 /* CU-RE__, String, 1-255 B, RFC7252 */
302 COAP_OPTION_HOP_LIMIT 16 /* ______U, uint, 1 B, RFC8768 */
303 COAP_OPTION_ACCEPT 17 /* C___E__, uint, 0-2 B, RFC7252 */
304 COAP_OPTION_Q_BLOCK1 19 /* CU__E_U, uint, 0-3 B, RFC8177 */
305 COAP_OPTION_LOCATION_QUERY 20 /* ___RE__, String, 0-255 B, RFC7252 */
306 COAP_OPTION_BLOCK2 23 /* CU-_E_U, uint, 0-3 B, RFC7959 */
307 COAP_OPTION_BLOCK1 27 /* CU-_E_U, uint, 0-3 B, RFC7959 */
308 COAP_OPTION_SIZE2 28 /* __N_E_U, uint, 0-4 B, RFC7959 */
309 COAP_OPTION_Q_BLOCK2 31 /* CU_RE_U, uint, 0-3 B, RFC9177 */
310 COAP_OPTION_PROXY_URI 35 /* CU-___U, String, 1-1034 B, RFC7252 */
311 COAP_OPTION_PROXY_SCHEME 39 /* CU-___U, String, 1-255 B, RFC7252 */
312 COAP_OPTION_SIZE1 60 /* __N_E_U, uint, 0-4 B, RFC7252 */
313 COAP_OPTION_ECHO 252 /* _N__E_U, opaque, 0-40 B, RFC9175 */
314 COAP_OPTION_NORESPONSE 258 /* _U-_E_U, uint, 0-1 B, RFC7967 */
315 COAP_OPTION_RTAG 292 /* ___RE_U, opaque, 0-8 B, RFC9175 */
316
317 See FURTHER INFORMATION as to how to get the latest list.
318
319 Function: coap_new_optlist()
320
321 The coap_new_optlist() function returns a newly created optlist entry
322 of type coap_optlist_t*. The number specifies which CoAP option is to
323 be used, and is one of the COAP_OPTION_* definitions. The length is the
324 length of the data of the option, and data points to the content of the
325 option.
326
327 NOTE: Where possible, the option data needs to be stripped of leading
328 zeros (big endian) to reduce the amount of data needed in the PDU, as
329 well as in some cases the maximum data size of an option can be
330 exceeded if not stripped and hence be illegal. This is done by using
331 coap_encode_var_safe() or coap_encode_var_safe8().
332
333 Function: coap_insert_optlist()
334
335 The coap_insert_optlist() function adds the optlist entry onto the end
336 of the optlist_chain. The initial optlist_chain entry needs to be set
337 to NULL before this function is first called. The coap_delete_optlist()
338 function has to be called to free off all the optlist_chain entries.
339
340 Function: coap_delete_optlist()
341
342 The coap_delete_optlist() function deletes and frees off all the
343 optlist entries in the optlist_chain.
344
345 Function: coap_add_optlist_pdu()
346
347 The coap_add_optlist_pdu() function sorts all of the entries in
348 optlist_chain into ascending option numeric order and adds all the
349 entries to the pdu. This function does not free off the entries in
350 optlist_chain. This function must be called after adding any token and
351 before adding in the payload data.
352
353 Function: coap_add_option()
354
355 The coap_add_option() function adds in the specified option of type
356 number with data of length length to the PDU pdu. It is important that
357 options are added to the pdu with number either being the same or
358 greater than the previous option number that was added.
359
360 NOTE: Where possible, the option data needs to be stripped of leading
361 zeros (big endian) to reduce the amount of data needed in the PDU, as
362 well as in some cases the maximum data size of an option can be
363 exceeded if not stripped and hence be illegal. This is done by using
364 coap_encode_var_safe() or coap_encode_var_safe8().
365
366 Function: coap_encode_var_safe()
367
368 The coap_encode_var_safe() function encodes value into buffer which has
369 a size of size in bytes. Normally, the buffer size should be at least
370 the sizeof(int) bytes unless you definitely know less space is
371 required.
372
373 Function: coap_encode_var_safe8()
374
375 The coap_encode_var_safe8() function encodes 8 byte value into buffer
376 which has a size of size in bytes. Normally, the buffer size should be
377 at least 8 bytes unless you definitely know less space is required.
378
379 Function: coap_split_path()
380
381 The coap_split_path() function splits up path of length length and
382 places the result in buffer which has a size of buflen with the nul
383 character separating each path component. buflen needs to be preset
384 with the size of buffer before the function call, and then buflen is
385 updated with the actual size of buffer used. The return value indicates
386 the number of components that individual COAP_OPTION_URI_PATH options
387 need to be created for.
388
389 Function: coap_split_query()
390
391 The coap_split_query() function splits up query of length length and
392 places the result in buffer which has a size of buflen with the nul
393 character separating each path component. buflen needs to be preset
394 with the size of buffer before the function call, and then buflen is
395 updated with the actual size of buffer used. The return value indicates
396 the number of components that individual COAP_OPTION_URI_QUERY options
397 need to be created for.
398
400 Most of the options are under the control of the applications, but the
401 following are primarily used internally by libcoap.
402
403 COAP_OPTION_BLOCK1 and COAP_OPTION_BLOCK2
404
405 These Block options are used when a large body needs to be split up
406 into multiple payloads. Following the introduction of
407 coap_context_set_block_mode(3), libcoap can internally handle the
408 setting of these options (see coap_block(3)). Applications can continue
409 to include these options to set hint block size values.
410
411 It is recommended that coap_context_set_block_mode(context,
412 COAP_BLOCK_USE_LIBCOAP|COAP_BLOCK_SINGLE_BODY) is used to reduce the
413 programming requirements for block handling within the applications.
414
415 COAP_OPTION_ECHO
416
417 This option can be set by the server application to indicate that the
418 state of the client’s freshness is confirmed. The libcoap client logic
419 will detect the use of the Echo option by the server and reflect back
420 the Echo value in the next request without involving the client
421 application. The opaque option Echo may be seen by the client
422 application.
423
424 COAP_OPTION_ETAG
425
426 This option is normally set by the server libcoap logic when sending
427 back multiple payloads so that the (libcoap logic) client can
428 re-assemble the correct body.
429
430 COAP_OPTION_HOP_LIMIT
431
432 When using proxy logic, the value of the Hop-Limit option is
433 decremented by one for each proxy hop. If the count decrements to zero,
434 then a 5.08 (Hop Limit Reached) error code is returned to the sender.
435 The initial count is 16, unless the client application sets its own
436 limit using the Hop-Limit option.
437
438 COAP_OPTION_RTAG
439
440 This option is set by the libcoap client logic when transmitting
441 multiple bodies with multiple payloads so that the (libcoap logic)
442 server can differentiate and re-assemble the correct body.
443
444 COAP_OPTION_SIZE1 and COAP_OPTION_SIZE2
445
446 These options are added by the libcoap logic to provide a size (Size1
447 by libcoap client logic, Size2 by libcoap server logic) indication to
448 the recipient of the size of the large body that is to be transferred.
449 See coap_block(3).
450
451 COAP_OPTION_OSCORE
452
453 This option is used during OSCORE enabled communications. It should not
454 be set by any application, but is used internally. See coap_oscore(3)
455 for further information on how to set up OSCORE.
456
458 Function: coap_add_data()
459
460 The coap_add_data() function adds in the specified payload data of
461 length length to the PDU pdu. Adding the payload data must be done
462 after any token or options are added. This function must only be called
463 once per pdu.
464
465 Function: coap_add_data_blocked_response()
466
467 The coap_add_data_blocked_response() function adds in the appropriate
468 part of the payload data of length length to the PDU pdu. It should be
469 used as a direct replacement for coap_add_data() if it is possible that
470 the data will not fit into a single pdu. It also adds in the
471 appropriate CoAP options to handle Block-Wise transfer. This function
472 is usually used for a server’s GET / FETCH response. The request and
473 response are the same parameters for the registered GET / FETCH
474 resource handler. The media_type is for the format of the data and
475 maxage defines the lifetime of the response. If set to -1, then the
476 Max-Age option does not get included. This function must only be called
477 once per pdu. It is the responsibility of the client to recognize that
478 it has only received a part of the data and request the next block
479 (with the appropriate Block options) from the server. Returning the
480 next requested block is handled by this function.
481
482 NOTE: This function has been superseded by
483 coap_add_data_large_response(). See coap_block(3).
484
486 Function: coap_send()
487
488 The coap_send() function is used to initiate the transmission of the
489 pdu associated with the session. The caller must not access or delete
490 pdu after calling coap_send() - even if there is a return error.
491
492 NOTE: For request handlers, returning from the request handler will
493 cause the response PDU to be transmitted as appropriate and there is no
494 need to call coap_send() to do this.
495
497 coap_new_pdu() and coap_pdu_init() return a newly created PDU or NULL
498 if there is a malloc or parameter failure.
499
500 coap_new_optlist() returns a newly created optlist or NULL if there is
501 a malloc failure.
502
503 coap_add_token(), coap_insert_optlist(), coap_add_optlist_pdu() and
504 coap_add_data() return 0 on failure, 1 on success.
505
506 coap_encode_var_safe() returns either the length of bytes encoded
507 (which can be 0 when encoding 0) or 0 on failure.
508
509 coap_encode_var_safe8() returns either the length of bytes encoded
510 (which can be 0 when encoding 0) or 0 on failure.
511
512 coap_add_option() returns the size of option added, or 0 on failure.
513
514 coap_send() returns the CoAP message ID on success or COAP_INVALID_MID
515 on failure.
516
517 coap_split_path() and coap_split_query() return the number of
518 components found.
519
520 coap_new_message_id() returns the next CoAP message ID to use.
521
523 Setup PDU and Transmit
524
525 #include <coap3/coap.h>
526
527 static int
528 build_send_pdu(coap_context_t *context, coap_session_t *session,
529 uint8_t msgtype, uint8_t request_code, const char *uri, const char *query,
530 unsigned char *data, size_t length, int observe) {
531
532 coap_pdu_t *pdu;
533 uint8_t buf[1024];
534 size_t buflen;
535 uint8_t *sbuf = buf;
536 int res;
537 coap_optlist_t *optlist_chain = NULL;
538 /* Remove (void) definition if variable is used */
539 (void)context;
540
541 /* Create the pdu with the appropriate options */
542 pdu = coap_pdu_init(msgtype, request_code, coap_new_message_id(session),
543 coap_session_max_pdu_size(session));
544 if (!pdu)
545 return 0;
546
547 /*
548 * Create unique token for this request for handling unsolicited /
549 * delayed responses
550 */
551 coap_session_new_token(session, &buflen, buf);
552 if (!coap_add_token(pdu, buflen, buf)) {
553 coap_log_debug("cannot add token to request\n");
554 goto error;
555 }
556
557 if (uri) {
558 /* Add in the URI options */
559 buflen = sizeof(buf);
560 res = coap_split_path((const uint8_t*)uri, strlen(uri), sbuf, &buflen);
561 while (res--) {
562 if (!coap_insert_optlist(&optlist_chain,
563 coap_new_optlist(COAP_OPTION_URI_PATH,
564 coap_opt_length(sbuf), coap_opt_value(sbuf))))
565 goto error;
566 sbuf += coap_opt_size(sbuf);
567 }
568 }
569
570 if (query) {
571 /* Add in the QUERY options */
572 buflen = sizeof(buf);
573 res = coap_split_query((const uint8_t*)query, strlen(query), sbuf, &buflen);
574 while (res--) {
575 if (!coap_insert_optlist(&optlist_chain,
576 coap_new_optlist(COAP_OPTION_URI_QUERY,
577 coap_opt_length(sbuf), coap_opt_value(sbuf))))
578 goto error;
579 sbuf += coap_opt_size(sbuf);
580 }
581 }
582
583 if (request_code == COAP_REQUEST_GET && observe) {
584 /* Indicate that we want to observe this resource */
585 if (!coap_insert_optlist(&optlist_chain,
586 coap_new_optlist(COAP_OPTION_OBSERVE,
587 coap_encode_var_safe(buf, sizeof(buf),
588 COAP_OBSERVE_ESTABLISH), buf)
589 ))
590 goto error;
591 }
592
593 /* ... Other code / options etc. ... */
594
595 /* Add in all the options (after internal sorting) to the pdu */
596 if (!coap_add_optlist_pdu(pdu, &optlist_chain))
597 goto error;
598
599 if (data && length) {
600 /* Add in the specified data */
601 if (!coap_add_data(pdu, length, data))
602 goto error;
603 }
604
605 if (coap_send(session, pdu) == COAP_INVALID_MID)
606 goto error;
607 return 1;
608
609 error:
610
611 if (pdu)
612 coap_delete_pdu(pdu);
613 return 0;
614
615 }
616
617 Resource Request Handler Response PDU Update
618
619 #include <coap3/coap.h>
620
621 #include <stdio.h>
622
623 static void
624 hnd_get_time(coap_resource_t *resource, coap_session_t *session,
625 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
626
627 unsigned char buf[40];
628 size_t len;
629 time_t now;
630
631 /* ... Additional analysis code for resource, request pdu etc. ... */
632
633 /* After analysis, generate a suitable response */
634
635 now = time(NULL);
636
637 if (query != NULL && coap_string_equal(query, coap_make_str_const("secs"))) {
638 /* Output secs since Jan 1 1970 */
639 len = snprintf((char *)buf, sizeof(buf), "%lu", now);
640 }
641 else {
642 /* Output human-readable time */
643 struct tm *tmp;
644 tmp = gmtime(&now);
645 if (!tmp) {
646 /* If 'now' is not valid */
647 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
648 return;
649 }
650 len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp);
651 }
652 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
653 /*
654 * Invoke coap_add_data_large_response() to do all the hard work.
655 *
656 * Define the format - COAP_MEDIATYPE_TEXT_PLAIN - to add in
657 * Define how long this response is valid for (secs) - 1 - to add in.
658 * Etag Option added internally with unique value as param set to 0
659 *
660 * Observe Option added internally if needed within the function
661 * Block2 Option added internally if output too large
662 * Size2 Option added internally
663 */
664 coap_add_data_large_response(resource, session, request, response,
665 query, COAP_MEDIATYPE_TEXT_PLAIN, 1, 0,
666 len,
667 buf, NULL, NULL);
668
669 /*
670 * Returning from the request handler will cause the response to be
671 * sent off (assuming coap_pdu_set_code() has been called), unless
672 * the response is confirmable and the code is COAP_EMPTY_CODE which
673 * will cause an empty ACK packet to be returned).
674 */
675
676 }
677
679 coap_block(3), coap_observe(3), coap_oscore(3), coap_pdu_access(3) and
680 coap_resource(3)
681
683 See
684
685 "RFC7252: The Constrained Application Protocol (CoAP)"
686
687 "RFC7959: Block-Wise Transfers in the Constrained Application Protocol
688 (CoAP)"
689
690 "RFC8613: Object Security for Constrained RESTful Environments
691 (OSCORE)"
692
693 "RFC8974: Extended Tokens and Stateless Clients in the Constrained
694 Application Protocol (CoAP)"
695
696 for further information.
697
698 See
699 https://www.iana.org/assignments/core-parameters/core-parameters.xhtml#option-numbers
700 for the current set of defined CoAP Options.
701
703 Please report bugs on the mailing list for libcoap:
704 libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
705 https://github.com/obgm/libcoap/issues
706
708 The libcoap project <libcoap-developers@lists.sourceforge.net>
709
710
711
712coap_pdu_setup 4.3.4 10/09/2023 COAP_PDU_SETUP(3)