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