libcoap 4.3.4
coap_mem.c
Go to the documentation of this file.
1/* coap_mem.c -- CoAP memory handling
2 *
3 * Copyright (C) 2014--2015,2019--2023 Olaf Bergmann <bergmann@tzi.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7 * This file is part of the CoAP library libcoap. Please see
8 * README for terms of use.
9 */
10
16#include "coap3/coap_internal.h"
17
18#if defined(RIOT_VERSION) && defined(MODULE_MEMARRAY)
19#include <memarray.h>
20
21#undef PACKAGE_NAME
22#undef PACKAGE_STRING
23#undef PACKAGE_TARNAME
24#undef PACKAGE_VERSION
25#include <coap3/coap_session.h>
26#undef PACKAGE_NAME
27#undef PACKAGE_STRING
28#undef PACKAGE_TARNAME
29#undef PACKAGE_VERSION
30
31#include "coap3/coap_session.h"
32#include "coap3/coap_net.h"
33#include "coap3/coap_pdu.h"
34#include "coap3/coap_resource.h"
35
40#ifndef COAP_MAX_STRING_SIZE
41#define COAP_MAX_STRING_SIZE (64U)
42#endif /* COAP_MAX_STRING_SIZE */
43
48#ifndef COAP_MAX_STRINGS
49#define COAP_MAX_STRINGS (16U)
50#endif /* COAP_MAX_STRINGS */
51
56#ifndef COAP_MAX_ENDPOINTS
57#define COAP_MAX_ENDPOINTS (4U)
58#endif /* COAP_MAX_ENDPOINTS */
59
64#ifndef COAP_MAX_RESOURCES
65#define COAP_MAX_RESOURCES (8U)
66#endif /* COAP_MAX_RESOURCES */
67
72#ifndef COAP_MAX_ATTRIBUTES
73#define COAP_MAX_ATTRIBUTES \
74 ((COAP_MAX_RESOURCES) * 4U)
75#endif /* COAP_MAX_ATTRIBUTE_STRINGS */
76
83#ifndef COAP_MAX_ATTRIBUTE_STRINGS
84#define COAP_MAX_ATTRIBUTE_STRINGS (COAP_MAX_ATTRIBUTES)
85#endif /* COAP_MAX_ATTRIBUTE_STRINGS */
86
91#ifndef COAP_MAX_ATTRIBUTE_SIZE
92#define COAP_MAX_ATTRIBUTE_SIZE (16U)
93#endif /* COAP_MAX_ATTRIBUTE_SIZE */
94
99#ifndef COAP_MAX_PACKETS
100#define COAP_MAX_PACKETS (4U)
101#endif /* COAP_MAX_PACKETS */
102
108#ifndef COAP_MAX_NODES
109#define COAP_MAX_NODES \
110 ((COAP_MAX_ENDPOINTS) * (COAP_MAX_PACKETS))
111#endif /* COAP_MAX_NODES */
112
117#ifndef COAP_MAX_CONTEXTS
118#define COAP_MAX_CONTEXTS (1U)
119#endif /* COAP_MAX_CONTEXTS */
120
126#ifndef COAP_MAX_PDUS
127#define COAP_MAX_PDUS ((COAP_MAX_ENDPOINTS) * 4U)
128#endif /* COAP_MAX_PDUS */
129
134#ifndef COAP_MAX_DTLS_SESSIONS
135#define COAP_MAX_DTLS_SESSIONS (2U)
136#endif /* COAP_MAX_CONTEXTS */
137
142#ifndef COAP_MAX_SESSIONS
143#define COAP_MAX_SESSIONS (COAP_MAX_ENDPOINTS)
144#endif /* COAP_MAX_CONTEXTS */
145
150#ifndef COAP_MAX_OPTIONS
151#define COAP_MAX_OPTIONS (16U)
152#endif /* COAP_MAX_CONTEXTS */
153
158#ifndef COAP_MAX_OPTION_SIZE
159#define COAP_MAX_OPTION_SIZE (16U)
160#endif /* COAP_MAX_OPTION_SIZE */
161
166#ifndef COAP_MAX_CACHE_KEYS
167#define COAP_MAX_CACHE_KEYS (2U)
168#endif /* COAP_MAX_CACHE_KEYS */
169
174#ifndef COAP_MAX_CACHE_ENTRIES
175#define COAP_MAX_CACHE_ENTRIES (2U)
176#endif /* COAP_MAX_CACHE_ENTRIES */
177
182#ifndef COAP_MAX_LG_CRCVS
183#if COAP_CLIENT_SUPPORT
184#define COAP_MAX_LG_CRCVS (1U)
185#else /* ! COAP_CLIENT_SUPPORT */
186#define COAP_MAX_LG_CRCVS (0U)
187#endif /* ! COAP_CLIENT_SUPPORT */
188#endif /* COAP_MAX_LG_CRCVS */
189
194#ifndef COAP_MAX_LG_SRCVS
195#if COAP_SERVER_SUPPORT
196#define COAP_MAX_LG_SRCVS (2U)
197#else /* ! COAP_SERVER_SUPPORT */
198#define COAP_MAX_LG_SRCVS (0U)
199#endif /* ! COAP_SERVER_SUPPORT */
200#endif /* COAP_MAX_LG_SRCVS */
201
206#ifndef COAP_MAX_LG_XMITS
207#if COAP_SERVER_SUPPORT
208#define COAP_MAX_LG_XMITS (2U)
209#else /* ! COAP_SERVER_SUPPORT */
210#define COAP_MAX_LG_XMITS (1U)
211#endif /* ! COAP_SERVER_SUPPORT */
212#endif /* COAP_MAX_LG_XMITS */
213
214/* The memstr is the storage for holding coap_string_t structure
215 * together with its contents. */
216union memstr_t {
218 char buf[sizeof(coap_string_t) + COAP_MAX_STRING_SIZE];
219};
220
221/* The attrstr is the storage for holding coap_string_t structures to
222 * serve as attribute names or values. As these are typically short,
223 * they are stored in a different arena than generic strings. */
224union attrstr_t {
226 char buf[sizeof(coap_string_t) + COAP_MAX_ATTRIBUTE_SIZE];
227};
228
229static union memstr_t string_storage_data[COAP_MAX_STRINGS];
230static memarray_t string_storage;
231
232#if COAP_SERVER_SUPPORT
233static coap_endpoint_t endpoint_storage_data[COAP_MAX_ENDPOINTS];
234static memarray_t endpoint_storage;
235
236static union attrstr_t attr_storage_data[COAP_MAX_ATTRIBUTE_STRINGS];
237static memarray_t attr_storage;
238
239static coap_attr_t resattr_storage_data[COAP_MAX_ATTRIBUTES];
240static memarray_t resattr_storage;
241#endif /* COAP_SERVER_SUPPORT */
242
243static coap_packet_t pkt_storage_data[COAP_MAX_PACKETS];
244static memarray_t pkt_storage;
245
246static coap_queue_t node_storage_data[COAP_MAX_NODES];
247static memarray_t node_storage;
248
249static coap_context_t context_storage_data[COAP_MAX_CONTEXTS];
250static memarray_t context_storage;
251
252static coap_pdu_t pdu_storage_data[COAP_MAX_PDUS];
253static memarray_t pdu_storage;
254
255/* The pdubuf is the storage for holding the (assembled) PDU data in a
256 * coap_pdu_t structure. */
257union pdubuf_t {
258 void *p; /* try to convince the compiler to word-align this structure */
259 char buf[COAP_DEFAULT_MAX_PDU_RX_SIZE];
260};
261
262static union pdubuf_t pdubuf_storage_data[COAP_MAX_PDUS];
263static memarray_t pdubuf_storage;
264
265#if COAP_SERVER_SUPPORT
266static coap_resource_t resource_storage_data[COAP_MAX_RESOURCES];
267static memarray_t resource_storage;
268#endif /* COAP_SERVER_SUPPORT */
269
270#ifdef COAP_WITH_LIBTINYDTLS
271#undef PACKAGE_BUGREPORT
272#include <session.h>
273static session_t dtls_storage_data[COAP_MAX_DTLS_SESSIONS];
274static memarray_t dtls_storage;
275#endif /* COAP_WITH_LIBTINYDTLS */
276
277static coap_session_t session_storage_data[COAP_MAX_SESSIONS];
278static memarray_t session_storage;
279
280/* The optbuf_t is the storage for holding optlist nodes. */
281struct optbuf_t {
282 coap_optlist_t optlist;
283 char optbuf[COAP_MAX_OPTION_SIZE];
284};
285static struct optbuf_t option_storage_data[COAP_MAX_OPTIONS];
286static memarray_t option_storage;
287
288#if COAP_SERVER_SUPPORT
289static coap_cache_key_t cache_key_storage_data[COAP_MAX_CACHE_KEYS];
290static memarray_t cache_key_storage;
291
292static coap_cache_entry_t cache_entry_storage_data[COAP_MAX_CACHE_ENTRIES];
293static memarray_t cache_entry_storage;
294#endif /* COAP_SERVER_SUPPORT */
295
296#if COAP_CLIENT_SUPPORT
297static coap_lg_crcv_t cache_lg_crcv_storage_data[COAP_MAX_LG_CRCVS];
298static memarray_t cache_lg_crcv_storage;
299#endif /* COAP_CLIENT_SUPPORT */
300
301#if COAP_SERVER_SUPPORT
302static coap_lg_srcv_t cache_lg_srcv_storage_data[COAP_MAX_LG_SRCVS];
303static memarray_t cache_lg_srcv_storage;
304
305static coap_lg_xmit_t cache_lg_xmit_storage_data[COAP_MAX_LG_XMITS];
306static memarray_t cache_lg_xmit_storage;
307#endif /* COAP_SERVER_SUPPORT */
308
309#define INIT_STORAGE(Storage, Count) \
310 memarray_init(&(Storage ## _storage), (Storage ## _storage_data), sizeof(Storage ## _storage_data[0]), (Count));
311
312#define STORAGE_PTR(Storage) (&(Storage ## _storage))
313
314void
315coap_memory_init(void) {
316 INIT_STORAGE(string, COAP_MAX_STRINGS);
317#if COAP_SERVER_SUPPORT
318 INIT_STORAGE(endpoint, COAP_MAX_ENDPOINTS);
319 INIT_STORAGE(attr, COAP_MAX_ATTRIBUTE_STRINGS);
320#endif /* COAP_SERVER_SUPPORT */
321 INIT_STORAGE(pkt, COAP_MAX_PACKETS);
322 INIT_STORAGE(node, COAP_MAX_NODES);
323 INIT_STORAGE(context, COAP_MAX_CONTEXTS);
324 INIT_STORAGE(pdu, COAP_MAX_PDUS);
325 INIT_STORAGE(pdubuf, COAP_MAX_PDUS);
326#if COAP_SERVER_SUPPORT
327 INIT_STORAGE(resource, COAP_MAX_RESOURCES);
328 INIT_STORAGE(resattr, COAP_MAX_ATTRIBUTES);
329#endif /* COAP_SERVER_SUPPORT */
330#ifdef COAP_WITH_LIBTINYDTLS
331 INIT_STORAGE(dtls, COAP_MAX_DTLS_SESSIONS);
332#endif
333 INIT_STORAGE(session, COAP_MAX_SESSIONS);
334 INIT_STORAGE(option, COAP_MAX_OPTIONS);
335#if COAP_SERVER_SUPPORT
336 INIT_STORAGE(cache_key, COAP_MAX_CACHE_KEYS);
337 INIT_STORAGE(cache_entry, COAP_MAX_CACHE_ENTRIES);
338#endif /* COAP_SERVER_SUPPORT */
339#if COAP_CLIENT_SUPPORT
340 INIT_STORAGE(cache_lg_crcv, COAP_MAX_LG_CRCVS);
341#endif /* COAP_SERVER_SUPPORT */
342#if COAP_SERVER_SUPPORT
343 INIT_STORAGE(cache_lg_srcv, COAP_MAX_LG_SRCVS);
344 INIT_STORAGE(cache_lg_xmit, COAP_MAX_LG_XMITS);
345#endif /* COAP_SERVER_SUPPORT */
346}
347
348static memarray_t *
349get_container(coap_memory_tag_t type) {
350 switch (type) {
351#if COAP_SERVER_SUPPORT
353 /* fall through */
355 return &attr_storage;
356#endif /* COAP_SERVER_SUPPORT */
357 case COAP_PACKET:
358 return &pkt_storage;
359 case COAP_NODE:
360 return &node_storage;
361 case COAP_CONTEXT:
362 return STORAGE_PTR(context);
363#if COAP_SERVER_SUPPORT
364 case COAP_ENDPOINT:
365 return &endpoint_storage;
366#endif /* COAP_SERVER_SUPPORT */
367 case COAP_PDU:
368 return &pdu_storage;
369 case COAP_PDU_BUF:
370 return &pdubuf_storage;
371#if COAP_SERVER_SUPPORT
372 case COAP_RESOURCE:
373 return &resource_storage;
375 return &resattr_storage;
376#endif /* COAP_SERVER_SUPPORT */
377#ifdef COAP_WITH_LIBTINYDTLS
379 return &dtls_storage;
380#endif
381 case COAP_SESSION:
382 return &session_storage;
383 case COAP_OPTLIST:
384 return &option_storage;
385#if COAP_SERVER_SUPPORT
386 case COAP_CACHE_KEY:
387 return &cache_key_storage;
388 case COAP_CACHE_ENTRY:
389 return &cache_entry_storage;
390#endif /* COAP_SERVER_SUPPORT */
391#if COAP_CLIENT_SUPPORT
392 case COAP_LG_CRCV:
393 return &cache_lg_crcv_storage;
394#endif /* COAP_CLIENT_SUPPORT */
395#if COAP_SERVER_SUPPORT
396 case COAP_LG_SRCV:
397 return &cache_lg_srcv_storage;
398 case COAP_LG_XMIT:
399 return &cache_lg_xmit_storage;
400#endif /* COAP_SERVER_SUPPORT */
401 case COAP_STRING:
402 /* fall through */
403 default:
404 return &string_storage;
405 }
406}
407
408void *
409coap_malloc_type(coap_memory_tag_t type, size_t size) {
410 memarray_t *container = get_container(type);
411 void *ptr;
412 assert(container);
413
414 if (size > container->size) {
415 coap_log_warn("coap_malloc_type: Requested memory exceeds maximum object "
416 "size (type %d, size %zu, max %d)\n",
417 type, size, container->size);
418 return NULL;
419 }
420
421 ptr = memarray_alloc(container);
422 if (!ptr)
423 coap_log_warn("coap_malloc_type: Failure (no free blocks) for type %d\n",
424 type);
425 return ptr;
426}
427
428void
429coap_free_type(coap_memory_tag_t type, void *object) {
430 if (object != NULL)
431 memarray_free(get_container(type), object);
432}
433
434void *
435coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
436 memarray_t *container = get_container(type);
437
438 assert(container);
439 /* The fixed container is all we have to work with */
440 if (p) {
441 if (size > container->size) {
442 coap_log_warn("coap_realloc_type: Requested memory exceeds maximum object "
443 "size (type %d, size %zu, max %d)\n",
444 type, size, container->size);
445 return NULL;
446 }
447 if (size == 0) {
448 coap_free_type(type, p);
449 return NULL;
450 }
451 return p;
452 }
453 return coap_malloc_type(type, size);
454}
455#else /* ! RIOT_VERSION */
456
457#if defined(HAVE_MALLOC) || defined(__MINGW32__)
458#include <stdlib.h>
459
460void
461coap_memory_init(void) {
462}
463
464void *
465coap_malloc_type(coap_memory_tag_t type, size_t size) {
466 (void)type;
467 return malloc(size);
468}
469
470void *
471coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
472 (void)type;
473 return realloc(p, size);
474}
475
476void
477coap_free_type(coap_memory_tag_t type, void *p) {
478 (void)type;
479 free(p);
480}
481
482#else /* ! HAVE_MALLOC && !__MINGW32__ */
483
484#ifdef WITH_CONTIKI
485#include "lib/heapmem.h"
486
487void
488coap_memory_init(void) {
489}
490
491void *
492coap_malloc_type(coap_memory_tag_t type, size_t size) {
493 return heapmem_alloc(size);
494}
495
496void *
497coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
498 return heapmem_realloc(p, size);
499}
500
501void
502coap_free_type(coap_memory_tag_t type, void *ptr) {
503 heapmem_free(ptr);
504}
505#endif /* WITH_CONTIKI */
506
507#endif /* ! HAVE_MALLOC */
508
509#endif /* ! RIOT_VERSION */
Pulls together all the internal only header files.
void coap_memory_init(void)
Initializes libcoap's memory management.
coap_memory_tag_t
Type specifiers for coap_malloc_type().
Definition: coap_mem.h:37
@ COAP_DTLS_SESSION
Definition: coap_mem.h:49
@ COAP_SESSION
Definition: coap_mem.h:50
@ COAP_CACHE_KEY
Definition: coap_mem.h:52
@ COAP_NODE
Definition: coap_mem.h:42
@ COAP_CACHE_ENTRY
Definition: coap_mem.h:53
@ COAP_RESOURCE
Definition: coap_mem.h:47
@ COAP_RESOURCEATTR
Definition: coap_mem.h:48
@ COAP_LG_XMIT
Definition: coap_mem.h:54
@ COAP_ATTRIBUTE_VALUE
Definition: coap_mem.h:40
@ COAP_ENDPOINT
Definition: coap_mem.h:44
@ COAP_CONTEXT
Definition: coap_mem.h:43
@ COAP_OPTLIST
Definition: coap_mem.h:51
@ COAP_PDU
Definition: coap_mem.h:45
@ COAP_LG_CRCV
Definition: coap_mem.h:55
@ COAP_ATTRIBUTE_NAME
Definition: coap_mem.h:39
@ COAP_LG_SRCV
Definition: coap_mem.h:56
@ COAP_PACKET
Definition: coap_mem.h:41
@ COAP_STRING
Definition: coap_mem.h:38
@ COAP_PDU_BUF
Definition: coap_mem.h:46
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...
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.
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
CoAP context interface.
Pre-defined constants that reflect defaults for CoAP.
Generic resource handling.
Defines the application visible session information.
#define coap_log_warn(...)
Definition: coap_debug.h:102
struct coap_string_t coap_string_t
CoAP string data definition.
Limits the number of subscribers for each resource that this server support.
The CoAP stack's global state is stored in a coap_context_t object.
Abstraction of virtual endpoint that can be attached to coap_context_t.
Structure to hold large body (many blocks) client receive information.
Structure to hold large body (many blocks) server receive information.
Structure to hold large body (many blocks) transmission information.
Representation of chained list of CoAP options to install.
Definition: coap_option.h:325
structure for CoAP PDUs
Queue entry.
Abstraction of resource that can be attached to coap_context_t.
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:38