Files
libcoap/include/coap2/mem.h
T
Jon Shallow 9cb2f62a3e RFC7641: Move block handling logic down into libcoap
This change removes the need for applications having to know about handling
requests for the next block etc.  It also gives the application the ability
to pass a large body of data to be transmitted and be told when this body is
no longer required.

This logic is enabled in libcoap by setting COAP_BLOCK_USE_LIBCOAP using
coap_context_set_block_mode()

This change breaks down into 4 specific areas

1) Client doing a PUT/POST etc. of a large amount of data (BLOCK1).

coap_add_data_large_request() is used which provides a 'finished with data'
callback function as well as adding required options to the PDUs.  This
function calls coap_add_data_large_internal().

Internal coap_handle_response_send_block() sends off the subsequent blocks
(using session->lg_xmit).

2) Server receiving PUT/POST etc. of a large amount of data (BLOCK1).

Internal coap_handle_request_get_block() acknowledges the appropriate blocks
(using session->lg_srcv) and either passes in the individual blocks or the body
depending on whether COAP_BLOCK_SINGLE_BODY is set or not using
coap_context_set_block_mode().

3) Server sending a large data response to GET / observe (BLOCK2)

coap_add_data_large_response() is used which provides a 'finished with data'
callback function.  This function calls coap_add_data_large_internal() as well
as filling in the necessary options for each PDU.

Interal coap_handle_request_send_block() will then send the next requested block
(using session->lg_xmit).

4) Client receiving a large data response (BLOCK2)

coap_send_large() for the initial request sets this up.

Internal coap_handle_response_get_block() will then request the next block when
previous block received (using session->lg_crcv) and either passes the
individual blocks or the body depending on COAP_BLOCK_SINGLE_BODY being set in
coap_context_set_block_mode().

----

The following new internal functions have been added

coap_handle_request_get_block()
coap_handle_request_send_block()
coap_handle_response_get_block()
coap_handle_response_send_block()
coap_add_data_large_internal()

The following new functions have been added.

coap_add_data_large_request()
coap_add_data_large_response()
coap_context_set_block_mode()
coap_get_data_large()
coap_pdu_duplicate()
coap_send_large()
coap_session_init_token()
coap_session_new_token()

The coap_session_init_token() and coap_session_new_token() were added to make
the handling of unique tokens for each request/response easier.
https://datatracker.ietf.org/doc/html/draft-ietf-core-echo-request-tag-10#section-4

New files

include/coap2/coap_block_internal.h:
man/coap_block.txt.in:

New memory types

COAP_LG_XMIT
COAP_LG_SRCV
COAP_LG_CRCV
2021-02-23 18:01:04 +00:00

138 lines
3.8 KiB
C

/*
* mem.h -- CoAP memory handling
*
* Copyright (C) 2010-2011,2014-2015 Olaf Bergmann <bergmann@tzi.org>
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef COAP_MEM_H_
#define COAP_MEM_H_
#include <stdlib.h>
#ifndef WITH_LWIP
/**
* Initializes libcoap's memory management.
* This function must be called once before coap_malloc() can be used on
* constrained devices.
*/
void coap_memory_init(void);
#endif /* WITH_LWIP */
/**
* Type specifiers for coap_malloc_type(). Memory objects can be typed to
* facilitate arrays of type objects to be used instead of dynamic memory
* management on constrained devices.
*/
typedef enum {
COAP_STRING,
COAP_ATTRIBUTE_NAME,
COAP_ATTRIBUTE_VALUE,
COAP_PACKET,
COAP_NODE,
COAP_CONTEXT,
COAP_ENDPOINT,
COAP_PDU,
COAP_PDU_BUF,
COAP_RESOURCE,
COAP_RESOURCEATTR,
#ifdef HAVE_LIBTINYDTLS
COAP_DTLS_SESSION,
#endif
COAP_SESSION,
COAP_OPTLIST,
COAP_CACHE_KEY,
COAP_CACHE_ENTRY,
COAP_LG_XMIT,
COAP_LG_CRCV,
COAP_LG_SRCV,
} coap_memory_tag_t;
#ifndef WITH_LWIP
/**
* Allocates a chunk of @p size bytes and returns a pointer to the newly
* allocated memory. The @p type is used to select the appropriate storage
* container on constrained devices. The storage allocated by coap_malloc_type()
* must be released with coap_free_type().
*
* @param type The type of object to be stored.
* @param size The number of bytes requested.
* @return A pointer to the allocated storage or @c NULL on error.
*/
void *coap_malloc_type(coap_memory_tag_t type, size_t size);
/**
* Reallocates a chunk @p p of bytes created by coap_malloc_type() or
* coap_realloc_type() and returns a pointer to the newly allocated memory of
* @p size.
* Only COAP_STRING type is supported.
*
* Note: If there is an error, @p p will separately need to be released by
* coap_free_type().
*
* @param type The type of object to be stored.
* @param p A pointer to memory that was allocated by coap_malloc_type().
* @param size The number of bytes requested.
* @return A pointer to the allocated storage or @c NULL on error.
*/
void *coap_realloc_type(coap_memory_tag_t type, void *p, size_t size);
/**
* Releases the memory that was allocated by coap_malloc_type(). The type tag @p
* type must be the same that was used for allocating the object pointed to by
* @p .
*
* @param type The type of the object to release.
* @param p A pointer to memory that was allocated by coap_malloc_type().
*/
void coap_free_type(coap_memory_tag_t type, void *p);
/**
* Wrapper function to coap_malloc_type() for backwards compatibility.
*/
COAP_STATIC_INLINE void *coap_malloc(size_t size) {
return coap_malloc_type(COAP_STRING, size);
}
/**
* Wrapper function to coap_free_type() for backwards compatibility.
*/
COAP_STATIC_INLINE void coap_free(void *object) {
coap_free_type(COAP_STRING, object);
}
#endif /* not WITH_LWIP */
#ifdef WITH_LWIP
#include <lwip/memp.h>
/* no initialization needed with lwip (or, more precisely: lwip must be
* completely initialized anyway by the time coap gets active) */
COAP_STATIC_INLINE void coap_memory_init(void) {}
/* It would be nice to check that size equals the size given at the memp
* declaration, but i currently don't see a standard way to check that without
* sourcing the custom memp pools and becoming dependent of its syntax
*/
#define coap_malloc_type(type, size) memp_malloc(MEMP_ ## type)
#define coap_free_type(type, p) memp_free(MEMP_ ## type, p)
/* Those are just here to make uri.c happy where string allocation has not been
* made conditional.
*/
COAP_STATIC_INLINE void *coap_malloc(size_t size) {
LWIP_ASSERT("coap_malloc must not be used in lwIP", 0);
}
COAP_STATIC_INLINE void coap_free(void *pointer) {
LWIP_ASSERT("coap_free must not be used in lwIP", 0);
}
#endif /* WITH_LWIP */
#endif /* COAP_MEM_H_ */