libcoap 4.3.1
mem.c
Go to the documentation of this file.
1/* mem.c -- CoAP memory handling
2 *
3 * Copyright (C) 2014--2015,2019--2020 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 <session.h>
26#undef PACKAGE_NAME
27#undef PACKAGE_STRING
28#undef PACKAGE_TARNAME
29#undef PACKAGE_VERSION
30
31#include "coap_session.h"
32#include "net.h"
33#include "pdu.h"
34#include "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
178/* The memstr is the storage for holding coap_string_t structure
179 * together with its contents. */
180union memstr_t {
182 char buf[sizeof(coap_string_t) + COAP_MAX_STRING_SIZE];
183};
184
185/* The attrstr is the storage for holding coap_string_t structures to
186 * serve as attribute names or values. As these are typically short,
187 * they are stored in a different arena than generic strings. */
188union attrstr_t {
190 char buf[sizeof(coap_string_t) + COAP_MAX_ATTRIBUTE_SIZE];
191};
192
193static union memstr_t string_storage_data[COAP_MAX_STRINGS];
194static memarray_t string_storage;
195
196static coap_endpoint_t endpoint_storage_data[COAP_MAX_ENDPOINTS];
197static memarray_t endpoint_storage;
198
199static union attrstr_t attr_storage_data[COAP_MAX_ATTRIBUTE_STRINGS];
200static memarray_t attr_storage;
201
202static coap_attr_t resattr_storage_data[COAP_MAX_ATTRIBUTES];
203static memarray_t resattr_storage;
204
205static coap_packet_t pkt_storage_data[COAP_MAX_PACKETS];
206static memarray_t pkt_storage;
207
208static coap_queue_t node_storage_data[COAP_MAX_NODES];
209static memarray_t node_storage;
210
211static coap_context_t context_storage_data[COAP_MAX_CONTEXTS];
212static memarray_t context_storage;
213
214static coap_pdu_t pdu_storage_data[COAP_MAX_PDUS];
215static memarray_t pdu_storage;
216
217/* The pdubuf is the storage for holding the (assembled) PDU data in a
218 * coap_pdu_t structure. */
219union pdubuf_t {
220 void *p; /* try to convince the compiler to word-align this structure */
221 char buf[COAP_DEFAULT_MAX_PDU_RX_SIZE];
222};
223
224static union pdubuf_t pdubuf_storage_data[COAP_MAX_PDUS];
225static memarray_t pdubuf_storage;
226
227static coap_resource_t resource_storage_data[COAP_MAX_RESOURCES];
228static memarray_t resource_storage;
229
230#ifdef HAVE_LIBTINYDTLS
231static session_t dtls_storage_data[COAP_MAX_DTLS_SESSIONS];
232static memarray_t dtls_storage;
233#endif /* HAVE_LIBTINYDTLS */
234
235static coap_session_t session_storage_data[COAP_MAX_SESSIONS];
236static memarray_t session_storage;
237
238/* The optbuf_t is the storage for holding optlist nodes. */
239struct optbuf_t {
240 coap_optlist_t optlist;
241 char optbuf[COAP_MAX_OPTION_SIZE];
242};
243static struct optbuf_t option_storage_data[COAP_MAX_OPTIONS];
244static memarray_t option_storage;
245
246static coap_cache_key_t cache_key_storage_data[COAP_MAX_CACHE_KEYS];
247static memarray_t cache_key_storage;
248
249static coap_cache_entry_t cache_entry_storage_data[COAP_MAX_CACHE_ENTRIES];
250static memarray_t cache_entry_storage;
251
252#define INIT_STORAGE(Storage, Count) \
253 memarray_init(&(Storage ## _storage), (Storage ## _storage_data), sizeof(Storage ## _storage_data[0]), (Count));
254
255#define STORAGE_PTR(Storage) (&(Storage ## _storage))
256
257void
258coap_memory_init(void) {
259 INIT_STORAGE(string, COAP_MAX_STRINGS);
260 INIT_STORAGE(endpoint, COAP_MAX_ENDPOINTS);
261 INIT_STORAGE(attr, COAP_MAX_ATTRIBUTE_STRINGS);
262 INIT_STORAGE(pkt, COAP_MAX_PACKETS);
263 INIT_STORAGE(node, COAP_MAX_NODES);
264 INIT_STORAGE(context, COAP_MAX_CONTEXTS);
265 INIT_STORAGE(pdu, COAP_MAX_PDUS);
266 INIT_STORAGE(pdubuf, COAP_MAX_PDUS);
267 INIT_STORAGE(resource, COAP_MAX_RESOURCES);
268 INIT_STORAGE(resattr, COAP_MAX_ATTRIBUTES);
269#ifdef HAVE_LIBTINYDTLS
270 INIT_STORAGE(dtls, COAP_MAX_DTLS_SESSIONS);
271#endif
272 INIT_STORAGE(session, COAP_MAX_SESSIONS);
273 INIT_STORAGE(option, COAP_MAX_OPTIONS);
274 INIT_STORAGE(cache_key, COAP_MAX_CACHE_KEYS);
275 INIT_STORAGE(cache_entry, COAP_MAX_CACHE_ENTRIES);
276}
277
278static memarray_t *
279get_container(coap_memory_tag_t type) {
280 switch(type) {
282 /* fall through */
283 case COAP_ATTRIBUTE_VALUE: return &attr_storage;
284 case COAP_PACKET: return &pkt_storage;
285 case COAP_NODE: return &node_storage;
286 case COAP_CONTEXT: return STORAGE_PTR(context);
287 case COAP_ENDPOINT: return &endpoint_storage;
288 case COAP_PDU: return &pdu_storage;
289 case COAP_PDU_BUF: return &pdubuf_storage;
290 case COAP_RESOURCE: return &resource_storage;
291 case COAP_RESOURCEATTR: return &resattr_storage;
292#ifdef HAVE_LIBTINYDTLS
293 case COAP_DTLS_SESSION: return &dtls_storage;
294#endif
295 case COAP_SESSION: return &session_storage;
296 case COAP_OPTLIST: return &option_storage;
297 case COAP_CACHE_KEY: return &cache_key_storage;
298 case COAP_CACHE_ENTRY: return &cache_key_entry;
299 case COAP_STRING:
300 /* fall through */
301 default:
302 return &string_storage;
303 }
304}
305
306void *
307coap_malloc_type(coap_memory_tag_t type, size_t size) {
308 memarray_t *container = get_container(type);
309 void *ptr;
310 assert(container);
311
312 if (size > container->size) {
314 "coap_malloc_type: Requested memory exceeds maximum object "
315 "size (type %d, size %zu, max %d)\n",
316 type, size, container->size);
317 return NULL;
318 }
319
320 ptr = memarray_alloc(container);
321 if (!ptr)
323 "coap_malloc_type: Failure (no free blocks) for type %d\n",
324 type);
325 return ptr;
326}
327
328void
329coap_free_type(coap_memory_tag_t type, void *object) {
330 if (object != NULL)
331 memarray_free(get_container(type), object);
332}
333#else /* ! RIOT_VERSION */
334
335#ifdef HAVE_MALLOC
336#include <stdlib.h>
337
338void
339coap_memory_init(void) {
340}
341
342void *
343coap_malloc_type(coap_memory_tag_t type, size_t size) {
344 (void)type;
345 return malloc(size);
346}
347
348void *
349coap_realloc_type(coap_memory_tag_t type, void* p, size_t size) {
350 (void)type;
351 return realloc(p, size);
352}
353
354void
355coap_free_type(coap_memory_tag_t type, void *p) {
356 (void)type;
357 free(p);
358}
359
360#else /* ! HAVE_MALLOC */
361
362#ifdef WITH_CONTIKI
363
368#ifndef COAP_MAX_STRING_SIZE
369#define COAP_MAX_STRING_SIZE 64
370#endif /* COAP_MAX_STRING_SIZE */
371
376#ifndef COAP_MAX_STRINGS
377#define COAP_MAX_STRINGS 10
378#endif /* COAP_MAX_STRINGS */
379
380struct coap_stringbuf_t {
381 char data[COAP_MAX_STRING_SIZE];
382};
383
384
385#define COAP_MAX_PACKET_SIZE (sizeof(coap_packet_t) + COAP_RXBUFFER_SIZE)
386#ifndef COAP_MAX_PACKETS
387#define COAP_MAX_PACKETS 2
388#endif /* COAP_MAX_PACKETS */
389
390typedef union {
391 coap_pdu_t packet; /* try to convince the compiler to word-align this structure */
392 char buf[COAP_MAX_PACKET_SIZE];
393} coap_packetbuf_t;
394
395MEMB(string_storage, struct coap_stringbuf_t, COAP_MAX_STRINGS);
396MEMB(packet_storage, coap_packetbuf_t, COAP_MAX_PACKETS);
397MEMB(session_storage, coap_session_t, COAP_MAX_SESSIONS);
398MEMB(node_storage, coap_queue_t, COAP_PDU_MAXCNT);
399MEMB(pdu_storage, coap_pdu_t, COAP_PDU_MAXCNT);
400MEMB(pdu_buf_storage, coap_packetbuf_t, COAP_PDU_MAXCNT);
401MEMB(resource_storage, coap_resource_t, COAP_MAX_RESOURCES);
402MEMB(attribute_storage, coap_attr_t, COAP_MAX_ATTRIBUTES);
403MEMB(cache_key_storage, coap_cache_key_t, COAP_MAX_CACHE_KEYS);
404MEMB(cache_entry_storage, coap_cache_entry_t, COAP_MAX_CACHE_ENTRIES);
405MEMB(lg_xmit_storage, coap_lg_xmit_t, COAP_MAX_LG_XMIT);
406MEMB(lg_crcv_storage, coap_lg_crcv_t, COAP_MAX_LG_CRCV);
407MEMB(lg_srcv_storage, coap_lg_srcv_t, COAP_MAX_LG_SRCV);
408
409static struct memb *
410get_container(coap_memory_tag_t type) {
411 switch(type) {
412 case COAP_PACKET: return &packet_storage;
413 case COAP_NODE: return &node_storage;
414 case COAP_SESSION: return &session_storage;
415 case COAP_PDU: return &pdu_storage;
416 case COAP_PDU_BUF: return &pdu_buf_storage;
417 case COAP_RESOURCE: return &resource_storage;
418 case COAP_RESOURCEATTR: return &attribute_storage;
419 case COAP_CACHE_KEY: return &cache_key_storage;
420 case COAP_CACHE_ENTRY: return &cache_entry_storage;
421 case COAP_LG_XMIT: return &lg_xmit_storage;
422 case COAP_LG_CRCV: return &lg_crcv_storage;
423 case COAP_LG_SRCV: return &lg_srcv_storage;
424 default:
425 return &string_storage;
426 }
427}
428
429void
430coap_memory_init(void) {
431 memb_init(&string_storage);
432 memb_init(&packet_storage);
433 memb_init(&node_storage);
434 memb_init(&session_storage);
435 memb_init(&pdu_storage);
436 memb_init(&pdu_buf_storage);
437 memb_init(&resource_storage);
438 memb_init(&attribute_storage);
439 memb_init(&cache_key_storage);
440 memb_init(&cache_entry_storage);
441 memb_init(&lg_xmit_storage);
442 memb_init(&lg_crcv_storage);
443 memb_init(&lg_srcv_storage);
444}
445
446void *
447coap_malloc_type(coap_memory_tag_t type, size_t size) {
448 struct memb *container = get_container(type);
449 void *ptr;
450
451 assert(container);
452
453 if (size > container->size) {
455 "coap_malloc_type: Requested memory exceeds maximum object "
456 "size (type %d, size %d, max %d)\n",
457 type, (int)size, container->size);
458 return NULL;
459 }
460
461 ptr = memb_alloc(container);
462 if (!ptr)
464 "coap_malloc_type: Failure (no free blocks) for type %d\n",
465 type);
466 return ptr;
467}
468
469void
470coap_free_type(coap_memory_tag_t type, void *object) {
471 memb_free(get_container(type), object);
472}
473#endif /* WITH_CONTIKI */
474
475#endif /* ! HAVE_MALLOC */
476
477#endif /* ! RIOT_VERSION */
Pulls together all the internal only header files.
Defines the application visible session information.
#define LOG_WARNING
Definition: coap_debug.h:72
#define coap_log(level,...)
Logging function.
Definition: coap_debug.h:165
struct coap_string_t coap_string_t
CoAP string data definition.
void coap_memory_init(void)
Initializes libcoap's memory management.
coap_memory_tag_t
Type specifiers for coap_malloc_type().
Definition: mem.h:36
@ COAP_SESSION
Definition: mem.h:51
@ COAP_CACHE_KEY
Definition: mem.h:53
@ COAP_NODE
Definition: mem.h:41
@ COAP_CACHE_ENTRY
Definition: mem.h:54
@ COAP_RESOURCE
Definition: mem.h:46
@ COAP_RESOURCEATTR
Definition: mem.h:47
@ COAP_LG_XMIT
Definition: mem.h:55
@ COAP_ATTRIBUTE_VALUE
Definition: mem.h:39
@ COAP_ENDPOINT
Definition: mem.h:43
@ COAP_CONTEXT
Definition: mem.h:42
@ COAP_OPTLIST
Definition: mem.h:52
@ COAP_PDU
Definition: mem.h:44
@ COAP_LG_CRCV
Definition: mem.h:56
@ COAP_ATTRIBUTE_NAME
Definition: mem.h:38
@ COAP_LG_SRCV
Definition: mem.h:57
@ COAP_PACKET
Definition: mem.h:40
@ COAP_STRING
Definition: mem.h:37
@ COAP_PDU_BUF
Definition: mem.h:45
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.
Abstraction of attribute associated with a resource.
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:328
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: str.h:38