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. */
180 union memstr_t {
181  coap_string_t s;
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. */
188 union attrstr_t {
189  coap_string_t s;
190  char buf[sizeof(coap_string_t) + COAP_MAX_ATTRIBUTE_SIZE];
191 };
192 
193 static union memstr_t string_storage_data[COAP_MAX_STRINGS];
194 static memarray_t string_storage;
195 
196 static coap_endpoint_t endpoint_storage_data[COAP_MAX_ENDPOINTS];
197 static memarray_t endpoint_storage;
198 
199 static union attrstr_t attr_storage_data[COAP_MAX_ATTRIBUTE_STRINGS];
200 static memarray_t attr_storage;
201 
202 static coap_attr_t resattr_storage_data[COAP_MAX_ATTRIBUTES];
203 static memarray_t resattr_storage;
204 
205 static coap_packet_t pkt_storage_data[COAP_MAX_PACKETS];
206 static memarray_t pkt_storage;
207 
208 static coap_queue_t node_storage_data[COAP_MAX_NODES];
209 static memarray_t node_storage;
210 
211 static coap_context_t context_storage_data[COAP_MAX_CONTEXTS];
212 static memarray_t context_storage;
213 
214 static coap_pdu_t pdu_storage_data[COAP_MAX_PDUS];
215 static memarray_t pdu_storage;
216 
217 /* The pdubuf is the storage for holding the (assembled) PDU data in a
218  * coap_pdu_t structure. */
219 union 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 
224 static union pdubuf_t pdubuf_storage_data[COAP_MAX_PDUS];
225 static memarray_t pdubuf_storage;
226 
227 static coap_resource_t resource_storage_data[COAP_MAX_RESOURCES];
228 static memarray_t resource_storage;
229 
230 #ifdef HAVE_LIBTINYDTLS
231 static session_t dtls_storage_data[COAP_MAX_DTLS_SESSIONS];
232 static memarray_t dtls_storage;
233 #endif /* HAVE_LIBTINYDTLS */
234 
235 static coap_session_t session_storage_data[COAP_MAX_SESSIONS];
236 static memarray_t session_storage;
237 
238 /* The optbuf_t is the storage for holding optlist nodes. */
239 struct optbuf_t {
240  coap_optlist_t optlist;
241  char optbuf[COAP_MAX_OPTION_SIZE];
242 };
243 static struct optbuf_t option_storage_data[COAP_MAX_OPTIONS];
244 static memarray_t option_storage;
245 
246 static coap_cache_key_t cache_key_storage_data[COAP_MAX_CACHE_KEYS];
247 static memarray_t cache_key_storage;
248 
249 static coap_cache_entry_t cache_entry_storage_data[COAP_MAX_CACHE_ENTRIES];
250 static 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 
257 void
258 coap_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 
278 static memarray_t *
279 get_container(coap_memory_tag_t type) {
280  switch(type) {
281  case COAP_ATTRIBUTE_NAME:
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 
306 void *
307 coap_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 
328 void
329 coap_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 
338 void
339 coap_memory_init(void) {
340 }
341 
342 void *
343 coap_malloc_type(coap_memory_tag_t type, size_t size) {
344  (void)type;
345  return malloc(size);
346 }
347 
348 void *
349 coap_realloc_type(coap_memory_tag_t type, void* p, size_t size) {
350  (void)type;
351  return realloc(p, size);
352 }
353 
354 void
355 coap_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 
380 struct 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 
390 typedef 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 
395 MEMB(string_storage, struct coap_stringbuf_t, COAP_MAX_STRINGS);
396 MEMB(packet_storage, coap_packetbuf_t, COAP_MAX_PACKETS);
397 MEMB(session_storage, coap_session_t, COAP_MAX_SESSIONS);
398 MEMB(node_storage, coap_queue_t, COAP_PDU_MAXCNT);
399 MEMB(pdu_storage, coap_pdu_t, COAP_PDU_MAXCNT);
400 MEMB(pdu_buf_storage, coap_packetbuf_t, COAP_PDU_MAXCNT);
401 MEMB(resource_storage, coap_resource_t, COAP_MAX_RESOURCES);
402 MEMB(attribute_storage, coap_attr_t, COAP_MAX_ATTRIBUTES);
403 MEMB(cache_key_storage, coap_cache_key_t, COAP_MAX_CACHE_KEYS);
404 MEMB(cache_entry_storage, coap_cache_entry_t, COAP_MAX_CACHE_ENTRIES);
405 MEMB(lg_xmit_storage, coap_lg_xmit_t, COAP_MAX_LG_XMIT);
406 MEMB(lg_crcv_storage, coap_lg_crcv_t, COAP_MAX_LG_CRCV);
407 MEMB(lg_srcv_storage, coap_lg_srcv_t, COAP_MAX_LG_SRCV);
408 
409 static struct memb *
410 get_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 
429 void
430 coap_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 
446 void *
447 coap_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 
469 void
470 coap_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_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_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_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