Coverage Report

Created: 2026-09-01 07:10

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(ESPIDF_VERSION)
550
551
#include "esp_heap_caps_init.h"
552
553
#if ((CONFIG_SPIRAM || CONFIG_SPIRAM_SUPPORT) && \
554
        (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC))
555
#define MEM_ALLOC_SPIRAM(size)         heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL)
556
#define MEM_REALLOC_SPIRAM(ptr, size)  heap_caps_realloc_prefer(ptr, size, 2, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL)
557
#define MEM_FREE_SPIRAM(ptr)           heap_caps_free(ptr)
558
#else
559
#define MEM_ALLOC_SPIRAM(size)         malloc(size)
560
#define MEM_REALLOC_SPIRAM(ptr, size)  realloc(ptr, size)
561
#define MEM_FREE_SPIRAM(ptr)           free(ptr)
562
#endif
563
564
void
565
coap_memory_init(void) {
566
}
567
568
void *
569
coap_malloc_type(coap_memory_tag_t type, size_t size) {
570
  void *ptr;
571
572
  (void)type;
573
  ptr = MEM_ALLOC_SPIRAM(size);
574
#if COAP_MEMORY_TYPE_TRACK
575
  assert(type < COAP_MEM_TAG_LAST);
576
  if (ptr) {
577
    track_counts[type]++;
578
    if (track_counts[type] > peak_counts[type])
579
      peak_counts[type] = track_counts[type];
580
  } else {
581
    fail_counts[type]++;
582
  }
583
#endif /* COAP_MEMORY_TYPE_TRACK */
584
  return ptr;
585
}
586
587
void *
588
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
589
  void *ptr;
590
591
  (void)type;
592
  ptr = MEM_REALLOC_SPIRAM(p, size);
593
#if COAP_MEMORY_TYPE_TRACK
594
  if (ptr) {
595
    assert(type < COAP_MEM_TAG_LAST);
596
    if (!p)
597
      track_counts[type]++;
598
    if (track_counts[type] > peak_counts[type])
599
      peak_counts[type] = track_counts[type];
600
  } else {
601
    fail_counts[type]++;
602
  }
603
#endif /* COAP_MEMORY_TYPE_TRACK */
604
  return ptr;
605
}
606
607
void
608
coap_free_type(coap_memory_tag_t type, void *p) {
609
  (void)type;
610
#if COAP_MEMORY_TYPE_TRACK
611
  assert(type < COAP_MEM_TAG_LAST);
612
  if (p)
613
    track_counts[type]--;
614
#endif /* COAP_MEMORY_TYPE_TRACK */
615
  MEM_FREE_SPIRAM(p);
616
}
617
618
#elif defined(HAVE_MALLOC) || defined(__MINGW32__)
619
620
#include <stdlib.h>
621
622
void
623
29
coap_memory_init(void) {
624
29
}
625
626
void *
627
116
coap_malloc_type(coap_memory_tag_t type, size_t size) {
628
116
  void *ptr;
629
630
116
  (void)type;
631
116
  ptr = malloc(size);
632
#if COAP_MEMORY_TYPE_TRACK
633
  assert(type < COAP_MEM_TAG_LAST);
634
  if (ptr) {
635
    track_counts[type]++;
636
    if (track_counts[type] > peak_counts[type])
637
      peak_counts[type] = track_counts[type];
638
  } else {
639
    fail_counts[type]++;
640
  }
641
#endif /* COAP_MEMORY_TYPE_TRACK */
642
116
  return ptr;
643
116
}
644
645
void *
646
0
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
647
0
  void *ptr;
648
649
0
  (void)type;
650
0
  ptr = realloc(p, size);
651
#if COAP_MEMORY_TYPE_TRACK
652
  if (ptr) {
653
    assert(type < COAP_MEM_TAG_LAST);
654
    if (!p)
655
      track_counts[type]++;
656
    if (track_counts[type] > peak_counts[type])
657
      peak_counts[type] = track_counts[type];
658
  } else {
659
    fail_counts[type]++;
660
  }
661
#endif /* COAP_MEMORY_TYPE_TRACK */
662
0
  return ptr;
