Coverage Report

Created: 2026-05-30 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcoap/src/coap_mem.c
Line
Count
Source
1
/* coap_mem.c -- CoAP memory handling
2
 *
3
 * Copyright (C) 2014--2015,2019--2026 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
 * @file coap_mem.c
13
 * @brief Memory handling functions
14
 */
15
16
#include "coap3/coap_libcoap_build.h"
17
18
#if ! (defined(WITH_LWIP) && ! MEM_LIBC_MALLOC)
19
#if COAP_MEMORY_TYPE_TRACK
20
static int track_counts[COAP_MEM_TAG_LAST];
21
static int peak_counts[COAP_MEM_TAG_LAST];
22
static int fail_counts[COAP_MEM_TAG_LAST];
23
#endif /* COAP_MEMORY_TYPE_TRACK */
24
#endif /* ! (WITH_LWIP && ! MEM_LIBC_MALLOC) */
25
26
#if defined(RIOT_VERSION) && defined(MODULE_MEMARRAY)
27
#include <memarray.h>
28
29
#undef PACKAGE_NAME
30
#undef PACKAGE_STRING
31
#undef PACKAGE_TARNAME
32
#undef PACKAGE_VERSION
33
#include <coap3/coap_session.h>
34
#undef PACKAGE_NAME
35
#undef PACKAGE_STRING
36
#undef PACKAGE_TARNAME
37
#undef PACKAGE_VERSION
38
39
#include "coap3/coap_session.h"
40
#include "coap3/coap_net.h"
41
#include "coap3/coap_pdu.h"
42
#include "coap3/coap_resource.h"
43
44
/**
45
 * The maximum size of a string on platforms that allocate fixed-size
46
 * memory blocks.
47
 */
48
#ifndef COAP_MAX_STRING_SIZE
49
#define COAP_MAX_STRING_SIZE     (120U)
50
#endif /* COAP_MAX_STRING_SIZE */
51
52
/**
53
 * The maximum number of strings on platforms that allocate
54
 * fixed-size memory blocks.
55
 */
56
#ifndef COAP_MAX_STRINGS
57
#define COAP_MAX_STRINGS         (16U)
58
#endif /* COAP_MAX_STRINGS */
59
60
/**
61
 * The maximum number of endpoints on platforms that allocate
62
 * fixed-size memory blocks.
63
 */
64
#ifndef COAP_MAX_ENDPOINTS
65
#if !COAP_DISABLE_TCP
66
#define COAP_MAX_ENDPOINTS          (4U)
67
#else /* COAP_DISABLE_TCP */
68
#define COAP_MAX_ENDPOINTS          (2U)
69
#endif /* COAP_DISABLE_TCP */
70
#endif /* COAP_MAX_ENDPOINTS */
71
72
/**
73
 * The maximum number of resources on platforms that allocate
74
 * fixed-size memory blocks.
75
 */
76
#ifndef COAP_MAX_RESOURCES
77
#define COAP_MAX_RESOURCES          (8U)
78
#endif /* COAP_MAX_RESOURCES */
79
80
/**
81
 * The maximum number of attributes on platforms that allocate
82
 * fixed-size memory blocks.  Default is #COAP_MAX_RESOURCES * 4.
83
 */
84
#ifndef COAP_MAX_ATTRIBUTES
85
#define COAP_MAX_ATTRIBUTES             \
86
  ((COAP_MAX_RESOURCES) * 4U)
87
#endif /* COAP_MAX_ATTRIBUTE_STRINGS */
88
89
/**
90
 * The maximum number of a strings that are used for attribute names
91
 * and values on platforms that allocate fixed-size memory blocks.
92
 * Default is #COAP_MAX_ATTRIBUTES, i.e. every attribute can have a
93
 * dynamic value.
94
 */
95
#ifndef COAP_MAX_ATTRIBUTE_STRINGS
96
#define COAP_MAX_ATTRIBUTE_STRINGS    (COAP_MAX_ATTRIBUTES)
97
#endif /* COAP_MAX_ATTRIBUTE_STRINGS */
98
99
/**
100
 * The maximum size of attribute names or values and values on
101
 * platforms that allocate fixed-size memory blocks.
102
 */
