libcoap 4.3.0
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
11
12#include "coap3/coap_internal.h"
13
14#if defined(RIOT_VERSION) && defined(MODULE_MEMARRAY)
15#include <memarray.h>
16
17#undef PACKAGE_NAME
18#undef PACKAGE_STRING
19#undef PACKAGE_TARNAME
20#undef PACKAGE_VERSION
21#include <session.h>
22#undef PACKAGE_NAME
23#undef PACKAGE_STRING
24#undef PACKAGE_TARNAME
25#undef PACKAGE_VERSION
26
27#include "coap_session.h"
28#include "net.h"
29#include "pdu.h"
30#include "resource.h"
31
36#ifndef COAP_MAX_STRING_SIZE
37#define COAP_MAX_STRING_SIZE (64U)
38#endif /* COAP_MAX_STRING_SIZE */
39
44#ifndef COAP_MAX_STRINGS
45#define COAP_MAX_STRINGS (16U)
46#endif /* COAP_MAX_STRINGS */
47
52#ifndef COAP_MAX_ENDPOINTS
53#define COAP_MAX_ENDPOINTS (4U)
54#endif /* COAP_MAX_ENDPOINTS */
55
60#ifndef COAP_MAX_RESOURCES
61#define COAP_MAX_RESOURCES (8U)
62#endif /* COAP_MAX_RESOURCES */
63
68#ifndef COAP_MAX_ATTRIBUTES
69#define COAP_MAX_ATTRIBUTES \
70 ((COAP_MAX_RESOURCES) * 4U)
71#endif /* COAP_MAX_ATTRIBUTE_STRINGS */
72
79#ifndef COAP_MAX_ATTRIBUTE_STRINGS
80#define COAP_MAX_ATTRIBUTE_STRINGS (COAP_MAX_ATTRIBUTES)
81#endif /* COAP_MAX_ATTRIBUTE_STRINGS */
82
87#ifndef COAP_MAX_ATTRIBUTE_SIZE
88#define COAP_MAX_ATTRIBUTE_SIZE (16U)
89#endif /* COAP_MAX_ATTRIBUTE_SIZE */
90
95#ifndef COAP_MAX_PACKETS
96#define COAP_MAX_PACKETS (4U)
97#endif /* COAP_MAX_PACKETS */
98
104#ifndef COAP_MAX_NODES
105#define COAP_MAX_NODES \
106 ((COAP_MAX_ENDPOINTS) * (COAP_MAX_PACKETS))
107#endif /* COAP_MAX_NODES */
108
113#ifndef COAP_MAX_CONTEXTS
114#define COAP_MAX_CONTEXTS (1U)
115#endif /* COAP_MAX_CONTEXTS */
116
122#ifndef COAP_MAX_PDUS
123#define COAP_MAX_PDUS ((COAP_MAX_ENDPOINTS) * 4U)
124#endif /* COAP_MAX_PDUS */
125
130#ifndef COAP_MAX_DTLS_SESSIONS
131#define COAP_MAX_DTLS_SESSIONS (2U)
132#endif /* COAP_MAX_CONTEXTS */
133
138#ifndef COAP_MAX_SESSIONS
139#define COAP_MAX_SESSIONS (COAP_MAX_ENDPOINTS)
140#endif /* COAP_MAX_CONTEXTS */
141
146#ifndef COAP_MAX_OPTIONS
147#define COAP_MAX_OPTIONS (16U)
148#endif /* COAP_MAX_CONTEXTS */
149
154#ifndef COAP_MAX_OPTION_SIZE
155#define COAP_MAX_OPTION_SIZE (16U)
156#endif /* COAP_MAX_OPTION_SIZE */
157
162#ifndef COAP_MAX_CACHE_KEYS
163#define COAP_MAX_CACHE_KEYS (2U)
164#endif /* COAP_MAX_CACHE_KEYS */
165
170#ifndef COAP_MAX_CACHE_ENTRIES
171#define COAP_MAX_CACHE_ENTRIES (2U)
172#endif /* COAP_MAX_CACHE_ENTRIES */
173
174/* The memstr is the storage for holding coap_string_t structure
175 * together with its contents. */
176union memstr_t {
178 char buf[sizeof(coap_string_t) + COAP_MAX_STRING_SIZE];
179};
180
181/* The attrstr is the storage for holding coap_string_t structures to
182 * serve as attribute names or values. As these are typically short,
183 * they are stored in a different arena than generic strings. */
184union attrstr_t {
186 char buf[sizeof(coap_string_t) + COAP_MAX_ATTRIBUTE_SIZE];
187};
188
189static union memstr_t string_storage_data[COAP_MAX_STRINGS];
190static memarray_t string_storage;
191
192static coap_endpoint_t endpoint_storage_data[COAP_MAX_ENDPOINTS];
193static memarray_t endpoint_storage;
194
195static union attrstr_t attr_storage_data[COAP_MAX_ATTRIBUTE_STRINGS];
196static memarray_t attr_storage;
197
198static coap_attr_t resattr_storage_data[COAP_MAX_ATTRIBUTES];
199static memarray_t resattr_storage;
200
201static coap_packet_t pkt_storage_data[COAP_MAX_PACKETS];
202static memarray_t pkt_storage;
203
204static coap_queue_t node_storage_data[COAP_MAX_NODES];
205static memarray_t node_storage;
206
207static coap_context_t context_storage_data[COAP_MAX_CONTEXTS];
208static memarray_t context_storage;
209
210static coap_pdu_t pdu_storage_data[COAP_MAX_PDUS];
211static memarray_t pdu_storage;
212
213/* The pdubuf is the storage for holding the (assembled) PDU data in a
214 * coap_pdu_t structure. */
215union pdubuf_t {
216 void *p; /* try to convince the compiler to word-align this structure */
218};
219
220static union pdubuf_t pdubuf_storage_data[COAP_MAX_PDUS];
221static memarray_t pdubuf_storage;
222
223static coap_resource_t resource_storage_data[COAP_MAX_RESOURCES];
224static memarray_t resource_storage;
225
226#ifdef HAVE_LIBTINYDTLS
227static session_t dtls_storage_data[COAP_MAX_DTLS_SESSIONS];
228static memarray_t dtls_storage;
229#endif /* HAVE_LIBTINYDTLS */
230
231static coap_session_t session_storage_data[COAP_MAX_SESSIONS];
232static memarray_t session_storage;
233
234/* The optbuf_t is the storage for holding optlist nodes. */
235struct optbuf_t {
236 coap_optlist_t optlist;
237 char optbuf[COAP_MAX_OPTION_SIZE];
238};
239static struct optbuf_t option_storage_data[COAP_MAX_OPTIONS];
240static memarray_t option_storage;
241
242static coap_cache_key_t cache_key_storage_data[COAP_MAX_CACHE_KEYS];
243static memarray_t cache_key_storage;
244
245static coap_cache_entry_t cache_entry_storage_data[COAP_MAX_CACHE_ENTRIES];
246static memarray_t cache_entry_storage;
247
248#define INIT_STORAGE(Storage, Count) \
249 memarray_init(&(Storage ## _storage), (Storage ## _storage_data), sizeof(Storage ## _storage_data[0]), (Count));
250
251#define STORAGE_PTR(Storage) (&(Storage ## _storage))
252
253void
254coap_memory_init(void) {
255 INIT_STORAGE(string, COAP_MAX_STRINGS);
256 INIT_STORAGE(endpoint, COAP_MAX_ENDPOINTS);
257 INIT_STORAGE(attr, COAP_MAX_ATTRIBUTE_STRINGS);
258 INIT_STORAGE(pkt, COAP_MAX_PACKETS);
259 INIT_STORAGE(node, COAP_MAX_NODES);
260 INIT_STORAGE(context, COAP_MAX_CONTEXTS);
261 INIT_STORAGE(pdu, COAP_MAX_PDUS);
262 INIT_STORAGE(pdubuf, COAP_MAX_PDUS);
263 INIT_STORAGE(resource, COAP_MAX_RESOURCES);
264 INIT_STORAGE(resattr, COAP_MAX_ATTRIBUTES);
265#ifdef HAVE_LIBTINYDTLS
266 INIT_STORAGE(dtls, COAP_MAX_DTLS_SESSIONS);
267#endif
268 INIT_STORAGE(session, COAP_MAX_SESSIONS);
269 INIT_STORAGE(option, COAP_MAX_OPTIONS);
270 INIT_STORAGE(cache_key, COAP_MAX_CACHE_KEYS);
271 INIT_STORAGE(cache_entry, COAP_MAX_CACHE_ENTRIES);
272}
273
274static memarray_t *
275get_container(coap_memory_tag_t type) {
276 switch(type) {
278 /* fall through */
279 case COAP_ATTRIBUTE_VALUE: return &attr_storage;
280 case COAP_PACKET: return &pkt_storage;
281 case COAP_NODE: return &node_storage;
282 case COAP_CONTEXT: return STORAGE_PTR(context);
283 case COAP_ENDPOINT: return &endpoint_storage;
284 case COAP_PDU: return &pdu_storage;
285 case COAP_PDU_BUF: return &pdubuf_storage;
286 case COAP_RESOURCE: return &resource_storage;
287 case COAP_RESOURCEATTR: return &resattr_storage;
288#ifdef HAVE_LIBTINYDTLS
289 case COAP_DTLS_SESSION: return &dtls_storage;
290#endif
291 case COAP_SESSION: return &session_storage;
292 case COAP_OPTLIST: return &option_storage;
293 case COAP_CACHE_KEY: return &cache_key_storage;
294 case COAP_CACHE_ENTRY: return &cache_key_entry;
295 case COAP_STRING:
296 /* fall through */
297 default:
298 return &string_storage;
299 }
300}
301
302void *
303coap_malloc_type(coap_memory_tag_t type, size_t size) {
304 memarray_t *container = get_container(type);
305 void *ptr;
306 assert(container);
307
308 if (size > container->size) {
310 "coap_malloc_type: Requested memory exceeds maximum object "
311 "size (type %d, size %zu, max %d)\n",
312 type, size, container->size);
313 return NULL;
314 }
315
316 ptr = memarray_alloc(container);
317 if (!ptr)
319 "coap_malloc_type: Failure (no free blocks) for type %d\n",
320 type);
321 return ptr;
322}
323
324void
325coap_free_type(coap_memory_tag_t type, void *object) {
326 if (object != NULL)
327 memarray_free(get_container(type), object);
328}
329#else /* ! RIOT_VERSION */
330
331#ifdef HAVE_MALLOC
332#include <stdlib.h>
333
334void
335coap_memory_init(void) {
336}
337
338void *
339coap_malloc_type(coap_memory_tag_t type, size_t size) {
340 (void)type;
341 return malloc(size);
342}
343
344void *
345coap_realloc_type(coap_memory_tag_t type, void* p, size_t size) {
346 (void)type;
347 return realloc(p, size);
348}
349
350void
351coap_free_type(coap_memory_tag_t type, void *p) {
352 (void)type;
353 free(p);
354}
355
356#else /* ! HAVE_MALLOC */
357
358#ifdef WITH_CONTIKI
359
364#ifndef COAP_MAX_STRING_SIZE
365#define COAP_MAX_STRING_SIZE 64
366#endif /* COAP_MAX_STRING_SIZE */
367
372#ifndef COAP_MAX_STRINGS
373#define COAP_MAX_STRINGS 10
374#endif /* COAP_MAX_STRINGS */
375
376struct coap_stringbuf_t {
377 char data[COAP_MAX_STRING_SIZE];
378};
379
380
381#define COAP_MAX_PACKET_SIZE (sizeof(coap_packet_t) + COAP_RXBUFFER_SIZE)
382#ifndef COAP_MAX_PACKETS
383#define COAP_MAX_PACKETS 2
384#endif /* COAP_MAX_PACKETS */
385
386typedef union {
387 coap_pdu_t packet; /* try to convince the compiler to word-align this structure */
388 char buf[COAP_MAX_PACKET_SIZE];
389} coap_packetbuf_t;
390
391MEMB(string_storage, struct coap_stringbuf_t, COAP_MAX_STRINGS);
392MEMB(packet_storage, coap_packetbuf_t, COAP_MAX_PACKETS);
393MEMB(session_storage, coap_session_t, COAP_MAX_SESSIONS);
394MEMB(node_storage, coap_queue_t, COAP_PDU_MAXCNT);
395MEMB(pdu_storage, coap_pdu_t, COAP_PDU_MAXCNT);
396MEMB(pdu_buf_storage, coap_packetbuf_t, COAP_PDU_MAXCNT);
397MEMB(resource_storage, coap_resource_t, COAP_MAX_RESOURCES);
398MEMB(attribute_storage, coap_attr_t, COAP_MAX_ATTRIBUTES);
399MEMB(cache_key_storage, coap_cache_key_t, COAP_MAX_CACHE_KEYS);
400MEMB(cache_entry_storage, coap_cache_entry_t, COAP_MAX_CACHE_ENTRIES);
401MEMB(lg_xmit_storage, coap_lg_xmit_t, COAP_MAX_LG_XMIT);
402MEMB(lg_crcv_storage, coap_lg_crcv_t, COAP_MAX_LG_CRCV);
403MEMB(lg_srcv_storage, coap_lg_srcv_t, COAP_MAX_LG_SRCV);
404
405static struct memb *
406get_container(coap_memory_tag_t type) {
407 switch(type) {
408 case COAP_PACKET: return &packet_storage;
409 case COAP_NODE: return &node_storage;
410 case COAP_SESSION: return &session_storage;
411 case COAP_PDU: return &pdu_storage;
412 case COAP_PDU_BUF: return &pdu_buf_storage;
413 case COAP_RESOURCE: return &resource_storage;
414 case COAP_RESOURCEATTR: return &attribute_storage;
415 case COAP_CACHE_KEY: return &cache_key_storage;
416 case COAP_CACHE_ENTRY: return &cache_entry_storage;
417 case COAP_LG_XMIT: return &lg_xmit_storage;
418 case COAP_LG_CRCV: return &lg_crcv_storage;
419 case COAP_LG_SRCV: return &lg_srcv_storage;
420 default:
421 return &string_storage;
422 }
423}
424
425void
426coap_memory_init(void) {
427 memb_init(&string_storage);
428 memb_init(&packet_storage);
429 memb_init(&node_storage);
430 memb_init(&session_storage);
431 memb_init(&pdu_storage);
432 memb_init(&pdu_buf_storage);
433 memb_init(&resource_storage);
434 memb_init(&attribute_storage);
435 memb_init(&cache_key_storage);
436 memb_init(&cache_entry_storage);
437 memb_init(&lg_xmit_storage);
438 memb_init(&lg_crcv_storage);
439 memb_init(&lg_srcv_storage);
440}
441
442void *
443coap_malloc_type(coap_memory_tag_t type, size_t size) {
444 struct memb *container = get_container(type);
445 void *ptr;
446
447 assert(container);
448
449 if (size > container->size) {
451 "coap_malloc_type: Requested memory exceeds maximum object "
452 "size (type %d, size %d, max %d)\n",
453 type, (int)size, container->size);
454 return NULL;
455 }
456
457 ptr = memb_alloc(container);
458 if (!ptr)
460 "coap_malloc_type: Failure (no free blocks) for type %d\n",
461 type);
462 return ptr;
463}
464
465void
466coap_free_type(coap_memory_tag_t type, void *object) {
467 memb_free(get_container(type), object);
468}
469#endif /* WITH_CONTIKI */
470
471#endif /* ! HAVE_MALLOC */
472
473#endif /* ! RIOT_VERSION */
Pulls together all the internal only header files.
Defines the application visible session information.
#define coap_log(level,...)
Logging function.
Definition: coap_debug.h:152
@ LOG_WARNING
Warning.
Definition: coap_debug.h:56
#define COAP_DEFAULT_MAX_PDU_RX_SIZE
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:31
@ COAP_SESSION
Definition: mem.h:46
@ COAP_CACHE_KEY
Definition: mem.h:48
@ COAP_NODE
Definition: mem.h:36
@ COAP_CACHE_ENTRY
Definition: mem.h:49
@ COAP_RESOURCE
Definition: mem.h:41
@ COAP_RESOURCEATTR
Definition: mem.h:42
@ COAP_LG_XMIT
Definition: mem.h:50
@ COAP_ATTRIBUTE_VALUE
Definition: mem.h:34
@ COAP_ENDPOINT
Definition: mem.h:38
@ COAP_CONTEXT
Definition: mem.h:37
@ COAP_OPTLIST
Definition: mem.h:47
@ COAP_PDU
Definition: mem.h:39
@ COAP_LG_CRCV
Definition: mem.h:51
@ COAP_ATTRIBUTE_NAME
Definition: mem.h:33
@ COAP_LG_SRCV
Definition: mem.h:52
@ COAP_PACKET
Definition: mem.h:35
@ COAP_STRING
Definition: mem.h:32
@ COAP_PDU_BUF
Definition: mem.h:40
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().
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: option.h:327
structure for CoAP PDUs token, if any, follows the fixed size header, then options until payload mark...
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:32