libcoap  4.3.0beta
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 "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 #ifdef __GNUC__
337 #define UNUSED_PARAM __attribute__((unused))
338 #else
339 #define UNUSED_PARAM
340 #endif /* __GNUC__ */
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 
406 static struct memb *
407 get_container(coap_memory_tag_t type) {
408  switch(type) {
409  case COAP_PACKET: return &packet_storage;
410  case COAP_NODE: return &node_storage;
411  case COAP_SESSION: return &session_storage;
412  case COAP_PDU: return &pdu_storage;
413  case COAP_PDU_BUF: return &pdu_buf_storage;
414  case COAP_RESOURCE: return &resource_storage;
415  case COAP_RESOURCEATTR: return &attribute_storage;
416  case COAP_CACHE_KEY: return &cache_key_storage;
417  case COAP_CACHE_ENTRY: return &cache_entry_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 }
436 
437 void *
438 coap_malloc_type(coap_memory_tag_t type, size_t size) {
439  struct memb *container = get_container(type);
440  void *ptr;
441 
442  assert(container);
443 
444  if (size > container->size) {
446  "coap_malloc_type: Requested memory exceeds maximum object "
447  "size (type %d, size %d, max %d)\n",
448  type, (int)size, container->size);
449  return NULL;
450  }
451 
452  ptr = memb_alloc(container);
453  if (!ptr)
455  "coap_malloc_type: Failure (no free blocks) for type %d\n",
456  type);
457  return ptr;
458 }
459 
460 void
461 coap_free_type(coap_memory_tag_t type, void *object) {
462  memb_free(get_container(type), object);
463 }
464 #endif /* WITH_CONTIKI */
465 
466 #endif /* ! HAVE_MALLOC */
467 
468 #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_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_ATTRIBUTE_NAME
Definition: mem.h:31
@ 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:53
Generic resource handling.
The CoAP stack's global state is stored in a coap_context_t object.
Definition: net.h:141
Abstraction of virtual endpoint that can be attached to coap_context_t.
Representation of chained list of CoAP options to install.
Definition: option.h:343
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:36
CoAP string data definition.
Definition: str.h:30