103
#ifndef COAP_MAX_ATTRIBUTE_SIZE
104
#define COAP_MAX_ATTRIBUTE_SIZE       (16U)
105
#endif /* COAP_MAX_ATTRIBUTE_SIZE */
106
107
/**
108
 * The maximum number of processed packets on platforms that allocate
109
 * fixed-size memory blocks.
110
 */
111
#ifndef COAP_MAX_PACKETS
112
#define COAP_MAX_PACKETS            (4U)
113
#endif /* COAP_MAX_PACKETS */
114
115
/**
116
 * The maximum number of nodes in retransmission queue on platforms
117
 * that allocate fixed-size memory blocks.
118
 */
119
#ifndef COAP_MAX_NODES
120
#define COAP_MAX_NODES           (COAP_MAX_PACKETS)
121
#endif /* COAP_MAX_NODES */
122
123
/**
124
 * The maximum number of CoAP contexts on platforms that allocate
125
 * fixed-size memory blocks. Default is 1.
126
 */
127
#ifndef COAP_MAX_CONTEXTS
128
#define COAP_MAX_CONTEXTS           (1U)
129
#endif /* COAP_MAX_CONTEXTS */
130
131
/**
132
 * The maximum number of CoAP PDUs processed in parallel on platforms
133
 * that allocate fixed-size memory blocks.
134
 */
135
#ifndef COAP_MAX_PDUS
136
#define COAP_MAX_PDUS               (4U)
137
#endif /* COAP_MAX_PDUS */
138
139
/**
140
 * The maximum number of DTLS sessions on platforms that allocate
141
 * fixed-size memory blocks.
142
 */
143
#ifndef COAP_MAX_DTLS_SESSIONS
144
#define COAP_MAX_DTLS_SESSIONS      (2U)
145
#endif /* COAP_MAX_CONTEXTS */
146
147
/**
148
 * The maximum number of DTLS sessions on platforms that allocate
149
 * fixed-size memory blocks.
150
 */
151
#ifndef COAP_MAX_SESSIONS
152
#define COAP_MAX_SESSIONS           (4U)
153
#endif /* COAP_MAX_CONTEXTS */
154
155
/**
156
 * The maximum number of optlist entries on platforms that allocate
157
 * fixed-size memory blocks.
158
 */
159
#ifndef COAP_MAX_OPTIONS
160
#define COAP_MAX_OPTIONS            (16U)
161
#endif /* COAP_MAX_CONTEXTS */
162
163
/**
164
 * The maximum size of option values on platforms that allocate
165
 * fixed-size memory blocks.
166
 */
167
#ifndef COAP_MAX_OPTION_SIZE
168
#define COAP_MAX_OPTION_SIZE        (16U)
169
#endif /* COAP_MAX_OPTION_SIZE */
170
171
/**
172
 * The maximum number of cache-key entries that allocate
173
 * fixed-size memory blocks.
174
 */
175
#ifndef COAP_MAX_CACHE_KEYS
176
#define COAP_MAX_CACHE_KEYS        (2U)
177
#endif /* COAP_MAX_CACHE_KEYS */
178
179
/**
180
 * The maximum number of cache-entry entries that allocate
181
 * fixed-size memory blocks.
182
 */
183
#ifndef COAP_MAX_CACHE_ENTRIES
184
#define COAP_MAX_CACHE_ENTRIES        (2U)
185
#endif /* COAP_MAX_CACHE_ENTRIES */
186
187
/**
188
 * The maximum number lg_crcv entries that allocate
189
 * fixed-size memory blocks.
190
 */
191
#ifndef COAP_MAX_LG_CRCVS
192
#if COAP_CLIENT_SUPPORT
193
#define COAP_MAX_LG_CRCVS        (1U)
194
#else /* ! COAP_CLIENT_SUPPORT */
195
#define COAP_MAX_LG_CRCVS        (0U)
196
#endif /* ! COAP_CLIENT_SUPPORT */
197
#endif /* COAP_MAX_LG_CRCVS */
198
199
/**
200
 * The maximum number lg_srcv entries that allocate
201
 * fixed-size memory blocks.
202
 */
