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