Loading...
Searching...
No Matches
coap_mem.c
Go to the documentation of this file.
/* coap_mem.c -- CoAP memory handling
*
* Copyright (C) 2014--2015,2019--2023 Olaf Bergmann <bergmann@tzi.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see
* README for terms of use.
*/
#include "coap3/coap_internal.h"
#if defined(RIOT_VERSION) && defined(MODULE_MEMARRAY)
#include <memarray.h>
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include <coap3/coap_session.h>
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include "coap3/coap_session.h"
#include "coap3/coap_net.h"
#include "coap3/coap_pdu.h"
#include "coap3/coap_resource.h"
#ifndef COAP_MAX_STRING_SIZE
#define COAP_MAX_STRING_SIZE (64U)
#endif /* COAP_MAX_STRING_SIZE */
#ifndef COAP_MAX_STRINGS
#define COAP_MAX_STRINGS (16U)
#endif /* COAP_MAX_STRINGS */
#ifndef COAP_MAX_ENDPOINTS
#define COAP_MAX_ENDPOINTS (4U)
#endif /* COAP_MAX_ENDPOINTS */
#ifndef COAP_MAX_RESOURCES
#define COAP_MAX_RESOURCES (8U)
#endif /* COAP_MAX_RESOURCES */
#ifndef COAP_MAX_ATTRIBUTES
#define COAP_MAX_ATTRIBUTES \
((COAP_MAX_RESOURCES) * 4U)
#endif /* COAP_MAX_ATTRIBUTE_STRINGS */
#ifndef COAP_MAX_ATTRIBUTE_STRINGS
#define COAP_MAX_ATTRIBUTE_STRINGS (COAP_MAX_ATTRIBUTES)
#endif /* COAP_MAX_ATTRIBUTE_STRINGS */
#ifndef COAP_MAX_ATTRIBUTE_SIZE
#define COAP_MAX_ATTRIBUTE_SIZE (16U)
#endif /* COAP_MAX_ATTRIBUTE_SIZE */
#ifndef COAP_MAX_PACKETS
#define COAP_MAX_PACKETS (4U)
#endif /* COAP_MAX_PACKETS */
#ifndef COAP_MAX_NODES
#define COAP_MAX_NODES \
((COAP_MAX_ENDPOINTS) * (COAP_MAX_PACKETS))
#endif /* COAP_MAX_NODES */
#ifndef COAP_MAX_CONTEXTS
#define COAP_MAX_CONTEXTS (1U)
#endif /* COAP_MAX_CONTEXTS */
#ifndef COAP_MAX_PDUS
#define COAP_MAX_PDUS ((COAP_MAX_ENDPOINTS) * 4U)
#endif /* COAP_MAX_PDUS */
#ifndef COAP_MAX_DTLS_SESSIONS
#define COAP_MAX_DTLS_SESSIONS (2U)
#endif /* COAP_MAX_CONTEXTS */
#ifndef COAP_MAX_SESSIONS
#define COAP_MAX_SESSIONS (COAP_MAX_ENDPOINTS)
#endif /* COAP_MAX_CONTEXTS */
#ifndef COAP_MAX_OPTIONS
#define COAP_MAX_OPTIONS (16U)
#endif /* COAP_MAX_CONTEXTS */
#ifndef COAP_MAX_OPTION_SIZE
#define COAP_MAX_OPTION_SIZE (16U)
#endif /* COAP_MAX_OPTION_SIZE */
#ifndef COAP_MAX_CACHE_KEYS
#define COAP_MAX_CACHE_KEYS (2U)
#endif /* COAP_MAX_CACHE_KEYS */
#ifndef COAP_MAX_CACHE_ENTRIES
#define COAP_MAX_CACHE_ENTRIES (2U)
#endif /* COAP_MAX_CACHE_ENTRIES */
#ifndef COAP_MAX_LG_CRCVS
#if COAP_CLIENT_SUPPORT
#define COAP_MAX_LG_CRCVS (1U)
#else /* ! COAP_CLIENT_SUPPORT */
#define COAP_MAX_LG_CRCVS (0U)
#endif /* ! COAP_CLIENT_SUPPORT */
#endif /* COAP_MAX_LG_CRCVS */
#ifndef COAP_MAX_LG_SRCVS
#if COAP_SERVER_SUPPORT
#define COAP_MAX_LG_SRCVS (2U)
#else /* ! COAP_SERVER_SUPPORT */
#define COAP_MAX_LG_SRCVS (0U)
#endif /* ! COAP_SERVER_SUPPORT */
#endif /* COAP_MAX_LG_SRCVS */
#ifndef COAP_MAX_LG_XMITS
#if COAP_SERVER_SUPPORT
#define COAP_MAX_LG_XMITS (2U)
#else /* ! COAP_SERVER_SUPPORT */
#define COAP_MAX_LG_XMITS (1U)
#endif /* ! COAP_SERVER_SUPPORT */
#endif /* COAP_MAX_LG_XMITS */
/* The memstr is the storage for holding coap_string_t structure
* together with its contents. */
union memstr_t {
coap_string_t s;
char buf[sizeof(coap_string_t) + COAP_MAX_STRING_SIZE];
};
/* The attrstr is the storage for holding coap_string_t structures to
* serve as attribute names or values. As these are typically short,
* they are stored in a different arena than generic strings. */
union attrstr_t {
coap_string_t s;
char buf[sizeof(coap_string_t) + COAP_MAX_ATTRIBUTE_SIZE];
};
static union memstr_t string_storage_data[COAP_MAX_STRINGS];
static memarray_t string_storage;
#if COAP_SERVER_SUPPORT
static coap_endpoint_t endpoint_storage_data[COAP_MAX_ENDPOINTS];
static memarray_t endpoint_storage;
static union attrstr_t attr_storage_data[COAP_MAX_ATTRIBUTE_STRINGS];
static memarray_t attr_storage;
static coap_attr_t resattr_storage_data[COAP_MAX_ATTRIBUTES];
static memarray_t resattr_storage;
#endif /* COAP_SERVER_SUPPORT */
static coap_packet_t pkt_storage_data[COAP_MAX_PACKETS];
static memarray_t pkt_storage;
static coap_queue_t node_storage_data[COAP_MAX_NODES];
static memarray_t node_storage;
static coap_context_t context_storage_data[COAP_MAX_CONTEXTS];
static memarray_t context_storage;
static coap_pdu_t pdu_storage_data[COAP_MAX_PDUS];
static memarray_t pdu_storage;
/* The pdubuf is the storage for holding the (assembled) PDU data in a
* coap_pdu_t structure. */
union pdubuf_t {
void *p; /* try to convince the compiler to word-align this structure */
char buf[COAP_DEFAULT_MAX_PDU_RX_SIZE];
};
static union pdubuf_t pdubuf_storage_data[COAP_MAX_PDUS];
static memarray_t pdubuf_storage;
#if COAP_SERVER_SUPPORT
static coap_resource_t resource_storage_data[COAP_MAX_RESOURCES];
static memarray_t resource_storage;
#endif /* COAP_SERVER_SUPPORT */
#ifdef COAP_WITH_LIBTINYDTLS
#undef PACKAGE_BUGREPORT
#include <session.h>
static session_t dtls_storage_data[COAP_MAX_DTLS_SESSIONS];
static memarray_t dtls_storage;
#endif /* COAP_WITH_LIBTINYDTLS */
static coap_session_t session_storage_data[COAP_MAX_SESSIONS];
static memarray_t session_storage;
/* The optbuf_t is the storage for holding optlist nodes. */
struct optbuf_t {
coap_optlist_t optlist;
char optbuf[COAP_MAX_OPTION_SIZE];
};
static struct optbuf_t option_storage_data[COAP_MAX_OPTIONS];
static memarray_t option_storage;
#if COAP_SERVER_SUPPORT
static coap_cache_key_t cache_key_storage_data[COAP_MAX_CACHE_KEYS];
static memarray_t cache_key_storage;
static coap_cache_entry_t cache_entry_storage_data[COAP_MAX_CACHE_ENTRIES];
static memarray_t cache_entry_storage;
#endif /* COAP_SERVER_SUPPORT */
#if COAP_CLIENT_SUPPORT
static coap_lg_crcv_t cache_lg_crcv_storage_data[COAP_MAX_LG_CRCVS];
static memarray_t cache_lg_crcv_storage;
#endif /* COAP_CLIENT_SUPPORT */
#if COAP_SERVER_SUPPORT
static coap_lg_srcv_t cache_lg_srcv_storage_data[COAP_MAX_LG_SRCVS];
static memarray_t cache_lg_srcv_storage;
static coap_lg_xmit_t cache_lg_xmit_storage_data[COAP_MAX_LG_XMITS];
static memarray_t cache_lg_xmit_storage;
#endif /* COAP_SERVER_SUPPORT */
#define INIT_STORAGE(Storage, Count) \
memarray_init(&(Storage ## _storage), (Storage ## _storage_data), sizeof(Storage ## _storage_data[0]), (Count));
#define STORAGE_PTR(Storage) (&(Storage ## _storage))
void
coap_memory_init(void) {
INIT_STORAGE(string, COAP_MAX_STRINGS);
#if COAP_SERVER_SUPPORT
INIT_STORAGE(endpoint, COAP_MAX_ENDPOINTS);
INIT_STORAGE(attr, COAP_MAX_ATTRIBUTE_STRINGS);
#endif /* COAP_SERVER_SUPPORT */
INIT_STORAGE(pkt, COAP_MAX_PACKETS);
INIT_STORAGE(node, COAP_MAX_NODES);
INIT_STORAGE(context, COAP_MAX_CONTEXTS);
INIT_STORAGE(pdu, COAP_MAX_PDUS);
INIT_STORAGE(pdubuf, COAP_MAX_PDUS);
#if COAP_SERVER_SUPPORT
INIT_STORAGE(resource, COAP_MAX_RESOURCES);
INIT_STORAGE(resattr, COAP_MAX_ATTRIBUTES);
#endif /* COAP_SERVER_SUPPORT */
#ifdef COAP_WITH_LIBTINYDTLS
INIT_STORAGE(dtls, COAP_MAX_DTLS_SESSIONS);
#endif
INIT_STORAGE(session, COAP_MAX_SESSIONS);
INIT_STORAGE(option, COAP_MAX_OPTIONS);
#if COAP_SERVER_SUPPORT
INIT_STORAGE(cache_key, COAP_MAX_CACHE_KEYS);
INIT_STORAGE(cache_entry, COAP_MAX_CACHE_ENTRIES);
#endif /* COAP_SERVER_SUPPORT */
#if COAP_CLIENT_SUPPORT
INIT_STORAGE(cache_lg_crcv, COAP_MAX_LG_CRCVS);
#endif /* COAP_SERVER_SUPPORT */
#if COAP_SERVER_SUPPORT
INIT_STORAGE(cache_lg_srcv, COAP_MAX_LG_SRCVS);
INIT_STORAGE(cache_lg_xmit, COAP_MAX_LG_XMITS);
#endif /* COAP_SERVER_SUPPORT */
}
static memarray_t *
get_container(coap_memory_tag_t type) {
switch (type) {
#if COAP_SERVER_SUPPORT
case COAP_ATTRIBUTE_NAME:
/* fall through */
case COAP_ATTRIBUTE_VALUE:
return &attr_storage;
#endif /* COAP_SERVER_SUPPORT */
case COAP_PACKET:
return &pkt_storage;
case COAP_NODE:
return &node_storage;
case COAP_CONTEXT:
return STORAGE_PTR(context);
#if COAP_SERVER_SUPPORT
case COAP_ENDPOINT:
return &endpoint_storage;
#endif /* COAP_SERVER_SUPPORT */
case COAP_PDU:
return &pdu_storage;
case COAP_PDU_BUF:
return &pdubuf_storage;
#if COAP_SERVER_SUPPORT
case COAP_RESOURCE:
return &resource_storage;
case COAP_RESOURCEATTR:
return &resattr_storage;
#endif /* COAP_SERVER_SUPPORT */
#ifdef COAP_WITH_LIBTINYDTLS
case COAP_DTLS_SESSION:
return &dtls_storage;
#endif
case COAP_SESSION:
return &session_storage;
case COAP_OPTLIST:
return &option_storage;
#if COAP_SERVER_SUPPORT
case COAP_CACHE_KEY:
return &cache_key_storage;
case COAP_CACHE_ENTRY:
return &cache_entry_storage;
#endif /* COAP_SERVER_SUPPORT */
#if COAP_CLIENT_SUPPORT
case COAP_LG_CRCV:
return &cache_lg_crcv_storage;
#endif /* COAP_CLIENT_SUPPORT */
#if COAP_SERVER_SUPPORT
case COAP_LG_SRCV:
return &cache_lg_srcv_storage;
case COAP_LG_XMIT:
return &cache_lg_xmit_storage;
#endif /* COAP_SERVER_SUPPORT */
case COAP_STRING:
/* fall through */
default:
return &string_storage;
}
}
void *
coap_malloc_type(coap_memory_tag_t type, size_t size) {
memarray_t *container = get_container(type);
void *ptr;
assert(container);
if (size > container->size) {
coap_log_warn("coap_malloc_type: Requested memory exceeds maximum object "
"size (type %d, size %zu, max %d)\n",
type, size, container->size);
return NULL;
}
ptr = memarray_alloc(container);
if (!ptr)
coap_log_warn("coap_malloc_type: Failure (no free blocks) for type %d\n",
type);
return ptr;
}
void
coap_free_type(coap_memory_tag_t type, void *object) {
if (object != NULL)
memarray_free(get_container(type), object);
}
void *
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
memarray_t *container = get_container(type);
assert(container);
/* The fixed container is all we have to work with */
if (p) {
if (size > container->size) {
coap_log_warn("coap_realloc_type: Requested memory exceeds maximum object "
"size (type %d, size %zu, max %d)\n",
type, size, container->size);
return NULL;
}
if (size == 0) {
coap_free_type(type, p);
return NULL;
}
return p;
}
return coap_malloc_type(type, size);
}
#else /* ! RIOT_VERSION */
#if defined(HAVE_MALLOC) || defined(__MINGW32__)
#include <stdlib.h>
void
coap_memory_init(void) {
}
void *
coap_malloc_type(coap_memory_tag_t type, size_t size) {
(void)type;
return malloc(size);
}
void *
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
(void)type;
return realloc(p, size);
}
void
coap_free_type(coap_memory_tag_t type, void *p) {
(void)type;
free(p);
}
#else /* ! HAVE_MALLOC && !__MINGW32__ */
#ifdef WITH_CONTIKI
#include "lib/heapmem.h"
void
coap_memory_init(void) {
}
void *
coap_malloc_type(coap_memory_tag_t type, size_t size) {
return heapmem_alloc(size);
}
void *
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
return heapmem_realloc(p, size);
}
void
coap_free_type(coap_memory_tag_t type, void *ptr) {
heapmem_free(ptr);
}
#endif /* WITH_CONTIKI */
#endif /* ! HAVE_MALLOC */
#endif /* ! RIOT_VERSION */
coap_internal.h
Pulls together all the internal only header files.
coap_memory_init
void coap_memory_init(void)
Initializes libcoap's memory management.
coap_memory_tag_t
coap_memory_tag_t
Type specifiers for coap_malloc_type().
Definition coap_mem.h:37
COAP_DTLS_SESSION
@ COAP_DTLS_SESSION
Definition coap_mem.h:49
COAP_SESSION
@ COAP_SESSION
Definition coap_mem.h:50
COAP_CACHE_KEY
@ COAP_CACHE_KEY
Definition coap_mem.h:52
COAP_NODE
@ COAP_NODE
Definition coap_mem.h:42
COAP_CACHE_ENTRY
@ COAP_CACHE_ENTRY
Definition coap_mem.h:53
COAP_RESOURCE
@ COAP_RESOURCE
Definition coap_mem.h:47
COAP_RESOURCEATTR
@ COAP_RESOURCEATTR
Definition coap_mem.h:48
COAP_LG_XMIT
@ COAP_LG_XMIT
Definition coap_mem.h:54
COAP_ATTRIBUTE_VALUE
@ COAP_ATTRIBUTE_VALUE
Definition coap_mem.h:40
COAP_ENDPOINT
@ COAP_ENDPOINT
Definition coap_mem.h:44
COAP_CONTEXT
@ COAP_CONTEXT
Definition coap_mem.h:43
COAP_OPTLIST
@ COAP_OPTLIST
Definition coap_mem.h:51
COAP_PDU
@ COAP_PDU
Definition coap_mem.h:45
COAP_LG_CRCV
@ COAP_LG_CRCV
Definition coap_mem.h:55
COAP_ATTRIBUTE_NAME
@ COAP_ATTRIBUTE_NAME
Definition coap_mem.h:39
COAP_LG_SRCV
@ COAP_LG_SRCV
Definition coap_mem.h:56
COAP_PACKET
@ COAP_PACKET
Definition coap_mem.h:41
COAP_STRING
@ COAP_STRING
Definition coap_mem.h:38
COAP_PDU_BUF
@ COAP_PDU_BUF
Definition coap_mem.h:46
coap_realloc_type
void * coap_realloc_type(coap_memory_tag_t type, void *p, size_t size)
Reallocates a chunk p of bytes created by coap_malloc_type() or coap_realloc_type() and returns a poi...
coap_malloc_type
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
coap_free_type
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
coap_net.h
CoAP context interface.
coap_pdu.h
Pre-defined constants that reflect defaults for CoAP.
coap_resource.h
Generic resource handling.
coap_session.h
Defines the application visible session information.
coap_log_warn
#define coap_log_warn(...)
Definition coap_debug.h:102
coap_attr_t
Limits the number of subscribers for each resource that this server support.
Definition coap_resource_internal.h:42
coap_cache_entry_t
Definition coap_cache_internal.h:41
coap_cache_key_t
Definition coap_cache_internal.h:37
coap_context_t
The CoAP stack's global state is stored in a coap_context_t object.
Definition coap_net_internal.h:49
coap_endpoint_t
Abstraction of virtual endpoint that can be attached to coap_context_t.
Definition coap_session_internal.h:219
coap_lg_crcv_t
Structure to hold large body (many blocks) client receive information.
Definition coap_block_internal.h:146
coap_lg_srcv_t
Structure to hold large body (many blocks) server receive information.
Definition coap_block_internal.h:177
coap_lg_xmit_t
Structure to hold large body (many blocks) transmission information.
Definition coap_block_internal.h:117
coap_optlist_t
Representation of chained list of CoAP options to install.
Definition coap_option.h:325
coap_packet_t
Definition coap_io_internal.h:207
coap_pdu_t
structure for CoAP PDUs
Definition coap_pdu_internal.h:119
coap_queue_t
Queue entry.
Definition coap_net_internal.h:34
coap_resource_t
Abstraction of resource that can be attached to coap_context_t.
Definition coap_resource_internal.h:53
coap_session_t
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
Definition coap_session_internal.h:68
coap_string_t
CoAP string data definition.
Definition coap_str.h:38