203
#ifndef COAP_MAX_LG_SRCVS
204
#if COAP_SERVER_SUPPORT
205
#define COAP_MAX_LG_SRCVS        (2U)
206
#else /* ! COAP_SERVER_SUPPORT */
207
#define COAP_MAX_LG_SRCVS        (0U)
208
#endif /* ! COAP_SERVER_SUPPORT */
209
#endif /* COAP_MAX_LG_SRCVS */
210
211
/**
212
 * The maximum number lg_xmit entries that allocate
213
 * fixed-size memory blocks.
214
 */
215
#ifndef COAP_MAX_LG_XMITS
216
#if COAP_SERVER_SUPPORT
217
#define COAP_MAX_LG_XMITS        (2U)
218
#else /* ! COAP_SERVER_SUPPORT */
219
#define COAP_MAX_LG_XMITS        (1U)
220
#endif /* ! COAP_SERVER_SUPPORT */
221
#endif /* COAP_MAX_LG_XMITS */
222
223
/* The memstr is the storage for holding coap_string_t contents. */
224
struct memstr_t {
225
  char buf[COAP_MAX_STRING_SIZE];
226
};
227
228
/* The attrstr is the storage for holding coap_string_t structures to
229
 * serve as attribute names or values. As these are typically short,
230
 * they are stored in a different arena than generic strings. */
231
struct attrstr_t {
232
  char buf[COAP_MAX_ATTRIBUTE_SIZE];
233
};
234
235
static struct memstr_t string_storage_data[COAP_MAX_STRINGS];
236
static memarray_t string_storage;
237
238
#if COAP_SERVER_SUPPORT
239
static coap_endpoint_t endpoint_storage_data[COAP_MAX_ENDPOINTS];
240
static memarray_t endpoint_storage;
241
242
static struct attrstr_t attr_storage_data[COAP_MAX_ATTRIBUTE_STRINGS];
243
static memarray_t attr_storage;
244
245
static coap_attr_t resattr_storage_data[COAP_MAX_ATTRIBUTES];
246
static memarray_t resattr_storage;
247
#endif /* COAP_SERVER_SUPPORT */
248
249
static coap_packet_t pkt_storage_data[COAP_MAX_PACKETS];
250
static memarray_t pkt_storage;
251
252
static coap_queue_t node_storage_data[COAP_MAX_NODES];
253
static memarray_t node_storage;
254
255
static coap_context_t context_storage_data[COAP_MAX_CONTEXTS];
256
static memarray_t context_storage;
257
258
static coap_pdu_t pdu_storage_data[COAP_MAX_PDUS];
259
static memarray_t pdu_storage;
260
261
/* The pdubuf is the storage for holding the (assembled) PDU data in a
262
 * coap_pdu_t structure. */
