libcoap-sys 0.2.2+libcoap-4.3.1

Raw bindings to the libcoap CoAP library.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
// -*- mode:doc; -*-
// vim: set syntax=asciidoc,tw=0:

coap_pdu_setup(3)
=================
:doctype: manpage
:man source:   coap_pdu_setup
:man version:  @PACKAGE_VERSION@
:man manual:   libcoap Manual

NAME
----
coap_pdu_setup,
coap_new_pdu,
coap_pdu_init,
coap_session_init_token,
coap_session_new_token,
coap_add_token,
coap_new_optlist,
coap_insert_optlist,
coap_delete_optlist,
coap_encode_var_safe,
coap_encode_var_safe8,
coap_add_optlist_pdu,
coap_add_option,
coap_add_data,
coap_add_data_blocked_response,
coap_send,
coap_split_path,
coap_split_query,
coap_pdu_set_mid,
coap_pdu_set_code,
coap_pdu_set_type
- Setting up CoAP PDUs

SYNOPSIS
--------
*#include <coap@LIBCOAP_API_VERSION@/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_);*

*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_split_path(const uint8_t *_path_, size_t _length_, uint8_t *_buffer_,
size_t *_buflen_);*

*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-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*,
*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls*
or *-lcoap-@LIBCOAP_API_VERSION@-tinydtls*.   Otherwise, link with
*-lcoap-@LIBCOAP_API_VERSION@* 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
https://tools.ietf.org/html/rfc7252#section-1.2

The PDU must be built in the correct order, from left to right.  In particular,
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 updated, and the PDU is
of type CONFIRMABLE, then the response PDU is transmitted 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
---------------------

*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

[source, c]
----
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

[source, c]
----
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
token), and must not be reused within EXCHANGE_LIFETIME (usually 247 seconds).
To automate this, the function *coap_new_message_id*(_session_) should be
called.

At the CoAP protocol level, requests and responses are matched by _message_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
determined by calling coap_session_max_pdu_size(session);

*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
---------

*Function: coap_session_init_token()*

The *coap_session_init_token*() function is used to initialize the starting
_token_ of _length_ for the _session_.

*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
registration.  Otherwise tokens should be unique for each request/response so
that they can be correctly matched.

*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 length of the token is 8 bytes.
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.

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)).
However, when the data transfers complete, the application will receive the
corrected token in the response PDU.

PDU OPTIONS
-----------

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://tools.ietf.org/html/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://tools.ietf.org/html/rfc7252#section-5.4.6
 *
 *   0   1   2   3   4   5   6   7
 * --+---+---+---+---+---+---+---+
 *           | NoCacheKey| U | C |
 * --+---+---+---+---+---+---+---+
 *
 * https://tools.ietf.org/html/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_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_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
_optlist_chain_ and then sorts the _optlist_chain_ before returning.
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 previous 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_split_path()*

The *coap_split_path*() function splits up _path_ of length _length_ and
places the result in _buffer_ which has a size of _buflen_ with the nul
character separating each path component.  _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. The return
value indicates the number of components that individual COAP_OPTION_URI_PATH
options need to be created for.

*Function: coap_split_query()*

The *coap_split_query*() function splits up _query_ of length _length_ and
places the result in _buffer_ which has a size of _buflen_ with the nul
character separating each path component.  _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. The return
value indicates the number of components that individual COAP_OPTION_URI_QUERY
options need to be created for.

PDU OPTIONS - LIBCOAP HANDLING
------------------------------
Most of the options are under the control of the applications, but the
following 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_context_set_block_mode*(3), libcoap can internally handle the setting
of these options (see *coap_block*(3)). Applications can continue to include
these options 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 programming 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 detect 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
differentiate 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
recipient of the size of the large body that is to be transferred. See
*coap_block*(3).

PDU PAYLOAD DATA
----------------

*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 format 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
------------

*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
-------------
The *coap_new_pdu*() and *coap_pdu_init*() function returns a newly created
_PDU_ or NULL if there is a malloc or parameter failure.

The *coap_new_optlist*() function returns a newly created _optlist_ or NULL
if there is a malloc failure.

The *coap_add_token*(), *coap_insert_optlist*(), *coap_delete_optlist*(),
*coap_add_optlist_pdu*() and *coap_add_data*()
functions return 0 on failure, 1 on success.

The *coap_add_optlist*() function returns either the length of the option
or 0 on failure.

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

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

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

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

EXAMPLES
--------
*Setup PDU and Transmit*

[source, c]
----
#include <coap@LIBCOAP_API_VERSION@/coap.h>

static int
build_send_pdu(coap_context_t *context, coap_session_t *session,
uint8_t msgtype, uint8_t request_code, const char *uri, const char *query,
unsigned char *data, size_t length, int observe) {

  coap_pdu_t *pdu;
  uint8_t buf[1024];
  size_t buflen;
  uint8_t *sbuf = buf;
  int res;
  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(LOG_DEBUG, "cannot add token to request\n");
    goto error;
  }

  if (uri) {
    /* Add in the URI options */
    buflen = sizeof(buf);
    res = coap_split_path((const uint8_t*)uri, strlen(uri), sbuf, &buflen);
    while (res--) {
      if (!coap_insert_optlist(&optlist_chain,
                               coap_new_optlist(COAP_OPTION_URI_PATH,
                        coap_opt_length(sbuf), coap_opt_value(sbuf))))
        goto error;
      sbuf += coap_opt_size(sbuf);
    }
  }

  if (query) {
    /* Add in the QUERY options */
    buflen = sizeof(buf);
    res = coap_split_query((const uint8_t*)query, strlen(query), sbuf, &buflen);
    while (res--) {
      if (!coap_insert_optlist(&optlist_chain,
                               coap_new_optlist(COAP_OPTION_URI_QUERY,
                        coap_opt_length(sbuf), coap_opt_value(sbuf))))
        goto error;
      sbuf += coap_opt_size(sbuf);
    }
  }

  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*

[source, c]
----
#include <coap@LIBCOAP_API_VERSION@/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);
  /*
   * When request handler returns, the response pdu will get automatically
   * sent, unless the pdu code is not updated and this is a NON or TCP based
   * request.
   */

}
----

SEE ALSO
--------
*coap_block*(3), *coap_observe*(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)"

"RFC9175: CoAP: Echo, Request-Tag, and Token Processing"

for further information.

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

BUGS
----
Please report bugs on the mailing list for libcoap:
libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
https://github.com/obgm/libcoap/issues

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