libcoap 4.3.2rc2

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. */
216 union memstr_t {
217 coap_string_t s;
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. */
224 union attrstr_t {
225 coap_string_t s;
226 char buf[sizeof(coap_string_t) + COAP_MAX_ATTRIBUTE_SIZE];
227};
228
229 static union memstr_t string_storage_data[COAP_MAX_STRINGS];
230 static memarray_t string_storage;
231
232#if COAP_SERVER_SUPPORT
233 static coap_endpoint_t endpoint_storage_data[COAP_MAX_ENDPOINTS];
234 static memarray_t endpoint_storage;
235
236 static union attrstr_t attr_storage_data[COAP_MAX_ATTRIBUTE_STRINGS];
237 static memarray_t attr_storage;
238
239 static coap_attr_t resattr_storage_data[COAP_MAX_ATTRIBUTES];
240 static memarray_t resattr_storage;
241#endif /* COAP_SERVER_SUPPORT */
242
243 static coap_packet_t pkt_storage_data[COAP_MAX_PACKETS];
244 static memarray_t pkt_storage;
245
246 static coap_queue_t node_storage_data[COAP_MAX_NODES];
247 static memarray_t node_storage;
248
249 static coap_context_t context_storage_data[COAP_MAX_CONTEXTS];
250 static memarray_t context_storage;
251
252 static coap_pdu_t pdu_storage_data[COAP_MAX_PDUS];
253 static memarray_t pdu_storage;
254
255/* The pdubuf is the storage for holding the (assembled) PDU data in a
256 * coap_pdu_t structure. */
257 union 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
262 static union pdubuf_t pdubuf_storage_data[COAP_MAX_PDUS];
263 static memarray_t pdubuf_storage;
264
265#if COAP_SERVER_SUPPORT
266 static coap_resource_t resource_storage_data[COAP_MAX_RESOURCES];
267 static memarray_t resource_storage;
268#endif /* COAP_SERVER_SUPPORT */
269
270#ifdef COAP_WITH_LIBTINYDTLS
271#undef PACKAGE_BUGREPORT
272#include <session.h>
273 static session_t dtls_storage_data[COAP_MAX_DTLS_SESSIONS];
274 static memarray_t dtls_storage;
275#endif /* COAP_WITH_LIBTINYDTLS */
276
277 static coap_session_t session_storage_data[COAP_MAX_SESSIONS];
278 static memarray_t session_storage;
279
280/* The optbuf_t is the storage for holding optlist nodes. */
281 struct optbuf_t {
282 coap_optlist_t optlist;
283 char optbuf[COAP_MAX_OPTION_SIZE];
284};
285 static struct optbuf_t option_storage_data[COAP_MAX_OPTIONS];
286 static memarray_t option_storage;
287
288#if COAP_SERVER_SUPPORT
289 static coap_cache_key_t cache_key_storage_data[COAP_MAX_CACHE_KEYS];
290 static memarray_t cache_key_storage;
291
292 static coap_cache_entry_t cache_entry_storage_data[COAP_MAX_CACHE_ENTRIES];
293 static memarray_t cache_entry_storage;
294#endif /* COAP_SERVER_SUPPORT */
295
296#if COAP_CLIENT_SUPPORT
297 static coap_lg_crcv_t cache_lg_crcv_storage_data[COAP_MAX_LG_CRCVS];
298 static memarray_t cache_lg_crcv_storage;
299#endif /* COAP_CLIENT_SUPPORT */
300
301#if COAP_SERVER_SUPPORT
302 static coap_lg_srcv_t cache_lg_srcv_storage_data[COAP_MAX_LG_SRCVS];
303 static memarray_t cache_lg_srcv_storage;
304
305 static coap_lg_xmit_t cache_lg_xmit_storage_data[COAP_MAX_LG_XMITS];
306 static 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
314 void
315 coap_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
348 static memarray_t *
349get_container(coap_memory_tag_t type) {
350 switch (type) {
351#if COAP_SERVER_SUPPORT
352 case COAP_ATTRIBUTE_NAME:
353 /* fall through */
354 case COAP_ATTRIBUTE_VALUE:
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;
374 case COAP_RESOURCEATTR:
375 return &resattr_storage;
376#endif /* COAP_SERVER_SUPPORT */
377#ifdef COAP_WITH_LIBTINYDTLS
378 case COAP_DTLS_SESSION:
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
408 void *
409 coap_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
428 void
429 coap_free_type(coap_memory_tag_t type, void *object) {
430 if (object != NULL)
431 memarray_free(get_container(type), object);
432}
433
434 void *
435 coap_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
460 void
461 coap_memory_init(void) {
462}
463
464 void *
465 coap_malloc_type(coap_memory_tag_t type, size_t size) {
466 (void)type;
467 return malloc(size);
468}
469
470 void *
471 coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
472 (void)type;
473 return realloc(p, size);
474}
475
476 void
477 coap_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
487 void
488 coap_memory_init(void) {
489}
490
491 void *
492 coap_malloc_type(coap_memory_tag_t type, size_t size) {
493 return heapmem_alloc(size);
494}
495
496 void *
497 coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
498 return heapmem_realloc(p, size);
499}
500
501 void
502 coap_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 */
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_string_t
struct coap_string_t coap_string_t
CoAP string data definition.
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