263
union pdubuf_t {
264
  void *p; /* try to convince the compiler to word-align this structure  */
265
  char buf[COAP_DEFAULT_MAX_PDU_RX_SIZE];
266
};
267
268
static union pdubuf_t pdubuf_storage_data[COAP_MAX_PDUS];
269
static memarray_t pdubuf_storage;
270
271
#if COAP_SERVER_SUPPORT
272
static coap_resource_t resource_storage_data[COAP_MAX_RESOURCES];
273
static memarray_t resource_storage;
274
#endif /* COAP_SERVER_SUPPORT */
275
276
#if COAP_WITH_LIBTINYDTLS
277
#undef PACKAGE_BUGREPORT
278
#undef PACKAGE_URL
279
#include <session.h>
280
static session_t dtls_storage_data[COAP_MAX_DTLS_SESSIONS];
281
static memarray_t dtls_storage;
282
#endif /* COAP_WITH_LIBTINYDTLS */
283
284
static coap_session_t session_storage_data[COAP_MAX_SESSIONS];
285
static memarray_t session_storage;
286
287
/* The optbuf_t is the storage for holding optlist nodes. */
288
struct optbuf_t {
289
  coap_optlist_t optlist;
290
  char optbuf[COAP_MAX_OPTION_SIZE];
291
};
292
static struct optbuf_t option_storage_data[COAP_MAX_OPTIONS];
293
static memarray_t option_storage;
294
295
#if COAP_SERVER_SUPPORT
296
static coap_cache_key_t cache_key_storage_data[COAP_MAX_CACHE_KEYS];
297
static memarray_t cache_key_storage;
298
299
static coap_cache_entry_t cache_entry_storage_data[COAP_MAX_CACHE_ENTRIES];
300
static memarray_t cache_entry_storage;
301
#endif /* COAP_SERVER_SUPPORT */
302
303
#if COAP_CLIENT_SUPPORT
304
static coap_lg_crcv_t cache_lg_crcv_storage_data[COAP_MAX_LG_CRCVS];
305
static memarray_t cache_lg_crcv_storage;
306
#endif /* COAP_CLIENT_SUPPORT */
307
308
#if COAP_SERVER_SUPPORT
309
static coap_lg_srcv_t cache_lg_srcv_storage_data[COAP_MAX_LG_SRCVS];
310
static memarray_t cache_lg_srcv_storage;
311
312
static coap_lg_xmit_t cache_lg_xmit_storage_data[COAP_MAX_LG_XMITS];
313
static memarray_t cache_lg_xmit_storage;
314
#endif /* COAP_SERVER_SUPPORT */
315
316
#define INIT_STORAGE(Storage, Count)  \
317
  memarray_init(&(Storage ## _storage), (Storage ## _storage_data), sizeof(Storage ## _storage_data[0]), (Count));
318
319
#define STORAGE_PTR(Storage)  (&(Storage ## _storage))
320
321
void
322
coap_memory_init(void) {
323
  INIT_STORAGE(string, COAP_MAX_STRINGS);
324
#if COAP_SERVER_SUPPORT
325
  INIT_STORAGE(endpoint, COAP_MAX_ENDPOINTS);
326
  INIT_STORAGE(attr, COAP_MAX_ATTRIBUTE_STRINGS);
327
#endif /* COAP_SERVER_SUPPORT */
328
  INIT_STORAGE(pkt, COAP_MAX_PACKETS);
329
  INIT_STORAGE(node, COAP_MAX_NODES);
330
  INIT_STORAGE(context, COAP_MAX_CONTEXTS);
331
  INIT_STORAGE(pdu, COAP_MAX_PDUS);
332
  INIT_STORAGE(pdubuf, COAP_MAX_PDUS);
333
#if COAP_SERVER_SUPPORT
334
  INIT_STORAGE(resource, COAP_MAX_RESOURCES);
335
  INIT_STORAGE(resattr, COAP_MAX_ATTRIBUTES);
336
#endif /* COAP_SERVER_SUPPORT */
337
#if COAP_WITH_LIBTINYDTLS
338
  INIT_STORAGE(dtls, COAP_MAX_DTLS_SESSIONS);
339
#endif
340
  INIT_STORAGE(session, COAP_MAX_SESSIONS);
341
  INIT_STORAGE(option, COAP_MAX_OPTIONS);
342
#if COAP_SERVER_SUPPORT
343
  INIT_STORAGE(cache_key, COAP_MAX_CACHE_KEYS);
344
  INIT_STORAGE(cache_entry, COAP_MAX_CACHE_ENTRIES);
345
#endif /* COAP_SERVER_SUPPORT */
346
#if COAP_CLIENT_SUPPORT
347
  INIT_STORAGE(cache_lg_crcv, COAP_MAX_LG_CRCVS);
348
#endif /* COAP_SERVER_SUPPORT */
349
#if COAP_SERVER_SUPPORT
350
  INIT_STORAGE(cache_lg_srcv, COAP_MAX_LG_SRCVS);
351
  INIT_STORAGE(cache_lg_xmit, COAP_MAX_LG_XMITS);
352
#endif /* COAP_SERVER_SUPPORT */
353
}
354
355
static memarray_t *
356
get_container(coap_memory_tag_t type) {
357
  switch (type) {
358
#if COAP_SERVER_SUPPORT
359
  case COAP_ATTRIBUTE_NAME:
360
  /* fall through */
361
  case COAP_ATTRIBUTE_VALUE:
362
    return &attr_storage;
363
#endif /* COAP_SERVER_SUPPORT */
364
  case COAP_PACKET:
365
    return &pkt_storage;
366
  case COAP_NODE:
367
    return &node_storage;
368
  case COAP_CONTEXT:
369
    return STORAGE_PTR(context);
370
#if COAP_SERVER_SUPPORT
371
  case COAP_ENDPOINT:
372
    return &endpoint_storage;
373
#endif /* COAP_SERVER_SUPPORT */
374
  case COAP_PDU:
375
    return &pdu_storage;
376
  case COAP_PDU_BUF:
377
    return &pdubuf_storage;
378
#if COAP_SERVER_SUPPORT
379
  case COAP_RESOURCE:
380
    return &resource_storage;
381
  case COAP_RESOURCEATTR:
382
    return &resattr_storage;
383
#endif /* COAP_SERVER_SUPPORT */
384
#if COAP_WITH_LIBTINYDTLS
385
  case COAP_DTLS_SESSION:
386
    return &dtls_storage;
387
#endif
388
  case COAP_SESSION:
389
    return &session_storage;
390
  case COAP_OPTLIST:
391
    return &option_storage;
392
#if COAP_SERVER_SUPPORT
393
  case COAP_CACHE_KEY:
394
    return &cache_key_storage;
395
  case COAP_CACHE_ENTRY:
396
    return &cache_entry_storage;
397
#endif /* COAP_SERVER_SUPPORT */
398
#if COAP_CLIENT_SUPPORT
399
  case COAP_LG_CRCV:
400
    return &cache_lg_crcv_storage;
401
#endif /* COAP_CLIENT_SUPPORT */
402
#if COAP_SERVER_SUPPORT
403
  case COAP_LG_SRCV:
404
    return &cache_lg_srcv_storage;
405
  case COAP_LG_XMIT:
406
    return &cache_lg_xmit_storage;
407
#endif /* COAP_SERVER_SUPPORT */
408
  case COAP_STRING:
409
  /* fall through */
410
  default:
411
    return &string_storage;
412
  }
413
}
414
415
void *
416
coap_malloc_type(coap_memory_tag_t type, size_t size) {
417
  memarray_t *container = get_container(type);
418
  void *ptr;
419
  assert(container);
420
421
  if (size > container->size) {
422
    coap_log_warn("coap_malloc_type: Requested memory exceeds maximum object "
423
                  "size (type %d, size %" PRIuS ", max %" PRIdS ")\n",
424
                  type, size, container->size);
425
    return NULL;
426
  }
427
428
  ptr = memarray_alloc(container);
429
  if (!ptr)
430
    coap_log_warn("coap_malloc_type: Failure (no free blocks) for type %d\n",
431
                  type);
432
#if COAP_MEMORY_TYPE_TRACK
433
  assert(type < COAP_MEM_TAG_LAST);
434
  if (ptr) {
435
    track_counts[type]++;
436
    if (track_counts[type] > peak_counts[type])
437
      peak_counts[type] = track_counts[type];
438
  } else {
439
    fail_counts[type]++;
440
  }
441
#endif /* COAP_MEMORY_TYPE_TRACK */
442
  return ptr;
443
}
444
445
void
446
coap_free_type(coap_memory_tag_t type, void *object) {
447
#if COAP_MEMORY_TYPE_TRACK
448
  assert(type < COAP_MEM_TAG_LAST);
449
  if (object)
450
    track_counts[type]--;
451
#endif /* COAP_MEMORY_TYPE_TRACK */
452
  if (object != NULL)
453
    memarray_free(get_container(type), object);
454
}
455
456
void *
457
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
458
  memarray_t *container = get_container(type);
459
460
  assert(container);
461
  /* The fixed container is all we have to work with */
462
  if (p) {
463
    if (size > container->size) {
464
      coap_log_warn("coap_realloc_type: Requested memory exceeds maximum object "
465
                    "size (type %d, size %" PRIuS ", max %" PRIdS ")\n",
466
                    type, size, container->size);
467
      return NULL;
468
    }
469
    if (size == 0) {
470
      coap_free_type(type, p);
471
      return NULL;
472
    }
473
    return p;
474
  }
475
  return coap_malloc_type(type, size);
476
477
}
478
/* End RIOT_VERSION */
479
480
#elif defined(__ZEPHYR__)
481
482
#include <zephyr/kernel.h>
483
#include <zephyr/version.h>
484
485
void
486
coap_memory_init(void) {
487
}
488
489
void *
490
coap_malloc_type(coap_memory_tag_t type, size_t size) {
491
  void *ptr;
492
493
  (void)type;
494
  ptr = k_malloc(size);
495
#if COAP_MEMORY_TYPE_TRACK
496
  assert(type < COAP_MEM_TAG_LAST);
497
  if (ptr) {
498
    track_counts[type]++;
499
    if (track_counts[type] > peak_counts[type])
500
      peak_counts[type] = track_counts[type];
501
  } else {
502
    fail_counts[type]++;
503
  }
504
#endif /* COAP_MEMORY_TYPE_TRACK */
505
  return ptr;
506
}
507
508
void *
509
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
510
  void *ptr;
511
512
  (void)type;
513
#if KERNEL_VERSION_NUMBER >= 0x30700
514
  ptr = k_realloc(p, size);
515
#else /* KERNEL_VERSION_NUMBER < 0x30700 */
516
  if (!p) {
517
    ptr = k_malloc(size);
518
  } else {
519
    /* Unfortunately do not know original size of p to take a copy of it */
520
    ptr = NULL;
521
  }
522
#endif /* KERNEL_VERSION_NUMBER < 0x30700 */
523
#if COAP_MEMORY_TYPE_TRACK
524
  if (ptr) {
525
    assert(type < COAP_MEM_TAG_LAST);
526
    if (!p)
527
      track_counts[type]++;
528
    if (track_counts[type] > peak_counts[type])
529
      peak_counts[type] = track_counts[type];
530
  } else {
531
    fail_counts[type]++;
532
  }
533
#endif /* COAP_MEMORY_TYPE_TRACK */
534
  return ptr;
535
}
536
537
void
538
coap_free_type(coap_memory_tag_t type, void *p) {
539
  (void)type;
540
#if COAP_MEMORY_TYPE_TRACK
541
  assert(type < COAP_MEM_TAG_LAST);
542
  if (p)
543
    track_counts[type]--;
544
#endif /* COAP_MEMORY_TYPE_TRACK */
545
  k_free(p);
546
}
547
/* End __ZEPHYR__ */
548
549
#elif defined(HAVE_MALLOC) || defined(__MINGW32__)
550
551
#include <stdlib.h>
552
553
void
554
0
coap_memory_init(void) {
555
0
}
556
557
void *
558
0
coap_malloc_type(coap_memory_tag_t type, size_t size) {
559
0
  void *ptr;
560
561
0
  (void)type;
562
0
  ptr = malloc(size);
563
#if COAP_MEMORY_TYPE_TRACK
564
  assert(type < COAP_MEM_TAG_LAST);
565
  if (ptr) {
566
    track_counts[type]++;
567
    if (track_counts[type] > peak_counts[type])
568
      peak_counts[type] = track_counts[type];
569
  } else {
570
    fail_counts[type]++;
571
  }
572
#endif /* COAP_MEMORY_TYPE_TRACK */
573
0
  return ptr;
574
0
}
575
576
void *
577
0
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
578
0
  void *ptr;
