libcoap 4.3.5-develop-18df85a
Loading...
Searching...
No Matches
coap_block_internal.h
Go to the documentation of this file.
1/*
2 * coap_block_internal.h -- Structures, Enums & Functions that are not
3 * exposed to application programming
4 *
5 * Copyright (C) 2010-2026 Olaf Bergmann <bergmann@tzi.org>
6 * Copyright (C) 2021-2026 Jon Shallow <supjps-libcoap@jpshallow.com>
7 *
8 * SPDX-License-Identifier: BSD-2-Clause
9 *
10 * This file is part of the CoAP library libcoap. Please see README for terms
11 * of use.
12 */
13
18
19#ifndef COAP_BLOCK_INTERNAL_H_
20#define COAP_BLOCK_INTERNAL_H_
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
32
33/*
34 * Use the top 20 bits of a 64 bit token for tracking current block in large transfer.
35 * However, if smaller tokens are required. this would be set up to 48, leaving 16 bits
36 * for unique tokens.
37 */
38#ifndef STATE_MAX_BLK_CNT_BITS
39#define STATE_MAX_BLK_CNT_BITS 20
40#endif /* STATE_MAX_BLK_CNT_BITS */
41#define STATE_TOKEN_BASE(t) ((t) & (0xffffffffffffffffULL >> STATE_MAX_BLK_CNT_BITS))
42#define STATE_TOKEN_RETRY(t) ((uint64_t)(t) >> (64 - STATE_MAX_BLK_CNT_BITS))
43#define STATE_TOKEN_FULL(t,r) (STATE_TOKEN_BASE(t) + ((uint64_t)(r) << (64 - STATE_MAX_BLK_CNT_BITS)))
44
45#if COAP_Q_BLOCK_SUPPORT
46#define COAP_BLOCK_SET_MASK (COAP_BLOCK_USE_LIBCOAP | \
47 COAP_BLOCK_SINGLE_BODY | \
48 COAP_BLOCK_TRY_Q_BLOCK | \
49 COAP_BLOCK_USE_M_Q_BLOCK | \
50 COAP_BLOCK_NO_PREEMPTIVE_RTAG | \
51 COAP_BLOCK_STLESS_FETCH | \
52 COAP_BLOCK_STLESS_BLOCK2 | \
53 COAP_BLOCK_NOT_RANDOM_BLOCK1 | \
54 COAP_BLOCK_FORCE_Q_BLOCK)
55#else /* ! COAP_Q_BLOCK_SUPPORT */
56#define COAP_BLOCK_SET_MASK (COAP_BLOCK_USE_LIBCOAP | \
57 COAP_BLOCK_SINGLE_BODY | \
58 COAP_BLOCK_NO_PREEMPTIVE_RTAG | \
59 COAP_BLOCK_STLESS_FETCH | \
60 COAP_BLOCK_STLESS_BLOCK2 | \
61 COAP_BLOCK_NOT_RANDOM_BLOCK1)
62#endif /* ! COAP_Q_BLOCK_SUPPORT */
63
64#define COAP_BLOCK_MAX_SIZE_MASK 0x7000000 /* (svr)Mask to get the max supported block size */
65#define COAP_BLOCK_MAX_SIZE_SHIFT 24 /* (svr)Mask shift to get the max supported block size */
66#define COAP_BLOCK_MAX_SIZE_GET(a) (((a) & COAP_BLOCK_MAX_SIZE_MASK) >> COAP_BLOCK_MAX_SIZE_SHIFT)
67#define COAP_BLOCK_MAX_SIZE_SET(a) (((a) << COAP_BLOCK_MAX_SIZE_SHIFT) & COAP_BLOCK_MAX_SIZE_MASK)
68
69#if COAP_Q_BLOCK_SUPPORT
70/* Internal use only and are dropped when setting block_mode */
71#define COAP_BLOCK_HAS_Q_BLOCK 0x40000000 /* Set when Q_BLOCK supported */
72#define COAP_BLOCK_PROBE_Q_BLOCK 0x80000000 /* Set when Q_BLOCK probing */
73
74#define set_block_mode_probe_q(block_mode) \
75 do { \
76 block_mode |= COAP_BLOCK_PROBE_Q_BLOCK; \
77 block_mode &= ~(COAP_BLOCK_TRY_Q_BLOCK | COAP_BLOCK_HAS_Q_BLOCK); \
78 } while (0)
79
80#define set_block_mode_has_q(block_mode) \
81 do { \
82 block_mode |= COAP_BLOCK_HAS_Q_BLOCK; \
83 block_mode &= ~(COAP_BLOCK_TRY_Q_BLOCK | COAP_BLOCK_PROBE_Q_BLOCK); \
84 } while (0)
85
86#define set_block_mode_drop_q(block_mode) \
87 do { \
88 block_mode &= ~(COAP_BLOCK_TRY_Q_BLOCK |\
89 COAP_BLOCK_PROBE_Q_BLOCK |\
90 COAP_BLOCK_HAS_Q_BLOCK | \
91 COAP_BLOCK_USE_M_Q_BLOCK | \
92 COAP_BLOCK_FORCE_Q_BLOCK); \
93 } while (0)
94
95#define COAP_SINGLE_BLOCK_OR_Q (COAP_BLOCK_SINGLE_BODY|COAP_BLOCK_HAS_Q_BLOCK)
96#else /* ! COAP_Q_BLOCK_SUPPORT */
97#define COAP_SINGLE_BLOCK_OR_Q (COAP_BLOCK_SINGLE_BODY)
98#endif /* ! COAP_Q_BLOCK_SUPPORT */
99
104
106 uint32_t begin;
107 uint32_t end;
108};
109
110#ifndef COAP_RBLOCK_CNT
111#define COAP_RBLOCK_CNT 6
112#endif
113#if COAP_RBLOCK_CNT > COAP_DEFAULT_MAX_PAYLOADS -1
114#error COAP_RBLOCK_CNT too large
115#endif
116#if COAP_RBLOCK_CNT < 2
117#error COAP_RBLOCK_CNT too small
118#endif
119
123typedef struct coap_rblock_t {
124 uint32_t used;
125 uint32_t retry;
126#if COAP_Q_BLOCK_SUPPORT
127 uint32_t processing_payload_set;
128 uint32_t latest_payload_set;
129#endif /* COAP_Q_BLOCK_SUPPORT */
132 uint32_t total_blocks;
134
139typedef struct coap_l_block1_t {
141 uint64_t state_token;
142 size_t bert_size;
143 uint32_t count;
144 coap_address_t upstream; /* Unicast IP of server if mcast client session */
146
161
170
176 uint8_t blk_size;
177 uint16_t option;
181 union {
184 } b;
190#if COAP_Q_BLOCK_SUPPORT
191 coap_tick_t non_timeout_random_ticks;
192 coap_rblock_t send_blocks;
193#endif /* COAP_Q_BLOCK_SUPPORT */
194 uint32_t ref;
195};
196
197#if COAP_CLIENT_SUPPORT
201struct coap_lg_crcv_t {
202 struct coap_lg_crcv_t *next;
203 uint8_t observe[3];
204 uint8_t observe_length;
205 uint8_t observe_set;
206 uint8_t szx;
207 uint8_t etag_set;
208 uint8_t etag_length;
209 uint8_t etag[8];
210 uint16_t content_format;
211 uint8_t last_type;
212 uint8_t initial;
213 uint16_t block_option;
214 uint16_t retry_counter;
215 size_t total_len;
216 coap_binary_t *body_data;
217 coap_binary_t *app_token;
218 coap_bin_const_t **obs_token;
220 size_t obs_token_cnt;
221 uint16_t o_block_option;
222 uint8_t o_blk_size;
223 uint32_t ref;
224 uint64_t state_token;
225 coap_pdu_t *sent_pdu;
226 coap_rblock_t rec_blocks;
227 coap_tick_t last_used;
228 coap_address_t upstream;
229 coap_lg_xmit_data_t *obs_data;
230};
231#endif /* COAP_CLIENT_SUPPORT */
232
233#if COAP_SERVER_SUPPORT
237struct coap_lg_srcv_t {
238 struct coap_lg_srcv_t *next;
239 uint8_t observe[3];
240 uint8_t observe_length;
241 uint8_t observe_set;
242 uint8_t no_more_seen;
243 uint8_t rtag_set;
244 uint8_t rtag_length;
245 uint8_t rtag[8];
246 uint16_t content_format;
247 uint8_t last_type;
248 uint8_t szx;
249 uint16_t block_option;
250 uint8_t dont_timeout;
251 coap_tick_t last_used;
252 size_t total_len;
253 coap_binary_t *body_data;
254 coap_resource_t *resource;
255 coap_str_const_t *uri_path;
256 coap_rblock_t rec_blocks;
257 coap_bin_const_t *last_token;
258 uint32_t ref;
259#if COAP_Q_BLOCK_SUPPORT
260 int32_t r_m_payload_set;
261#endif /* COAP_Q_BLOCK_SUPPORT */
262#if COAP_OSCORE_SUPPORT
263 oscore_recipient_ctx_t *recipient_ctx;
265#endif /* COAP_OSCORE_SUPPORT */
266 coap_cache_key_t *cache_key;
267};
268#endif /* COAP_SERVER_SUPPORT */
269
270#if COAP_Q_BLOCK_SUPPORT
271typedef enum {
272 COAP_SEND_SKIP_PDU,
273 COAP_SEND_INC_PDU,
274 COAP_SEND_MISSING,
275} coap_send_pdu_t;
276#endif /* COAP_Q_BLOCK_SUPPORT */
277
278#if COAP_CLIENT_SUPPORT
279coap_lg_crcv_t *coap_block_new_lg_crcv(coap_session_t *session,
280 coap_pdu_t *pdu,
281 coap_lg_xmit_t *lg_xmit);
282
294void coap_block_delete_lg_crcv(coap_session_t *session,
295 coap_lg_crcv_t *lg_crcv);
296
308coap_lg_crcv_release_lkd(coap_session_t *session,coap_lg_crcv_t *lg_crcv) {
309 coap_block_delete_lg_crcv(session, lg_crcv);
310 return;
311}
312
321coap_lg_crcv_reference_lkd(coap_lg_crcv_t *lg_crcv) {
322 lg_crcv->ref++;
323 return;
324}
325
326int coap_block_check_lg_crcv_timeouts(coap_session_t *session,
327 coap_tick_t now,
328 coap_tick_t *tim_rem);
329
330#if COAP_Q_BLOCK_SUPPORT
331coap_mid_t coap_send_q_block1(coap_session_t *session,
332 coap_block_b_t block,
333 coap_pdu_t *request,
334 coap_send_pdu_t send_request);
335
345int coap_block_check_q_block1_xmit(coap_session_t *session,
346 coap_tick_t now, coap_tick_t *tim_rem);
347
348coap_mid_t coap_block_test_q_block(coap_session_t *session, coap_pdu_t *actual);
349#endif /* COAP_Q_BLOCK_SUPPORT */
350
351#endif /* COAP_CLIENT_SUPPORT */
352
353#if COAP_Q_BLOCK_SUPPORT
369coap_mid_t coap_send_q_blocks(coap_session_t *session,
370 coap_lg_xmit_t *lg_xmit,
371 coap_block_b_t block,
372 coap_pdu_t *pdu,
373 coap_send_pdu_t send_pdu);
374#endif /* COAP_Q_BLOCK_SUPPORT */
375
376#if COAP_SERVER_SUPPORT
388void coap_block_delete_lg_srcv(coap_session_t *session,
389 coap_lg_srcv_t *lg_srcv);
390
402coap_lg_srcv_release_lkd(coap_session_t *session,coap_lg_srcv_t *lg_srcv) {
403 coap_block_delete_lg_srcv(session, lg_srcv);
404 return;
405}
406
415coap_lg_srcv_reference_lkd(coap_lg_srcv_t *lg_srcv) {
416 lg_srcv->ref++;
417 return;
418}
419
420int coap_block_check_lg_srcv_timeouts(coap_session_t *session,
421 coap_tick_t now,
422 coap_tick_t *tim_rem);
423
424#if COAP_Q_BLOCK_SUPPORT
434int coap_block_check_q_block2_xmit(coap_session_t *session,
435 coap_tick_t now, coap_tick_t *tim_rem);
436
437coap_mid_t coap_send_q_block2(coap_session_t *session,
438 coap_resource_t *resource,
439 const coap_string_t *query,
440 coap_pdu_code_t request_method,
441 coap_block_b_t block,
442 coap_pdu_t *response,
443 coap_send_pdu_t send_response);
444#endif /* COAP_Q_BLOCK_SUPPORT */
445
446int coap_handle_request_send_block(coap_session_t *session,
447 coap_pdu_t *pdu,
448 coap_pdu_t *response,
449 coap_resource_t *resource,
450 coap_string_t *query);
451
452int coap_handle_request_put_block(coap_context_t *context,
453 coap_session_t *session,
454 coap_pdu_t *pdu,
455 coap_pdu_t *response,
456 coap_resource_t *resource,
457 coap_string_t *uri_path,
458 coap_opt_t *observe,
459 int *added_block,
460 coap_lg_srcv_t **free_lg_srcv);
461
462coap_lg_xmit_t *coap_find_lg_xmit_response(const coap_session_t *session,
463 const coap_pdu_t *request,
464 const coap_resource_t *resource,
465 const coap_string_t *query);
466
519int coap_add_data_large_response_lkd(coap_resource_t *resource,
520 coap_session_t *session,
521 const coap_pdu_t *request,
522 coap_pdu_t *response,
523 const coap_string_t *query,
524 uint16_t media_type,
525 int maxage,
526 uint64_t etag,
527 size_t length,
528 const uint8_t *data,
529 coap_release_large_data_t release_func,
530 void *app_ptr);
531
532#endif /* COAP_SERVER_SUPPORT */
533
534#if COAP_CLIENT_SUPPORT
535int coap_handle_response_send_block(coap_session_t *session, coap_pdu_t *sent,
536 coap_pdu_t *rcvd);
537
538int coap_handle_response_get_block(coap_context_t *context,
539 coap_session_t *session,
540 coap_pdu_t *sent,
541 coap_pdu_t *rcvd,
542 coap_recurse_t recursive);
543
544coap_mid_t coap_retransmit_oscore_pdu(coap_session_t *session,
545 coap_pdu_t *pdu,
546 coap_opt_t *echo);
547
557coap_lg_crcv_t *coap_find_lg_crcv(coap_session_t *session, coap_pdu_t *pdu);
558
559#endif /* COAP_CLIENT_SUPPORT */
560
571
584 coap_lg_xmit_t *lg_xmit);
585
598 coap_block_delete_lg_xmit(session, lg_xmit);
599 return;
600}
601
611 lg_xmit->ref++;
612 return;
613}
614
616 coap_tick_t now,
617 coap_tick_t *tim_rem);
618
619#if COAP_Q_BLOCK_SUPPORT
620int coap_block_drop_resp_q_block_xmit(coap_session_t *session,
621 coap_lg_xmit_t *lg_xmit);
622
623int coap_block_drop_resp_q_block2_crcv(coap_session_t *session,
624 coap_lg_crcv_t *lg_crcv,
625 coap_pdu_t *sent);
626#endif /* COAP_Q_BLOCK_SUPPORT */
627
639 const coap_pdu_t *request,
640 coap_pdu_t *response,
641 const coap_resource_t *resource,
642 const coap_string_t *query);
643
663 uint32_t block_mode);
664
679int coap_context_set_max_block_size_lkd(coap_context_t *context, size_t max_block_size);
680
696coap_binary_t *coap_block_build_body_lkd(coap_binary_t *body_data, size_t length,
697 const uint8_t *data, size_t offset, size_t total);
698
699#if COAP_CLIENT_SUPPORT
744int coap_add_data_large_request_lkd(coap_session_t *session,
745 coap_pdu_t *pdu,
746 size_t length,
747 const uint8_t *data,
748 coap_release_large_data_t release_func,
749 void *app_ptr);
750
790int coap_add_data_large_request_app_lkd(coap_session_t *session,
791 coap_pdu_t *pdu,
792 size_t length,
793 coap_release_large_data_t release_func,
794 coap_get_large_data_t get_func,
795 void *app_ptr);
796
805#else /* ! COAP_CLIENT_SUPPORT */
806#define coap_check_update_token(a,b)
807#endif /* ! COAP_CLIENT_SUPPORT */
808
810
811#ifdef __cplusplus
812}
813#endif
814
815#endif /* COAP_BLOCK_INTERNAL_H_ */
struct coap_lg_crcv_t coap_lg_crcv_t
struct coap_cache_key_t coap_cache_key_t
struct coap_resource_t coap_resource_t
struct coap_lg_srcv_t coap_lg_srcv_t
uint8_t coap_opt_t
Use byte-oriented access methods here because sliding a complex struct coap_opt_t over the data buffe...
struct coap_rblock_t coap_rblock_t
Structure to keep track of received blocks.
#define coap_check_update_token(a, b)
int coap_context_set_max_block_size_lkd(coap_context_t *context, size_t max_block_size)
Set the context level maximum block size that the server supports when sending or receiving packets w...
Definition coap_block.c:455
void coap_context_set_block_mode_lkd(coap_context_t *context, uint32_t block_mode)
Set the context level CoAP block handling bits for handling RFC7959.
Definition coap_block.c:430
#define COAP_RBLOCK_CNT
void coap_check_code_lg_xmit(const coap_session_t *session, const coap_pdu_t *request, coap_pdu_t *response, const coap_resource_t *resource, const coap_string_t *query)
The function checks that the code in a newly formed lg_xmit created by coap_add_data_large_response_l...
COAP_STATIC_INLINE void coap_lg_xmit_reference_lkd(coap_lg_xmit_t *lg_xmit)
Increment reference counter on a lg_xmit.
void coap_block_delete_lg_xmit(coap_session_t *session, coap_lg_xmit_t *lg_xmit)
Remove a lg_xmit.
coap_binary_t * coap_block_build_body_lkd(coap_binary_t *body_data, size_t length, const uint8_t *data, size_t offset, size_t total)
Re-assemble payloads into a body.
COAP_STATIC_INLINE void coap_lg_xmit_release_lkd(coap_session_t *session, coap_lg_xmit_t *lg_xmit)
Decrement reference counter on a lg_xmit.
coap_lg_xmit_t * coap_find_lg_xmit(coap_session_t *session, coap_pdu_t *pdu)
Find the current lg_xmit for the session that matches the pdu.
Definition coap_block.c:485
int coap_block_check_lg_xmit_timeouts(coap_session_t *session, coap_tick_t now, coap_tick_t *tim_rem)
@ COAP_RECURSE_OK
@ COAP_RECURSE_NO
int(* coap_get_large_data_t)(coap_session_t *session, size_t max, size_t offset, uint8_t *data, size_t *length, void *app_ptr)
Callback handler for getting the data based on app_ptr provided to coap_add_data_large_request_app() ...
Definition coap_block.h:360
void(* coap_release_large_data_t)(coap_session_t *session, void *app_ptr)
Callback handler for de-allocating the data based on app_ptr provided to coap_add_data_large_*() func...
Definition coap_block.h:291
time_t coap_time_t
CoAP time in seconds since epoch.
Definition coap_time.h:154
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
Definition coap_time.h:149
struct oscore_recipient_ctx_t oscore_recipient_ctx_t
int coap_mid_t
coap_mid_t is used to store the CoAP Message ID of a CoAP PDU.
Definition coap_pdu.h:184
coap_pdu_code_t
Set of codes available for a PDU.
Definition coap_pdu.h:248
struct coap_str_const_t coap_str_const_t
CoAP string data definition with const data.
struct coap_binary_t coap_binary_t
CoAP binary data definition.
struct coap_bin_const_t coap_bin_const_t
CoAP binary data definition with const data.
#define COAP_STATIC_INLINE
Definition libcoap.h:57
Multi-purpose address abstraction.
CoAP binary data definition with const data.
Definition coap_str.h:65
CoAP binary data definition.
Definition coap_str.h:57
Structure of Block options with BERT support.
Definition coap_block.h:55
The CoAP stack's global state is stored in a coap_context_t object.
Structure to keep track of block1 specific information (Requests).
uint64_t state_token
state token
size_t bert_size
size of last BERT block
coap_address_t upstream
uint32_t count
the number of packets sent for payload
coap_binary_t * app_token
original PDU token
Structure to keep track of block2 specific information (Responses).
coap_pdu_code_t request_method
Method used to request this data.
uint8_t rtag_length
RTag length.
coap_string_t * query
Associated query for the resource.
uint64_t etag
ETag value.
coap_resource_t * resource
associated resource
coap_time_t maxage_expire
When this entry expires.
uint8_t rtag_set
Set if RTag is in receive PDU.
uint8_t rtag[8]
RTag for block checking.
coap_get_large_data_t get_func
Where to get data id needed.
void * app_ptr
application provided ptr for de-alloc function
uint32_t ref
Reference count.
const uint8_t * data
large data ptr
size_t length
large data length
coap_release_large_data_t release_func
large data de-alloc function
Structure to hold large body (many blocks) transmission information.
coap_tick_t last_all_sent
Last time all data sent or 0.
uint8_t blk_size
large block transmission size
union coap_lg_xmit_t::@371164272002100222145011123062035157102143075044 b
coap_tick_t last_sent
Last time any data sent.
coap_lg_xmit_data_t * data_info
Pointer to large data information.
int last_block
last acknowledged block number Block1 last transmitted Q-Block2
coap_tick_t last_payload
Last time MAX_PAYLOAD was sent or 0.
coap_pdu_t * sent_pdu
The sent pdu with all the data.
coap_l_block1_t b1
coap_l_block2_t b2
uint32_t ref
Reference count.
uint16_t option
large block transmission CoAP option
struct coap_lg_xmit_t * next
coap_tick_t last_obs
Last time used (Observe tracking) or 0.
structure for CoAP PDUs
Structure to keep track of received blocks.
uint32_t total_blocks
Set to block no + 1 when More bit unset.
uint32_t used
Number of range blocks in use.
struct coap_lg_range range[COAP_RBLOCK_CNT]
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
CoAP string data definition.
Definition coap_str.h:39