663
0
}
664
665
void
666
435
coap_free_type(coap_memory_tag_t type, void *p) {
667
435
  (void)type;
668
#if COAP_MEMORY_TYPE_TRACK
669
  assert(type < COAP_MEM_TAG_LAST);
670
  if (p)
671
    track_counts[type]--;
672
#endif /* COAP_MEMORY_TYPE_TRACK */
673
435
  free(p);
674
435
}
675
676
/* End of HAVE_MALLOC || __MINGW32__ */
677
678
#elif WITH_CONTIKI
679
#include "lib/heapmem.h"
680
681
void
682
coap_memory_init(void) {
683
}
684
685
void *
686
coap_malloc_type(coap_memory_tag_t type, size_t size) {
687
  void *ptr = heapmem_alloc(size);
688
689
#if COAP_MEMORY_TYPE_TRACK
690
  assert(type < COAP_MEM_TAG_LAST);
691
  if (ptr) {
692
    track_counts[type]++;
693
    if (track_counts[type] > peak_counts[type])
694
      peak_counts[type] = track_counts[type];
695
  } else {
696
    fail_counts[type]++;
697
  }
698
#endif /* COAP_MEMORY_TYPE_TRACK */
699
  return ptr;
700
}
701
702
void *
703
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
704
  void *ptr = heapmem_realloc(p, size);
705
#if COAP_MEMORY_TYPE_TRACK
706
  if (ptr) {
707
    assert(type < COAP_MEM_TAG_LAST);
708
    if (!p)
709
      track_counts[type]++;
710
    if (track_counts[type] > peak_counts[type])
711
      peak_counts[type] = track_counts[type];
712
  } else {
713
    fail_counts[type]++;
714
  }
715
#endif /* COAP_MEMORY_TYPE_TRACK */
716
  return ptr;
717
}
718
719
void
720
coap_free_type(coap_memory_tag_t type, void *ptr) {
721
#if COAP_MEMORY_TYPE_TRACK
722
  assert(type < COAP_MEM_TAG_LAST);
723
  if (ptr)
724
    track_counts[type]--;
725
#endif /* COAP_MEMORY_TYPE_TRACK */
726
  if (ptr)
727
    heapmem_free(ptr);
728
}
729
730
#endif /* WITH_CONTIKI */
731
732
#if ! (defined(WITH_LWIP) && ! MEM_LIBC_MALLOC)
733
#define MAKE_CASE(n) case n: name = #n; break
734
void
735
29
coap_dump_memory_type_counts(coap_log_t level) {
736
#if COAP_MEMORY_TYPE_TRACK
737
  int i;
738
739
  coap_log(level, "*  Memory type counts\n");
740
  for (i = 0; i < COAP_MEM_TAG_LAST; i++) {
741
    const char *name = "?";
742
743
744
    switch (i) {
745
      MAKE_CASE(COAP_STRING);
746
      MAKE_CASE(COAP_ATTRIBUTE_NAME);
747
      MAKE_CASE(COAP_ATTRIBUTE_VALUE);
748
      MAKE_CASE(COAP_PACKET);
749
      MAKE_CASE(COAP_NODE);
750
      MAKE_CASE(COAP_CONTEXT);
751
      MAKE_CASE(COAP_ENDPOINT);
752
      MAKE_CASE(COAP_PDU);
753
      MAKE_CASE(COAP_PDU_BUF);
754
      MAKE_CASE(COAP_RESOURCE);
755
      MAKE_CASE(COAP_RESOURCEATTR);
756
      MAKE_CASE(COAP_DTLS_SESSION);
757
      MAKE_CASE(COAP_SESSION);
758
      MAKE_CASE(COAP_OPTLIST);
759
      MAKE_CASE(COAP_CACHE_KEY);
760
      MAKE_CASE(COAP_CACHE_ENTRY);
761
      MAKE_CASE(COAP_LG_XMIT);
762
      MAKE_CASE(COAP_LG_CRCV);
763
      MAKE_CASE(COAP_LG_SRCV);
764
      MAKE_CASE(COAP_DIGEST_CTX);
765
      MAKE_CASE(COAP_SUBSCRIPTION);
766
      MAKE_CASE(COAP_DTLS_CONTEXT);
767
      MAKE_CASE(COAP_OSCORE_COM);
768
      MAKE_CASE(COAP_OSCORE_SEN);
769
      MAKE_CASE(COAP_OSCORE_REC);
770
      MAKE_CASE(COAP_OSCORE_EX);
771
      MAKE_CASE(COAP_OSCORE_EP);
772
      MAKE_CASE(COAP_OSCORE_BUF);
773
      MAKE_CASE(COAP_COSE);
774
    case COAP_MEM_TAG_LAST:
775
    default:
776
      break;
777
    }
778
    coap_log(level, "*    %-20s in-use %3d peak %3d failed %2d\n",
779
             name, track_counts[i], peak_counts[i], fail_counts[i]);
780
  }
781
#else /* COAP_MEMORY_TYPE_TRACK */
782
29
  (void)level;
783
29
#endif /* COAP_MEMORY_TYPE_TRACK */
784
29
}
785
#endif /* ! (WITH_LWIP && ! MEM_LIBC_MALLOC) */