579
580
0
  (void)type;
581
0
  ptr = realloc(p, size);
582
#if COAP_MEMORY_TYPE_TRACK
583
  if (ptr) {
584
    assert(type < COAP_MEM_TAG_LAST);
585
    if (!p)
586
      track_counts[type]++;
587
    if (track_counts[type] > peak_counts[type])
588
      peak_counts[type] = track_counts[type];
589
  } else {
590
    fail_counts[type]++;
591
  }
592
#endif /* COAP_MEMORY_TYPE_TRACK */
593
0
  return ptr;
594
0
}
595
596
void
597
0
coap_free_type(coap_memory_tag_t type, void *p) {
598
0
  (void)type;
599
#if COAP_MEMORY_TYPE_TRACK
600
  assert(type < COAP_MEM_TAG_LAST);
601
  if (p)
602
    track_counts[type]--;
603
#endif /* COAP_MEMORY_TYPE_TRACK */
604
0
  free(p);
605
0
}
606
607
/* End of HAVE_MALLOC || __MINGW32__ */
608
609
#elif WITH_CONTIKI
610
#include "lib/heapmem.h"
611
612
void
613
coap_memory_init(void) {
614
}
615
616
void *
617
coap_malloc_type(coap_memory_tag_t type, size_t size) {
618
  void *ptr = heapmem_alloc(size);
619
620
#if COAP_MEMORY_TYPE_TRACK
621
  assert(type < COAP_MEM_TAG_LAST);
622
  if (ptr) {
623
    track_counts[type]++;
624
    if (track_counts[type] > peak_counts[type])
625
      peak_counts[type] = track_counts[type];
626
  } else {
627
    fail_counts[type]++;
628
  }
629
#endif /* COAP_MEMORY_TYPE_TRACK */
630
  return ptr;
631
}
632
633
void *
634
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
635
  void *ptr = heapmem_realloc(p, size);
636
#if COAP_MEMORY_TYPE_TRACK
637
  if (ptr) {
638
    assert(type < COAP_MEM_TAG_LAST);
639
    if (!p)
640
      track_counts[type]++;
641
    if (track_counts[type] > peak_counts[type])
642
      peak_counts[type] = track_counts[type];
643
  } else {
644
    fail_counts[type]++;
645
  }
646
#endif /* COAP_MEMORY_TYPE_TRACK */
647
  return ptr;
648
}
649
650
void
651
coap_free_type(coap_memory_tag_t type, void *ptr) {
652
#if COAP_MEMORY_TYPE_TRACK
653
  assert(type < COAP_MEM_TAG_LAST);
654
  if (ptr)
655
    track_counts[type]--;
656
#endif /* COAP_MEMORY_TYPE_TRACK */
657
  if (ptr)
658
    heapmem_free(ptr);
659
}
660
661
#endif /* WITH_CONTIKI */
662
663
#if ! (defined(WITH_LWIP) && ! MEM_LIBC_MALLOC)
664
#define MAKE_CASE(n) case n: name = #n; break
665
void
666
0
coap_dump_memory_type_counts(coap_log_t level) {
667
#if COAP_MEMORY_TYPE_TRACK
668
  int i;
669
670
  coap_log(level, "*  Memory type counts\n");
671
  for (i = 0; i < COAP_MEM_TAG_LAST; i++) {
672
    const char *name = "?";
673
674
675
    switch (i) {
676
      MAKE_CASE(COAP_STRING);
677
      MAKE_CASE(COAP_ATTRIBUTE_NAME);
678
      MAKE_CASE(COAP_ATTRIBUTE_VALUE);
679
      MAKE_CASE(COAP_PACKET);
680
      MAKE_CASE(COAP_NODE);
681
      MAKE_CASE(COAP_CONTEXT);
682
      MAKE_CASE(COAP_ENDPOINT);
683
      MAKE_CASE(COAP_PDU);
684
      MAKE_CASE(COAP_PDU_BUF);
685
      MAKE_CASE(COAP_RESOURCE);
686
      MAKE_CASE(COAP_RESOURCEATTR);
687
      MAKE_CASE(COAP_DTLS_SESSION);
688
      MAKE_CASE(COAP_SESSION);
689
      MAKE_CASE(COAP_OPTLIST);
690
      MAKE_CASE(COAP_CACHE_KEY);
691
      MAKE_CASE(COAP_CACHE_ENTRY);
692
      MAKE_CASE(COAP_LG_XMIT);
693
      MAKE_CASE(COAP_LG_CRCV);
694
      MAKE_CASE(COAP_LG_SRCV);
695
      MAKE_CASE(COAP_DIGEST_CTX);
696
      MAKE_CASE(COAP_SUBSCRIPTION);
697
      MAKE_CASE(COAP_DTLS_CONTEXT);
698
      MAKE_CASE(COAP_OSCORE_COM);
699
      MAKE_CASE(COAP_OSCORE_SEN);
700
      MAKE_CASE(COAP_OSCORE_REC);
701
      MAKE_CASE(COAP_OSCORE_EX);
702
      MAKE_CASE(COAP_OSCORE_EP);
703
      MAKE_CASE(COAP_OSCORE_BUF);
704
      MAKE_CASE(COAP_COSE);
705
    case COAP_MEM_TAG_LAST:
706
    default:
707
      break;
708
    }
709
    coap_log(level, "*    %-20s in-use %3d peak %3d failed %2d\n",
710
             name, track_counts[i], peak_counts[i], fail_counts[i]);
711
  }
712
#else /* COAP_MEMORY_TYPE_TRACK */
713
0
  (void)level;
714
0
#endif /* COAP_MEMORY_TYPE_TRACK */
715
0
}
716
#endif /* ! (WITH_LWIP && ! MEM_LIBC_MALLOC) */