xref: /btstack/src/btstack_memory.c (revision f399f7fbd7500ce38dbdebe25ff374624fc71cef)
1 /*
2  * Copyright (C) 2014 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 
39 #define BTSTACK_FILE__ "btstack_memory.c"
40 
41 
42 /*
43  *  btstack_memory.c
44  *
45  *  @brief BTstack memory management via configurable memory pools
46  *
47  *  @note code generated by tool/btstack_memory_generator.py
48  *  @note returnes buffers are initialized with 0
49  *
50  */
51 
52 #include "btstack_memory.h"
53 #include "btstack_memory_pool.h"
54 #include "btstack_debug.h"
55 
56 #include <stdlib.h>
57 
58 #ifdef HAVE_MALLOC
59 typedef struct btstack_memory_buffer {
60     struct btstack_memory_buffer * next;
61     struct btstack_memory_buffer * prev;
62 } btstack_memory_buffer_t;
63 
64 typedef struct {
65     btstack_memory_buffer_t tracking;
66     void * pointer;
67 } test_buffer_t;
68 
69 static btstack_memory_buffer_t * btstack_memory_malloc_buffers;
70 static uint32_t btstack_memory_malloc_counter;
71 
72 static void btstack_memory_tracking_add(btstack_memory_buffer_t * buffer){
73     btstack_assert(buffer != NULL);
74     if (btstack_memory_malloc_buffers != NULL) {
75         // let current first item prev point to new first item
76         btstack_memory_malloc_buffers->prev = buffer;
77     }
78     buffer->prev = NULL;
79     buffer->next = btstack_memory_malloc_buffers;
80     btstack_memory_malloc_buffers = buffer;
81 
82     btstack_memory_malloc_counter++;
83 }
84 
85 static void btstack_memory_tracking_remove(btstack_memory_buffer_t * buffer){
86     btstack_assert(buffer != NULL);
87     if (buffer->prev == NULL){
88         // first item
89         btstack_memory_malloc_buffers = buffer->next;
90     } else {
91         buffer->prev->next = buffer->next;
92     }
93     if (buffer->next != NULL){
94         buffer->next->prev = buffer->prev;
95     }
96 
97     btstack_memory_malloc_counter--;
98 }
99 #endif
100 
101 void btstack_memory_deinit(void){
102 #ifdef HAVE_MALLOC
103     while (btstack_memory_malloc_buffers != NULL){
104         btstack_memory_buffer_t * buffer = btstack_memory_malloc_buffers;
105         btstack_memory_malloc_buffers = buffer->next;
106         free(buffer);
107     }
108     btstack_assert(btstack_memory_malloc_counter == 0);
109 #endif
110 }
111 
112 
113 // MARK: hci_connection_t
114 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_HCI_CONNECTIONS)
115     #if defined(MAX_NO_HCI_CONNECTIONS)
116         #error "Deprecated MAX_NO_HCI_CONNECTIONS defined instead of MAX_NR_HCI_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_HCI_CONNECTIONS."
117     #else
118         #define MAX_NR_HCI_CONNECTIONS 0
119     #endif
120 #endif
121 
122 #ifdef MAX_NR_HCI_CONNECTIONS
123 #if MAX_NR_HCI_CONNECTIONS > 0
124 static hci_connection_t hci_connection_storage[MAX_NR_HCI_CONNECTIONS];
125 static btstack_memory_pool_t hci_connection_pool;
126 hci_connection_t * btstack_memory_hci_connection_get(void){
127     void * buffer = btstack_memory_pool_get(&hci_connection_pool);
128     if (buffer){
129         memset(buffer, 0, sizeof(hci_connection_t));
130     }
131     return (hci_connection_t *) buffer;
132 }
133 void btstack_memory_hci_connection_free(hci_connection_t *hci_connection){
134     btstack_memory_pool_free(&hci_connection_pool, hci_connection);
135 }
136 #else
137 hci_connection_t * btstack_memory_hci_connection_get(void){
138     return NULL;
139 }
140 void btstack_memory_hci_connection_free(hci_connection_t *hci_connection){
141     UNUSED(hci_connection);
142 };
143 #endif
144 #elif defined(HAVE_MALLOC)
145 
146 typedef struct {
147     btstack_memory_buffer_t tracking;
148     hci_connection_t data;
149 } btstack_memory_hci_connection_t;
150 
151 hci_connection_t * btstack_memory_hci_connection_get(void){
152     btstack_memory_hci_connection_t * buffer = (btstack_memory_hci_connection_t *) malloc(sizeof(btstack_memory_hci_connection_t));
153     if (buffer){
154         memset(buffer, 0, sizeof(btstack_memory_hci_connection_t));
155         btstack_memory_tracking_add(&buffer->tracking);
156         return &buffer->data;
157     } else {
158         return NULL;
159     }
160 }
161 void btstack_memory_hci_connection_free(hci_connection_t *hci_connection){
162     // reconstruct buffer start
163     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) hci_connection)[-1];
164     btstack_memory_tracking_remove(buffer);
165     free(buffer);
166 }
167 #endif
168 
169 
170 
171 // MARK: l2cap_service_t
172 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_L2CAP_SERVICES)
173     #if defined(MAX_NO_L2CAP_SERVICES)
174         #error "Deprecated MAX_NO_L2CAP_SERVICES defined instead of MAX_NR_L2CAP_SERVICES. Please update your btstack_config.h to use MAX_NR_L2CAP_SERVICES."
175     #else
176         #define MAX_NR_L2CAP_SERVICES 0
177     #endif
178 #endif
179 
180 #ifdef MAX_NR_L2CAP_SERVICES
181 #if MAX_NR_L2CAP_SERVICES > 0
182 static l2cap_service_t l2cap_service_storage[MAX_NR_L2CAP_SERVICES];
183 static btstack_memory_pool_t l2cap_service_pool;
184 l2cap_service_t * btstack_memory_l2cap_service_get(void){
185     void * buffer = btstack_memory_pool_get(&l2cap_service_pool);
186     if (buffer){
187         memset(buffer, 0, sizeof(l2cap_service_t));
188     }
189     return (l2cap_service_t *) buffer;
190 }
191 void btstack_memory_l2cap_service_free(l2cap_service_t *l2cap_service){
192     btstack_memory_pool_free(&l2cap_service_pool, l2cap_service);
193 }
194 #else
195 l2cap_service_t * btstack_memory_l2cap_service_get(void){
196     return NULL;
197 }
198 void btstack_memory_l2cap_service_free(l2cap_service_t *l2cap_service){
199     UNUSED(l2cap_service);
200 };
201 #endif
202 #elif defined(HAVE_MALLOC)
203 
204 typedef struct {
205     btstack_memory_buffer_t tracking;
206     l2cap_service_t data;
207 } btstack_memory_l2cap_service_t;
208 
209 l2cap_service_t * btstack_memory_l2cap_service_get(void){
210     btstack_memory_l2cap_service_t * buffer = (btstack_memory_l2cap_service_t *) malloc(sizeof(btstack_memory_l2cap_service_t));
211     if (buffer){
212         memset(buffer, 0, sizeof(btstack_memory_l2cap_service_t));
213         btstack_memory_tracking_add(&buffer->tracking);
214         return &buffer->data;
215     } else {
216         return NULL;
217     }
218 }
219 void btstack_memory_l2cap_service_free(l2cap_service_t *l2cap_service){
220     // reconstruct buffer start
221     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) l2cap_service)[-1];
222     btstack_memory_tracking_remove(buffer);
223     free(buffer);
224 }
225 #endif
226 
227 
228 // MARK: l2cap_channel_t
229 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_L2CAP_CHANNELS)
230     #if defined(MAX_NO_L2CAP_CHANNELS)
231         #error "Deprecated MAX_NO_L2CAP_CHANNELS defined instead of MAX_NR_L2CAP_CHANNELS. Please update your btstack_config.h to use MAX_NR_L2CAP_CHANNELS."
232     #else
233         #define MAX_NR_L2CAP_CHANNELS 0
234     #endif
235 #endif
236 
237 #ifdef MAX_NR_L2CAP_CHANNELS
238 #if MAX_NR_L2CAP_CHANNELS > 0
239 static l2cap_channel_t l2cap_channel_storage[MAX_NR_L2CAP_CHANNELS];
240 static btstack_memory_pool_t l2cap_channel_pool;
241 l2cap_channel_t * btstack_memory_l2cap_channel_get(void){
242     void * buffer = btstack_memory_pool_get(&l2cap_channel_pool);
243     if (buffer){
244         memset(buffer, 0, sizeof(l2cap_channel_t));
245     }
246     return (l2cap_channel_t *) buffer;
247 }
248 void btstack_memory_l2cap_channel_free(l2cap_channel_t *l2cap_channel){
249     btstack_memory_pool_free(&l2cap_channel_pool, l2cap_channel);
250 }
251 #else
252 l2cap_channel_t * btstack_memory_l2cap_channel_get(void){
253     return NULL;
254 }
255 void btstack_memory_l2cap_channel_free(l2cap_channel_t *l2cap_channel){
256     UNUSED(l2cap_channel);
257 };
258 #endif
259 #elif defined(HAVE_MALLOC)
260 
261 typedef struct {
262     btstack_memory_buffer_t tracking;
263     l2cap_channel_t data;
264 } btstack_memory_l2cap_channel_t;
265 
266 l2cap_channel_t * btstack_memory_l2cap_channel_get(void){
267     btstack_memory_l2cap_channel_t * buffer = (btstack_memory_l2cap_channel_t *) malloc(sizeof(btstack_memory_l2cap_channel_t));
268     if (buffer){
269         memset(buffer, 0, sizeof(btstack_memory_l2cap_channel_t));
270         btstack_memory_tracking_add(&buffer->tracking);
271         return &buffer->data;
272     } else {
273         return NULL;
274     }
275 }
276 void btstack_memory_l2cap_channel_free(l2cap_channel_t *l2cap_channel){
277     // reconstruct buffer start
278     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) l2cap_channel)[-1];
279     btstack_memory_tracking_remove(buffer);
280     free(buffer);
281 }
282 #endif
283 
284 
285 #ifdef ENABLE_CLASSIC
286 
287 // MARK: rfcomm_multiplexer_t
288 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_RFCOMM_MULTIPLEXERS)
289     #if defined(MAX_NO_RFCOMM_MULTIPLEXERS)
290         #error "Deprecated MAX_NO_RFCOMM_MULTIPLEXERS defined instead of MAX_NR_RFCOMM_MULTIPLEXERS. Please update your btstack_config.h to use MAX_NR_RFCOMM_MULTIPLEXERS."
291     #else
292         #define MAX_NR_RFCOMM_MULTIPLEXERS 0
293     #endif
294 #endif
295 
296 #ifdef MAX_NR_RFCOMM_MULTIPLEXERS
297 #if MAX_NR_RFCOMM_MULTIPLEXERS > 0
298 static rfcomm_multiplexer_t rfcomm_multiplexer_storage[MAX_NR_RFCOMM_MULTIPLEXERS];
299 static btstack_memory_pool_t rfcomm_multiplexer_pool;
300 rfcomm_multiplexer_t * btstack_memory_rfcomm_multiplexer_get(void){
301     void * buffer = btstack_memory_pool_get(&rfcomm_multiplexer_pool);
302     if (buffer){
303         memset(buffer, 0, sizeof(rfcomm_multiplexer_t));
304     }
305     return (rfcomm_multiplexer_t *) buffer;
306 }
307 void btstack_memory_rfcomm_multiplexer_free(rfcomm_multiplexer_t *rfcomm_multiplexer){
308     btstack_memory_pool_free(&rfcomm_multiplexer_pool, rfcomm_multiplexer);
309 }
310 #else
311 rfcomm_multiplexer_t * btstack_memory_rfcomm_multiplexer_get(void){
312     return NULL;
313 }
314 void btstack_memory_rfcomm_multiplexer_free(rfcomm_multiplexer_t *rfcomm_multiplexer){
315     UNUSED(rfcomm_multiplexer);
316 };
317 #endif
318 #elif defined(HAVE_MALLOC)
319 
320 typedef struct {
321     btstack_memory_buffer_t tracking;
322     rfcomm_multiplexer_t data;
323 } btstack_memory_rfcomm_multiplexer_t;
324 
325 rfcomm_multiplexer_t * btstack_memory_rfcomm_multiplexer_get(void){
326     btstack_memory_rfcomm_multiplexer_t * buffer = (btstack_memory_rfcomm_multiplexer_t *) malloc(sizeof(btstack_memory_rfcomm_multiplexer_t));
327     if (buffer){
328         memset(buffer, 0, sizeof(btstack_memory_rfcomm_multiplexer_t));
329         btstack_memory_tracking_add(&buffer->tracking);
330         return &buffer->data;
331     } else {
332         return NULL;
333     }
334 }
335 void btstack_memory_rfcomm_multiplexer_free(rfcomm_multiplexer_t *rfcomm_multiplexer){
336     // reconstruct buffer start
337     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) rfcomm_multiplexer)[-1];
338     btstack_memory_tracking_remove(buffer);
339     free(buffer);
340 }
341 #endif
342 
343 
344 // MARK: rfcomm_service_t
345 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_RFCOMM_SERVICES)
346     #if defined(MAX_NO_RFCOMM_SERVICES)
347         #error "Deprecated MAX_NO_RFCOMM_SERVICES defined instead of MAX_NR_RFCOMM_SERVICES. Please update your btstack_config.h to use MAX_NR_RFCOMM_SERVICES."
348     #else
349         #define MAX_NR_RFCOMM_SERVICES 0
350     #endif
351 #endif
352 
353 #ifdef MAX_NR_RFCOMM_SERVICES
354 #if MAX_NR_RFCOMM_SERVICES > 0
355 static rfcomm_service_t rfcomm_service_storage[MAX_NR_RFCOMM_SERVICES];
356 static btstack_memory_pool_t rfcomm_service_pool;
357 rfcomm_service_t * btstack_memory_rfcomm_service_get(void){
358     void * buffer = btstack_memory_pool_get(&rfcomm_service_pool);
359     if (buffer){
360         memset(buffer, 0, sizeof(rfcomm_service_t));
361     }
362     return (rfcomm_service_t *) buffer;
363 }
364 void btstack_memory_rfcomm_service_free(rfcomm_service_t *rfcomm_service){
365     btstack_memory_pool_free(&rfcomm_service_pool, rfcomm_service);
366 }
367 #else
368 rfcomm_service_t * btstack_memory_rfcomm_service_get(void){
369     return NULL;
370 }
371 void btstack_memory_rfcomm_service_free(rfcomm_service_t *rfcomm_service){
372     UNUSED(rfcomm_service);
373 };
374 #endif
375 #elif defined(HAVE_MALLOC)
376 
377 typedef struct {
378     btstack_memory_buffer_t tracking;
379     rfcomm_service_t data;
380 } btstack_memory_rfcomm_service_t;
381 
382 rfcomm_service_t * btstack_memory_rfcomm_service_get(void){
383     btstack_memory_rfcomm_service_t * buffer = (btstack_memory_rfcomm_service_t *) malloc(sizeof(btstack_memory_rfcomm_service_t));
384     if (buffer){
385         memset(buffer, 0, sizeof(btstack_memory_rfcomm_service_t));
386         btstack_memory_tracking_add(&buffer->tracking);
387         return &buffer->data;
388     } else {
389         return NULL;
390     }
391 }
392 void btstack_memory_rfcomm_service_free(rfcomm_service_t *rfcomm_service){
393     // reconstruct buffer start
394     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) rfcomm_service)[-1];
395     btstack_memory_tracking_remove(buffer);
396     free(buffer);
397 }
398 #endif
399 
400 
401 // MARK: rfcomm_channel_t
402 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_RFCOMM_CHANNELS)
403     #if defined(MAX_NO_RFCOMM_CHANNELS)
404         #error "Deprecated MAX_NO_RFCOMM_CHANNELS defined instead of MAX_NR_RFCOMM_CHANNELS. Please update your btstack_config.h to use MAX_NR_RFCOMM_CHANNELS."
405     #else
406         #define MAX_NR_RFCOMM_CHANNELS 0
407     #endif
408 #endif
409 
410 #ifdef MAX_NR_RFCOMM_CHANNELS
411 #if MAX_NR_RFCOMM_CHANNELS > 0
412 static rfcomm_channel_t rfcomm_channel_storage[MAX_NR_RFCOMM_CHANNELS];
413 static btstack_memory_pool_t rfcomm_channel_pool;
414 rfcomm_channel_t * btstack_memory_rfcomm_channel_get(void){
415     void * buffer = btstack_memory_pool_get(&rfcomm_channel_pool);
416     if (buffer){
417         memset(buffer, 0, sizeof(rfcomm_channel_t));
418     }
419     return (rfcomm_channel_t *) buffer;
420 }
421 void btstack_memory_rfcomm_channel_free(rfcomm_channel_t *rfcomm_channel){
422     btstack_memory_pool_free(&rfcomm_channel_pool, rfcomm_channel);
423 }
424 #else
425 rfcomm_channel_t * btstack_memory_rfcomm_channel_get(void){
426     return NULL;
427 }
428 void btstack_memory_rfcomm_channel_free(rfcomm_channel_t *rfcomm_channel){
429     UNUSED(rfcomm_channel);
430 };
431 #endif
432 #elif defined(HAVE_MALLOC)
433 
434 typedef struct {
435     btstack_memory_buffer_t tracking;
436     rfcomm_channel_t data;
437 } btstack_memory_rfcomm_channel_t;
438 
439 rfcomm_channel_t * btstack_memory_rfcomm_channel_get(void){
440     btstack_memory_rfcomm_channel_t * buffer = (btstack_memory_rfcomm_channel_t *) malloc(sizeof(btstack_memory_rfcomm_channel_t));
441     if (buffer){
442         memset(buffer, 0, sizeof(btstack_memory_rfcomm_channel_t));
443         btstack_memory_tracking_add(&buffer->tracking);
444         return &buffer->data;
445     } else {
446         return NULL;
447     }
448 }
449 void btstack_memory_rfcomm_channel_free(rfcomm_channel_t *rfcomm_channel){
450     // reconstruct buffer start
451     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) rfcomm_channel)[-1];
452     btstack_memory_tracking_remove(buffer);
453     free(buffer);
454 }
455 #endif
456 
457 
458 
459 // MARK: btstack_link_key_db_memory_entry_t
460 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES)
461     #if defined(MAX_NO_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES)
462         #error "Deprecated MAX_NO_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES defined instead of MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES. Please update your btstack_config.h to use MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES."
463     #else
464         #define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 0
465     #endif
466 #endif
467 
468 #ifdef MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES
469 #if MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES > 0
470 static btstack_link_key_db_memory_entry_t btstack_link_key_db_memory_entry_storage[MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES];
471 static btstack_memory_pool_t btstack_link_key_db_memory_entry_pool;
472 btstack_link_key_db_memory_entry_t * btstack_memory_btstack_link_key_db_memory_entry_get(void){
473     void * buffer = btstack_memory_pool_get(&btstack_link_key_db_memory_entry_pool);
474     if (buffer){
475         memset(buffer, 0, sizeof(btstack_link_key_db_memory_entry_t));
476     }
477     return (btstack_link_key_db_memory_entry_t *) buffer;
478 }
479 void btstack_memory_btstack_link_key_db_memory_entry_free(btstack_link_key_db_memory_entry_t *btstack_link_key_db_memory_entry){
480     btstack_memory_pool_free(&btstack_link_key_db_memory_entry_pool, btstack_link_key_db_memory_entry);
481 }
482 #else
483 btstack_link_key_db_memory_entry_t * btstack_memory_btstack_link_key_db_memory_entry_get(void){
484     return NULL;
485 }
486 void btstack_memory_btstack_link_key_db_memory_entry_free(btstack_link_key_db_memory_entry_t *btstack_link_key_db_memory_entry){
487     UNUSED(btstack_link_key_db_memory_entry);
488 };
489 #endif
490 #elif defined(HAVE_MALLOC)
491 
492 typedef struct {
493     btstack_memory_buffer_t tracking;
494     btstack_link_key_db_memory_entry_t data;
495 } btstack_memory_btstack_link_key_db_memory_entry_t;
496 
497 btstack_link_key_db_memory_entry_t * btstack_memory_btstack_link_key_db_memory_entry_get(void){
498     btstack_memory_btstack_link_key_db_memory_entry_t * buffer = (btstack_memory_btstack_link_key_db_memory_entry_t *) malloc(sizeof(btstack_memory_btstack_link_key_db_memory_entry_t));
499     if (buffer){
500         memset(buffer, 0, sizeof(btstack_memory_btstack_link_key_db_memory_entry_t));
501         btstack_memory_tracking_add(&buffer->tracking);
502         return &buffer->data;
503     } else {
504         return NULL;
505     }
506 }
507 void btstack_memory_btstack_link_key_db_memory_entry_free(btstack_link_key_db_memory_entry_t *btstack_link_key_db_memory_entry){
508     // reconstruct buffer start
509     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) btstack_link_key_db_memory_entry)[-1];
510     btstack_memory_tracking_remove(buffer);
511     free(buffer);
512 }
513 #endif
514 
515 
516 
517 // MARK: bnep_service_t
518 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_BNEP_SERVICES)
519     #if defined(MAX_NO_BNEP_SERVICES)
520         #error "Deprecated MAX_NO_BNEP_SERVICES defined instead of MAX_NR_BNEP_SERVICES. Please update your btstack_config.h to use MAX_NR_BNEP_SERVICES."
521     #else
522         #define MAX_NR_BNEP_SERVICES 0
523     #endif
524 #endif
525 
526 #ifdef MAX_NR_BNEP_SERVICES
527 #if MAX_NR_BNEP_SERVICES > 0
528 static bnep_service_t bnep_service_storage[MAX_NR_BNEP_SERVICES];
529 static btstack_memory_pool_t bnep_service_pool;
530 bnep_service_t * btstack_memory_bnep_service_get(void){
531     void * buffer = btstack_memory_pool_get(&bnep_service_pool);
532     if (buffer){
533         memset(buffer, 0, sizeof(bnep_service_t));
534     }
535     return (bnep_service_t *) buffer;
536 }
537 void btstack_memory_bnep_service_free(bnep_service_t *bnep_service){
538     btstack_memory_pool_free(&bnep_service_pool, bnep_service);
539 }
540 #else
541 bnep_service_t * btstack_memory_bnep_service_get(void){
542     return NULL;
543 }
544 void btstack_memory_bnep_service_free(bnep_service_t *bnep_service){
545     UNUSED(bnep_service);
546 };
547 #endif
548 #elif defined(HAVE_MALLOC)
549 
550 typedef struct {
551     btstack_memory_buffer_t tracking;
552     bnep_service_t data;
553 } btstack_memory_bnep_service_t;
554 
555 bnep_service_t * btstack_memory_bnep_service_get(void){
556     btstack_memory_bnep_service_t * buffer = (btstack_memory_bnep_service_t *) malloc(sizeof(btstack_memory_bnep_service_t));
557     if (buffer){
558         memset(buffer, 0, sizeof(btstack_memory_bnep_service_t));
559         btstack_memory_tracking_add(&buffer->tracking);
560         return &buffer->data;
561     } else {
562         return NULL;
563     }
564 }
565 void btstack_memory_bnep_service_free(bnep_service_t *bnep_service){
566     // reconstruct buffer start
567     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) bnep_service)[-1];
568     btstack_memory_tracking_remove(buffer);
569     free(buffer);
570 }
571 #endif
572 
573 
574 // MARK: bnep_channel_t
575 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_BNEP_CHANNELS)
576     #if defined(MAX_NO_BNEP_CHANNELS)
577         #error "Deprecated MAX_NO_BNEP_CHANNELS defined instead of MAX_NR_BNEP_CHANNELS. Please update your btstack_config.h to use MAX_NR_BNEP_CHANNELS."
578     #else
579         #define MAX_NR_BNEP_CHANNELS 0
580     #endif
581 #endif
582 
583 #ifdef MAX_NR_BNEP_CHANNELS
584 #if MAX_NR_BNEP_CHANNELS > 0
585 static bnep_channel_t bnep_channel_storage[MAX_NR_BNEP_CHANNELS];
586 static btstack_memory_pool_t bnep_channel_pool;
587 bnep_channel_t * btstack_memory_bnep_channel_get(void){
588     void * buffer = btstack_memory_pool_get(&bnep_channel_pool);
589     if (buffer){
590         memset(buffer, 0, sizeof(bnep_channel_t));
591     }
592     return (bnep_channel_t *) buffer;
593 }
594 void btstack_memory_bnep_channel_free(bnep_channel_t *bnep_channel){
595     btstack_memory_pool_free(&bnep_channel_pool, bnep_channel);
596 }
597 #else
598 bnep_channel_t * btstack_memory_bnep_channel_get(void){
599     return NULL;
600 }
601 void btstack_memory_bnep_channel_free(bnep_channel_t *bnep_channel){
602     UNUSED(bnep_channel);
603 };
604 #endif
605 #elif defined(HAVE_MALLOC)
606 
607 typedef struct {
608     btstack_memory_buffer_t tracking;
609     bnep_channel_t data;
610 } btstack_memory_bnep_channel_t;
611 
612 bnep_channel_t * btstack_memory_bnep_channel_get(void){
613     btstack_memory_bnep_channel_t * buffer = (btstack_memory_bnep_channel_t *) malloc(sizeof(btstack_memory_bnep_channel_t));
614     if (buffer){
615         memset(buffer, 0, sizeof(btstack_memory_bnep_channel_t));
616         btstack_memory_tracking_add(&buffer->tracking);
617         return &buffer->data;
618     } else {
619         return NULL;
620     }
621 }
622 void btstack_memory_bnep_channel_free(bnep_channel_t *bnep_channel){
623     // reconstruct buffer start
624     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) bnep_channel)[-1];
625     btstack_memory_tracking_remove(buffer);
626     free(buffer);
627 }
628 #endif
629 
630 
631 
632 // MARK: hfp_connection_t
633 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_HFP_CONNECTIONS)
634     #if defined(MAX_NO_HFP_CONNECTIONS)
635         #error "Deprecated MAX_NO_HFP_CONNECTIONS defined instead of MAX_NR_HFP_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_HFP_CONNECTIONS."
636     #else
637         #define MAX_NR_HFP_CONNECTIONS 0
638     #endif
639 #endif
640 
641 #ifdef MAX_NR_HFP_CONNECTIONS
642 #if MAX_NR_HFP_CONNECTIONS > 0
643 static hfp_connection_t hfp_connection_storage[MAX_NR_HFP_CONNECTIONS];
644 static btstack_memory_pool_t hfp_connection_pool;
645 hfp_connection_t * btstack_memory_hfp_connection_get(void){
646     void * buffer = btstack_memory_pool_get(&hfp_connection_pool);
647     if (buffer){
648         memset(buffer, 0, sizeof(hfp_connection_t));
649     }
650     return (hfp_connection_t *) buffer;
651 }
652 void btstack_memory_hfp_connection_free(hfp_connection_t *hfp_connection){
653     btstack_memory_pool_free(&hfp_connection_pool, hfp_connection);
654 }
655 #else
656 hfp_connection_t * btstack_memory_hfp_connection_get(void){
657     return NULL;
658 }
659 void btstack_memory_hfp_connection_free(hfp_connection_t *hfp_connection){
660     UNUSED(hfp_connection);
661 };
662 #endif
663 #elif defined(HAVE_MALLOC)
664 
665 typedef struct {
666     btstack_memory_buffer_t tracking;
667     hfp_connection_t data;
668 } btstack_memory_hfp_connection_t;
669 
670 hfp_connection_t * btstack_memory_hfp_connection_get(void){
671     btstack_memory_hfp_connection_t * buffer = (btstack_memory_hfp_connection_t *) malloc(sizeof(btstack_memory_hfp_connection_t));
672     if (buffer){
673         memset(buffer, 0, sizeof(btstack_memory_hfp_connection_t));
674         btstack_memory_tracking_add(&buffer->tracking);
675         return &buffer->data;
676     } else {
677         return NULL;
678     }
679 }
680 void btstack_memory_hfp_connection_free(hfp_connection_t *hfp_connection){
681     // reconstruct buffer start
682     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) hfp_connection)[-1];
683     btstack_memory_tracking_remove(buffer);
684     free(buffer);
685 }
686 #endif
687 
688 
689 
690 // MARK: hid_host_connection_t
691 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_HID_HOST_CONNECTIONS)
692     #if defined(MAX_NO_HID_HOST_CONNECTIONS)
693         #error "Deprecated MAX_NO_HID_HOST_CONNECTIONS defined instead of MAX_NR_HID_HOST_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_HID_HOST_CONNECTIONS."
694     #else
695         #define MAX_NR_HID_HOST_CONNECTIONS 0
696     #endif
697 #endif
698 
699 #ifdef MAX_NR_HID_HOST_CONNECTIONS
700 #if MAX_NR_HID_HOST_CONNECTIONS > 0
701 static hid_host_connection_t hid_host_connection_storage[MAX_NR_HID_HOST_CONNECTIONS];
702 static btstack_memory_pool_t hid_host_connection_pool;
703 hid_host_connection_t * btstack_memory_hid_host_connection_get(void){
704     void * buffer = btstack_memory_pool_get(&hid_host_connection_pool);
705     if (buffer){
706         memset(buffer, 0, sizeof(hid_host_connection_t));
707     }
708     return (hid_host_connection_t *) buffer;
709 }
710 void btstack_memory_hid_host_connection_free(hid_host_connection_t *hid_host_connection){
711     btstack_memory_pool_free(&hid_host_connection_pool, hid_host_connection);
712 }
713 #else
714 hid_host_connection_t * btstack_memory_hid_host_connection_get(void){
715     return NULL;
716 }
717 void btstack_memory_hid_host_connection_free(hid_host_connection_t *hid_host_connection){
718     // silence compiler warning about unused parameter in a portable way
719     (void) hid_host_connection;
720 };
721 #endif
722 #elif defined(HAVE_MALLOC)
723 hid_host_connection_t * btstack_memory_hid_host_connection_get(void){
724     void * buffer = malloc(sizeof(hid_host_connection_t));
725     if (buffer){
726         memset(buffer, 0, sizeof(hid_host_connection_t));
727     }
728     return (hid_host_connection_t *) buffer;
729 }
730 void btstack_memory_hid_host_connection_free(hid_host_connection_t *hid_host_connection){
731     free(hid_host_connection);
732 }
733 #endif
734 
735 
736 
737 // MARK: service_record_item_t
738 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_SERVICE_RECORD_ITEMS)
739     #if defined(MAX_NO_SERVICE_RECORD_ITEMS)
740         #error "Deprecated MAX_NO_SERVICE_RECORD_ITEMS defined instead of MAX_NR_SERVICE_RECORD_ITEMS. Please update your btstack_config.h to use MAX_NR_SERVICE_RECORD_ITEMS."
741     #else
742         #define MAX_NR_SERVICE_RECORD_ITEMS 0
743     #endif
744 #endif
745 
746 #ifdef MAX_NR_SERVICE_RECORD_ITEMS
747 #if MAX_NR_SERVICE_RECORD_ITEMS > 0
748 static service_record_item_t service_record_item_storage[MAX_NR_SERVICE_RECORD_ITEMS];
749 static btstack_memory_pool_t service_record_item_pool;
750 service_record_item_t * btstack_memory_service_record_item_get(void){
751     void * buffer = btstack_memory_pool_get(&service_record_item_pool);
752     if (buffer){
753         memset(buffer, 0, sizeof(service_record_item_t));
754     }
755     return (service_record_item_t *) buffer;
756 }
757 void btstack_memory_service_record_item_free(service_record_item_t *service_record_item){
758     btstack_memory_pool_free(&service_record_item_pool, service_record_item);
759 }
760 #else
761 service_record_item_t * btstack_memory_service_record_item_get(void){
762     return NULL;
763 }
764 void btstack_memory_service_record_item_free(service_record_item_t *service_record_item){
765     UNUSED(service_record_item);
766 };
767 #endif
768 #elif defined(HAVE_MALLOC)
769 
770 typedef struct {
771     btstack_memory_buffer_t tracking;
772     service_record_item_t data;
773 } btstack_memory_service_record_item_t;
774 
775 service_record_item_t * btstack_memory_service_record_item_get(void){
776     btstack_memory_service_record_item_t * buffer = (btstack_memory_service_record_item_t *) malloc(sizeof(btstack_memory_service_record_item_t));
777     if (buffer){
778         memset(buffer, 0, sizeof(btstack_memory_service_record_item_t));
779         btstack_memory_tracking_add(&buffer->tracking);
780         return &buffer->data;
781     } else {
782         return NULL;
783     }
784 }
785 void btstack_memory_service_record_item_free(service_record_item_t *service_record_item){
786     // reconstruct buffer start
787     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) service_record_item)[-1];
788     btstack_memory_tracking_remove(buffer);
789     free(buffer);
790 }
791 #endif
792 
793 
794 
795 // MARK: avdtp_stream_endpoint_t
796 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_AVDTP_STREAM_ENDPOINTS)
797     #if defined(MAX_NO_AVDTP_STREAM_ENDPOINTS)
798         #error "Deprecated MAX_NO_AVDTP_STREAM_ENDPOINTS defined instead of MAX_NR_AVDTP_STREAM_ENDPOINTS. Please update your btstack_config.h to use MAX_NR_AVDTP_STREAM_ENDPOINTS."
799     #else
800         #define MAX_NR_AVDTP_STREAM_ENDPOINTS 0
801     #endif
802 #endif
803 
804 #ifdef MAX_NR_AVDTP_STREAM_ENDPOINTS
805 #if MAX_NR_AVDTP_STREAM_ENDPOINTS > 0
806 static avdtp_stream_endpoint_t avdtp_stream_endpoint_storage[MAX_NR_AVDTP_STREAM_ENDPOINTS];
807 static btstack_memory_pool_t avdtp_stream_endpoint_pool;
808 avdtp_stream_endpoint_t * btstack_memory_avdtp_stream_endpoint_get(void){
809     void * buffer = btstack_memory_pool_get(&avdtp_stream_endpoint_pool);
810     if (buffer){
811         memset(buffer, 0, sizeof(avdtp_stream_endpoint_t));
812     }
813     return (avdtp_stream_endpoint_t *) buffer;
814 }
815 void btstack_memory_avdtp_stream_endpoint_free(avdtp_stream_endpoint_t *avdtp_stream_endpoint){
816     btstack_memory_pool_free(&avdtp_stream_endpoint_pool, avdtp_stream_endpoint);
817 }
818 #else
819 avdtp_stream_endpoint_t * btstack_memory_avdtp_stream_endpoint_get(void){
820     return NULL;
821 }
822 void btstack_memory_avdtp_stream_endpoint_free(avdtp_stream_endpoint_t *avdtp_stream_endpoint){
823     UNUSED(avdtp_stream_endpoint);
824 };
825 #endif
826 #elif defined(HAVE_MALLOC)
827 
828 typedef struct {
829     btstack_memory_buffer_t tracking;
830     avdtp_stream_endpoint_t data;
831 } btstack_memory_avdtp_stream_endpoint_t;
832 
833 avdtp_stream_endpoint_t * btstack_memory_avdtp_stream_endpoint_get(void){
834     btstack_memory_avdtp_stream_endpoint_t * buffer = (btstack_memory_avdtp_stream_endpoint_t *) malloc(sizeof(btstack_memory_avdtp_stream_endpoint_t));
835     if (buffer){
836         memset(buffer, 0, sizeof(btstack_memory_avdtp_stream_endpoint_t));
837         btstack_memory_tracking_add(&buffer->tracking);
838         return &buffer->data;
839     } else {
840         return NULL;
841     }
842 }
843 void btstack_memory_avdtp_stream_endpoint_free(avdtp_stream_endpoint_t *avdtp_stream_endpoint){
844     // reconstruct buffer start
845     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) avdtp_stream_endpoint)[-1];
846     btstack_memory_tracking_remove(buffer);
847     free(buffer);
848 }
849 #endif
850 
851 
852 
853 // MARK: avdtp_connection_t
854 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_AVDTP_CONNECTIONS)
855     #if defined(MAX_NO_AVDTP_CONNECTIONS)
856         #error "Deprecated MAX_NO_AVDTP_CONNECTIONS defined instead of MAX_NR_AVDTP_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_AVDTP_CONNECTIONS."
857     #else
858         #define MAX_NR_AVDTP_CONNECTIONS 0
859     #endif
860 #endif
861 
862 #ifdef MAX_NR_AVDTP_CONNECTIONS
863 #if MAX_NR_AVDTP_CONNECTIONS > 0
864 static avdtp_connection_t avdtp_connection_storage[MAX_NR_AVDTP_CONNECTIONS];
865 static btstack_memory_pool_t avdtp_connection_pool;
866 avdtp_connection_t * btstack_memory_avdtp_connection_get(void){
867     void * buffer = btstack_memory_pool_get(&avdtp_connection_pool);
868     if (buffer){
869         memset(buffer, 0, sizeof(avdtp_connection_t));
870     }
871     return (avdtp_connection_t *) buffer;
872 }
873 void btstack_memory_avdtp_connection_free(avdtp_connection_t *avdtp_connection){
874     btstack_memory_pool_free(&avdtp_connection_pool, avdtp_connection);
875 }
876 #else
877 avdtp_connection_t * btstack_memory_avdtp_connection_get(void){
878     return NULL;
879 }
880 void btstack_memory_avdtp_connection_free(avdtp_connection_t *avdtp_connection){
881     UNUSED(avdtp_connection);
882 };
883 #endif
884 #elif defined(HAVE_MALLOC)
885 
886 typedef struct {
887     btstack_memory_buffer_t tracking;
888     avdtp_connection_t data;
889 } btstack_memory_avdtp_connection_t;
890 
891 avdtp_connection_t * btstack_memory_avdtp_connection_get(void){
892     btstack_memory_avdtp_connection_t * buffer = (btstack_memory_avdtp_connection_t *) malloc(sizeof(btstack_memory_avdtp_connection_t));
893     if (buffer){
894         memset(buffer, 0, sizeof(btstack_memory_avdtp_connection_t));
895         btstack_memory_tracking_add(&buffer->tracking);
896         return &buffer->data;
897     } else {
898         return NULL;
899     }
900 }
901 void btstack_memory_avdtp_connection_free(avdtp_connection_t *avdtp_connection){
902     // reconstruct buffer start
903     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) avdtp_connection)[-1];
904     btstack_memory_tracking_remove(buffer);
905     free(buffer);
906 }
907 #endif
908 
909 
910 
911 // MARK: avrcp_connection_t
912 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_AVRCP_CONNECTIONS)
913     #if defined(MAX_NO_AVRCP_CONNECTIONS)
914         #error "Deprecated MAX_NO_AVRCP_CONNECTIONS defined instead of MAX_NR_AVRCP_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_AVRCP_CONNECTIONS."
915     #else
916         #define MAX_NR_AVRCP_CONNECTIONS 0
917     #endif
918 #endif
919 
920 #ifdef MAX_NR_AVRCP_CONNECTIONS
921 #if MAX_NR_AVRCP_CONNECTIONS > 0
922 static avrcp_connection_t avrcp_connection_storage[MAX_NR_AVRCP_CONNECTIONS];
923 static btstack_memory_pool_t avrcp_connection_pool;
924 avrcp_connection_t * btstack_memory_avrcp_connection_get(void){
925     void * buffer = btstack_memory_pool_get(&avrcp_connection_pool);
926     if (buffer){
927         memset(buffer, 0, sizeof(avrcp_connection_t));
928     }
929     return (avrcp_connection_t *) buffer;
930 }
931 void btstack_memory_avrcp_connection_free(avrcp_connection_t *avrcp_connection){
932     btstack_memory_pool_free(&avrcp_connection_pool, avrcp_connection);
933 }
934 #else
935 avrcp_connection_t * btstack_memory_avrcp_connection_get(void){
936     return NULL;
937 }
938 void btstack_memory_avrcp_connection_free(avrcp_connection_t *avrcp_connection){
939     UNUSED(avrcp_connection);
940 };
941 #endif
942 #elif defined(HAVE_MALLOC)
943 
944 typedef struct {
945     btstack_memory_buffer_t tracking;
946     avrcp_connection_t data;
947 } btstack_memory_avrcp_connection_t;
948 
949 avrcp_connection_t * btstack_memory_avrcp_connection_get(void){
950     btstack_memory_avrcp_connection_t * buffer = (btstack_memory_avrcp_connection_t *) malloc(sizeof(btstack_memory_avrcp_connection_t));
951     if (buffer){
952         memset(buffer, 0, sizeof(btstack_memory_avrcp_connection_t));
953         btstack_memory_tracking_add(&buffer->tracking);
954         return &buffer->data;
955     } else {
956         return NULL;
957     }
958 }
959 void btstack_memory_avrcp_connection_free(avrcp_connection_t *avrcp_connection){
960     // reconstruct buffer start
961     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) avrcp_connection)[-1];
962     btstack_memory_tracking_remove(buffer);
963     free(buffer);
964 }
965 #endif
966 
967 
968 
969 // MARK: avrcp_browsing_connection_t
970 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_AVRCP_BROWSING_CONNECTIONS)
971     #if defined(MAX_NO_AVRCP_BROWSING_CONNECTIONS)
972         #error "Deprecated MAX_NO_AVRCP_BROWSING_CONNECTIONS defined instead of MAX_NR_AVRCP_BROWSING_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_AVRCP_BROWSING_CONNECTIONS."
973     #else
974         #define MAX_NR_AVRCP_BROWSING_CONNECTIONS 0
975     #endif
976 #endif
977 
978 #ifdef MAX_NR_AVRCP_BROWSING_CONNECTIONS
979 #if MAX_NR_AVRCP_BROWSING_CONNECTIONS > 0
980 static avrcp_browsing_connection_t avrcp_browsing_connection_storage[MAX_NR_AVRCP_BROWSING_CONNECTIONS];
981 static btstack_memory_pool_t avrcp_browsing_connection_pool;
982 avrcp_browsing_connection_t * btstack_memory_avrcp_browsing_connection_get(void){
983     void * buffer = btstack_memory_pool_get(&avrcp_browsing_connection_pool);
984     if (buffer){
985         memset(buffer, 0, sizeof(avrcp_browsing_connection_t));
986     }
987     return (avrcp_browsing_connection_t *) buffer;
988 }
989 void btstack_memory_avrcp_browsing_connection_free(avrcp_browsing_connection_t *avrcp_browsing_connection){
990     btstack_memory_pool_free(&avrcp_browsing_connection_pool, avrcp_browsing_connection);
991 }
992 #else
993 avrcp_browsing_connection_t * btstack_memory_avrcp_browsing_connection_get(void){
994     return NULL;
995 }
996 void btstack_memory_avrcp_browsing_connection_free(avrcp_browsing_connection_t *avrcp_browsing_connection){
997     UNUSED(avrcp_browsing_connection);
998 };
999 #endif
1000 #elif defined(HAVE_MALLOC)
1001 
1002 typedef struct {
1003     btstack_memory_buffer_t tracking;
1004     avrcp_browsing_connection_t data;
1005 } btstack_memory_avrcp_browsing_connection_t;
1006 
1007 avrcp_browsing_connection_t * btstack_memory_avrcp_browsing_connection_get(void){
1008     btstack_memory_avrcp_browsing_connection_t * buffer = (btstack_memory_avrcp_browsing_connection_t *) malloc(sizeof(btstack_memory_avrcp_browsing_connection_t));
1009     if (buffer){
1010         memset(buffer, 0, sizeof(btstack_memory_avrcp_browsing_connection_t));
1011         btstack_memory_tracking_add(&buffer->tracking);
1012         return &buffer->data;
1013     } else {
1014         return NULL;
1015     }
1016 }
1017 void btstack_memory_avrcp_browsing_connection_free(avrcp_browsing_connection_t *avrcp_browsing_connection){
1018     // reconstruct buffer start
1019     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) avrcp_browsing_connection)[-1];
1020     btstack_memory_tracking_remove(buffer);
1021     free(buffer);
1022 }
1023 #endif
1024 
1025 
1026 #endif
1027 #ifdef ENABLE_BLE
1028 
1029 // MARK: gatt_client_t
1030 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_GATT_CLIENTS)
1031     #if defined(MAX_NO_GATT_CLIENTS)
1032         #error "Deprecated MAX_NO_GATT_CLIENTS defined instead of MAX_NR_GATT_CLIENTS. Please update your btstack_config.h to use MAX_NR_GATT_CLIENTS."
1033     #else
1034         #define MAX_NR_GATT_CLIENTS 0
1035     #endif
1036 #endif
1037 
1038 #ifdef MAX_NR_GATT_CLIENTS
1039 #if MAX_NR_GATT_CLIENTS > 0
1040 static gatt_client_t gatt_client_storage[MAX_NR_GATT_CLIENTS];
1041 static btstack_memory_pool_t gatt_client_pool;
1042 gatt_client_t * btstack_memory_gatt_client_get(void){
1043     void * buffer = btstack_memory_pool_get(&gatt_client_pool);
1044     if (buffer){
1045         memset(buffer, 0, sizeof(gatt_client_t));
1046     }
1047     return (gatt_client_t *) buffer;
1048 }
1049 void btstack_memory_gatt_client_free(gatt_client_t *gatt_client){
1050     btstack_memory_pool_free(&gatt_client_pool, gatt_client);
1051 }
1052 #else
1053 gatt_client_t * btstack_memory_gatt_client_get(void){
1054     return NULL;
1055 }
1056 void btstack_memory_gatt_client_free(gatt_client_t *gatt_client){
1057     UNUSED(gatt_client);
1058 };
1059 #endif
1060 #elif defined(HAVE_MALLOC)
1061 
1062 typedef struct {
1063     btstack_memory_buffer_t tracking;
1064     gatt_client_t data;
1065 } btstack_memory_gatt_client_t;
1066 
1067 gatt_client_t * btstack_memory_gatt_client_get(void){
1068     btstack_memory_gatt_client_t * buffer = (btstack_memory_gatt_client_t *) malloc(sizeof(btstack_memory_gatt_client_t));
1069     if (buffer){
1070         memset(buffer, 0, sizeof(btstack_memory_gatt_client_t));
1071         btstack_memory_tracking_add(&buffer->tracking);
1072         return &buffer->data;
1073     } else {
1074         return NULL;
1075     }
1076 }
1077 void btstack_memory_gatt_client_free(gatt_client_t *gatt_client){
1078     // reconstruct buffer start
1079     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) gatt_client)[-1];
1080     btstack_memory_tracking_remove(buffer);
1081     free(buffer);
1082 }
1083 #endif
1084 
1085 
1086 // MARK: whitelist_entry_t
1087 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_WHITELIST_ENTRIES)
1088     #if defined(MAX_NO_WHITELIST_ENTRIES)
1089         #error "Deprecated MAX_NO_WHITELIST_ENTRIES defined instead of MAX_NR_WHITELIST_ENTRIES. Please update your btstack_config.h to use MAX_NR_WHITELIST_ENTRIES."
1090     #else
1091         #define MAX_NR_WHITELIST_ENTRIES 0
1092     #endif
1093 #endif
1094 
1095 #ifdef MAX_NR_WHITELIST_ENTRIES
1096 #if MAX_NR_WHITELIST_ENTRIES > 0
1097 static whitelist_entry_t whitelist_entry_storage[MAX_NR_WHITELIST_ENTRIES];
1098 static btstack_memory_pool_t whitelist_entry_pool;
1099 whitelist_entry_t * btstack_memory_whitelist_entry_get(void){
1100     void * buffer = btstack_memory_pool_get(&whitelist_entry_pool);
1101     if (buffer){
1102         memset(buffer, 0, sizeof(whitelist_entry_t));
1103     }
1104     return (whitelist_entry_t *) buffer;
1105 }
1106 void btstack_memory_whitelist_entry_free(whitelist_entry_t *whitelist_entry){
1107     btstack_memory_pool_free(&whitelist_entry_pool, whitelist_entry);
1108 }
1109 #else
1110 whitelist_entry_t * btstack_memory_whitelist_entry_get(void){
1111     return NULL;
1112 }
1113 void btstack_memory_whitelist_entry_free(whitelist_entry_t *whitelist_entry){
1114     UNUSED(whitelist_entry);
1115 };
1116 #endif
1117 #elif defined(HAVE_MALLOC)
1118 
1119 typedef struct {
1120     btstack_memory_buffer_t tracking;
1121     whitelist_entry_t data;
1122 } btstack_memory_whitelist_entry_t;
1123 
1124 whitelist_entry_t * btstack_memory_whitelist_entry_get(void){
1125     btstack_memory_whitelist_entry_t * buffer = (btstack_memory_whitelist_entry_t *) malloc(sizeof(btstack_memory_whitelist_entry_t));
1126     if (buffer){
1127         memset(buffer, 0, sizeof(btstack_memory_whitelist_entry_t));
1128         btstack_memory_tracking_add(&buffer->tracking);
1129         return &buffer->data;
1130     } else {
1131         return NULL;
1132     }
1133 }
1134 void btstack_memory_whitelist_entry_free(whitelist_entry_t *whitelist_entry){
1135     // reconstruct buffer start
1136     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) whitelist_entry)[-1];
1137     btstack_memory_tracking_remove(buffer);
1138     free(buffer);
1139 }
1140 #endif
1141 
1142 
1143 // MARK: sm_lookup_entry_t
1144 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_SM_LOOKUP_ENTRIES)
1145     #if defined(MAX_NO_SM_LOOKUP_ENTRIES)
1146         #error "Deprecated MAX_NO_SM_LOOKUP_ENTRIES defined instead of MAX_NR_SM_LOOKUP_ENTRIES. Please update your btstack_config.h to use MAX_NR_SM_LOOKUP_ENTRIES."
1147     #else
1148         #define MAX_NR_SM_LOOKUP_ENTRIES 0
1149     #endif
1150 #endif
1151 
1152 #ifdef MAX_NR_SM_LOOKUP_ENTRIES
1153 #if MAX_NR_SM_LOOKUP_ENTRIES > 0
1154 static sm_lookup_entry_t sm_lookup_entry_storage[MAX_NR_SM_LOOKUP_ENTRIES];
1155 static btstack_memory_pool_t sm_lookup_entry_pool;
1156 sm_lookup_entry_t * btstack_memory_sm_lookup_entry_get(void){
1157     void * buffer = btstack_memory_pool_get(&sm_lookup_entry_pool);
1158     if (buffer){
1159         memset(buffer, 0, sizeof(sm_lookup_entry_t));
1160     }
1161     return (sm_lookup_entry_t *) buffer;
1162 }
1163 void btstack_memory_sm_lookup_entry_free(sm_lookup_entry_t *sm_lookup_entry){
1164     btstack_memory_pool_free(&sm_lookup_entry_pool, sm_lookup_entry);
1165 }
1166 #else
1167 sm_lookup_entry_t * btstack_memory_sm_lookup_entry_get(void){
1168     return NULL;
1169 }
1170 void btstack_memory_sm_lookup_entry_free(sm_lookup_entry_t *sm_lookup_entry){
1171     UNUSED(sm_lookup_entry);
1172 };
1173 #endif
1174 #elif defined(HAVE_MALLOC)
1175 
1176 typedef struct {
1177     btstack_memory_buffer_t tracking;
1178     sm_lookup_entry_t data;
1179 } btstack_memory_sm_lookup_entry_t;
1180 
1181 sm_lookup_entry_t * btstack_memory_sm_lookup_entry_get(void){
1182     btstack_memory_sm_lookup_entry_t * buffer = (btstack_memory_sm_lookup_entry_t *) malloc(sizeof(btstack_memory_sm_lookup_entry_t));
1183     if (buffer){
1184         memset(buffer, 0, sizeof(btstack_memory_sm_lookup_entry_t));
1185         btstack_memory_tracking_add(&buffer->tracking);
1186         return &buffer->data;
1187     } else {
1188         return NULL;
1189     }
1190 }
1191 void btstack_memory_sm_lookup_entry_free(sm_lookup_entry_t *sm_lookup_entry){
1192     // reconstruct buffer start
1193     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) sm_lookup_entry)[-1];
1194     btstack_memory_tracking_remove(buffer);
1195     free(buffer);
1196 }
1197 #endif
1198 
1199 
1200 #endif
1201 #ifdef ENABLE_MESH
1202 
1203 // MARK: mesh_network_pdu_t
1204 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_MESH_NETWORK_PDUS)
1205     #if defined(MAX_NO_MESH_NETWORK_PDUS)
1206         #error "Deprecated MAX_NO_MESH_NETWORK_PDUS defined instead of MAX_NR_MESH_NETWORK_PDUS. Please update your btstack_config.h to use MAX_NR_MESH_NETWORK_PDUS."
1207     #else
1208         #define MAX_NR_MESH_NETWORK_PDUS 0
1209     #endif
1210 #endif
1211 
1212 #ifdef MAX_NR_MESH_NETWORK_PDUS
1213 #if MAX_NR_MESH_NETWORK_PDUS > 0
1214 static mesh_network_pdu_t mesh_network_pdu_storage[MAX_NR_MESH_NETWORK_PDUS];
1215 static btstack_memory_pool_t mesh_network_pdu_pool;
1216 mesh_network_pdu_t * btstack_memory_mesh_network_pdu_get(void){
1217     void * buffer = btstack_memory_pool_get(&mesh_network_pdu_pool);
1218     if (buffer){
1219         memset(buffer, 0, sizeof(mesh_network_pdu_t));
1220     }
1221     return (mesh_network_pdu_t *) buffer;
1222 }
1223 void btstack_memory_mesh_network_pdu_free(mesh_network_pdu_t *mesh_network_pdu){
1224     btstack_memory_pool_free(&mesh_network_pdu_pool, mesh_network_pdu);
1225 }
1226 #else
1227 mesh_network_pdu_t * btstack_memory_mesh_network_pdu_get(void){
1228     return NULL;
1229 }
1230 void btstack_memory_mesh_network_pdu_free(mesh_network_pdu_t *mesh_network_pdu){
1231     UNUSED(mesh_network_pdu);
1232 };
1233 #endif
1234 #elif defined(HAVE_MALLOC)
1235 
1236 typedef struct {
1237     btstack_memory_buffer_t tracking;
1238     mesh_network_pdu_t data;
1239 } btstack_memory_mesh_network_pdu_t;
1240 
1241 mesh_network_pdu_t * btstack_memory_mesh_network_pdu_get(void){
1242     btstack_memory_mesh_network_pdu_t * buffer = (btstack_memory_mesh_network_pdu_t *) malloc(sizeof(btstack_memory_mesh_network_pdu_t));
1243     if (buffer){
1244         memset(buffer, 0, sizeof(btstack_memory_mesh_network_pdu_t));
1245         btstack_memory_tracking_add(&buffer->tracking);
1246         return &buffer->data;
1247     } else {
1248         return NULL;
1249     }
1250 }
1251 void btstack_memory_mesh_network_pdu_free(mesh_network_pdu_t *mesh_network_pdu){
1252     // reconstruct buffer start
1253     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) mesh_network_pdu)[-1];
1254     btstack_memory_tracking_remove(buffer);
1255     free(buffer);
1256 }
1257 #endif
1258 
1259 
1260 // MARK: mesh_segmented_pdu_t
1261 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_MESH_SEGMENTED_PDUS)
1262     #if defined(MAX_NO_MESH_SEGMENTED_PDUS)
1263         #error "Deprecated MAX_NO_MESH_SEGMENTED_PDUS defined instead of MAX_NR_MESH_SEGMENTED_PDUS. Please update your btstack_config.h to use MAX_NR_MESH_SEGMENTED_PDUS."
1264     #else
1265         #define MAX_NR_MESH_SEGMENTED_PDUS 0
1266     #endif
1267 #endif
1268 
1269 #ifdef MAX_NR_MESH_SEGMENTED_PDUS
1270 #if MAX_NR_MESH_SEGMENTED_PDUS > 0
1271 static mesh_segmented_pdu_t mesh_segmented_pdu_storage[MAX_NR_MESH_SEGMENTED_PDUS];
1272 static btstack_memory_pool_t mesh_segmented_pdu_pool;
1273 mesh_segmented_pdu_t * btstack_memory_mesh_segmented_pdu_get(void){
1274     void * buffer = btstack_memory_pool_get(&mesh_segmented_pdu_pool);
1275     if (buffer){
1276         memset(buffer, 0, sizeof(mesh_segmented_pdu_t));
1277     }
1278     return (mesh_segmented_pdu_t *) buffer;
1279 }
1280 void btstack_memory_mesh_segmented_pdu_free(mesh_segmented_pdu_t *mesh_segmented_pdu){
1281     btstack_memory_pool_free(&mesh_segmented_pdu_pool, mesh_segmented_pdu);
1282 }
1283 #else
1284 mesh_segmented_pdu_t * btstack_memory_mesh_segmented_pdu_get(void){
1285     return NULL;
1286 }
1287 void btstack_memory_mesh_segmented_pdu_free(mesh_segmented_pdu_t *mesh_segmented_pdu){
1288     UNUSED(mesh_segmented_pdu);
1289 };
1290 #endif
1291 #elif defined(HAVE_MALLOC)
1292 
1293 typedef struct {
1294     btstack_memory_buffer_t tracking;
1295     mesh_segmented_pdu_t data;
1296 } btstack_memory_mesh_segmented_pdu_t;
1297 
1298 mesh_segmented_pdu_t * btstack_memory_mesh_segmented_pdu_get(void){
1299     btstack_memory_mesh_segmented_pdu_t * buffer = (btstack_memory_mesh_segmented_pdu_t *) malloc(sizeof(btstack_memory_mesh_segmented_pdu_t));
1300     if (buffer){
1301         memset(buffer, 0, sizeof(btstack_memory_mesh_segmented_pdu_t));
1302         btstack_memory_tracking_add(&buffer->tracking);
1303         return &buffer->data;
1304     } else {
1305         return NULL;
1306     }
1307 }
1308 void btstack_memory_mesh_segmented_pdu_free(mesh_segmented_pdu_t *mesh_segmented_pdu){
1309     // reconstruct buffer start
1310     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) mesh_segmented_pdu)[-1];
1311     btstack_memory_tracking_remove(buffer);
1312     free(buffer);
1313 }
1314 #endif
1315 
1316 
1317 // MARK: mesh_upper_transport_pdu_t
1318 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_MESH_UPPER_TRANSPORT_PDUS)
1319     #if defined(MAX_NO_MESH_UPPER_TRANSPORT_PDUS)
1320         #error "Deprecated MAX_NO_MESH_UPPER_TRANSPORT_PDUS defined instead of MAX_NR_MESH_UPPER_TRANSPORT_PDUS. Please update your btstack_config.h to use MAX_NR_MESH_UPPER_TRANSPORT_PDUS."
1321     #else
1322         #define MAX_NR_MESH_UPPER_TRANSPORT_PDUS 0
1323     #endif
1324 #endif
1325 
1326 #ifdef MAX_NR_MESH_UPPER_TRANSPORT_PDUS
1327 #if MAX_NR_MESH_UPPER_TRANSPORT_PDUS > 0
1328 static mesh_upper_transport_pdu_t mesh_upper_transport_pdu_storage[MAX_NR_MESH_UPPER_TRANSPORT_PDUS];
1329 static btstack_memory_pool_t mesh_upper_transport_pdu_pool;
1330 mesh_upper_transport_pdu_t * btstack_memory_mesh_upper_transport_pdu_get(void){
1331     void * buffer = btstack_memory_pool_get(&mesh_upper_transport_pdu_pool);
1332     if (buffer){
1333         memset(buffer, 0, sizeof(mesh_upper_transport_pdu_t));
1334     }
1335     return (mesh_upper_transport_pdu_t *) buffer;
1336 }
1337 void btstack_memory_mesh_upper_transport_pdu_free(mesh_upper_transport_pdu_t *mesh_upper_transport_pdu){
1338     btstack_memory_pool_free(&mesh_upper_transport_pdu_pool, mesh_upper_transport_pdu);
1339 }
1340 #else
1341 mesh_upper_transport_pdu_t * btstack_memory_mesh_upper_transport_pdu_get(void){
1342     return NULL;
1343 }
1344 void btstack_memory_mesh_upper_transport_pdu_free(mesh_upper_transport_pdu_t *mesh_upper_transport_pdu){
1345     UNUSED(mesh_upper_transport_pdu);
1346 };
1347 #endif
1348 #elif defined(HAVE_MALLOC)
1349 
1350 typedef struct {
1351     btstack_memory_buffer_t tracking;
1352     mesh_upper_transport_pdu_t data;
1353 } btstack_memory_mesh_upper_transport_pdu_t;
1354 
1355 mesh_upper_transport_pdu_t * btstack_memory_mesh_upper_transport_pdu_get(void){
1356     btstack_memory_mesh_upper_transport_pdu_t * buffer = (btstack_memory_mesh_upper_transport_pdu_t *) malloc(sizeof(btstack_memory_mesh_upper_transport_pdu_t));
1357     if (buffer){
1358         memset(buffer, 0, sizeof(btstack_memory_mesh_upper_transport_pdu_t));
1359         btstack_memory_tracking_add(&buffer->tracking);
1360         return &buffer->data;
1361     } else {
1362         return NULL;
1363     }
1364 }
1365 void btstack_memory_mesh_upper_transport_pdu_free(mesh_upper_transport_pdu_t *mesh_upper_transport_pdu){
1366     // reconstruct buffer start
1367     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) mesh_upper_transport_pdu)[-1];
1368     btstack_memory_tracking_remove(buffer);
1369     free(buffer);
1370 }
1371 #endif
1372 
1373 
1374 // MARK: mesh_network_key_t
1375 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_MESH_NETWORK_KEYS)
1376     #if defined(MAX_NO_MESH_NETWORK_KEYS)
1377         #error "Deprecated MAX_NO_MESH_NETWORK_KEYS defined instead of MAX_NR_MESH_NETWORK_KEYS. Please update your btstack_config.h to use MAX_NR_MESH_NETWORK_KEYS."
1378     #else
1379         #define MAX_NR_MESH_NETWORK_KEYS 0
1380     #endif
1381 #endif
1382 
1383 #ifdef MAX_NR_MESH_NETWORK_KEYS
1384 #if MAX_NR_MESH_NETWORK_KEYS > 0
1385 static mesh_network_key_t mesh_network_key_storage[MAX_NR_MESH_NETWORK_KEYS];
1386 static btstack_memory_pool_t mesh_network_key_pool;
1387 mesh_network_key_t * btstack_memory_mesh_network_key_get(void){
1388     void * buffer = btstack_memory_pool_get(&mesh_network_key_pool);
1389     if (buffer){
1390         memset(buffer, 0, sizeof(mesh_network_key_t));
1391     }
1392     return (mesh_network_key_t *) buffer;
1393 }
1394 void btstack_memory_mesh_network_key_free(mesh_network_key_t *mesh_network_key){
1395     btstack_memory_pool_free(&mesh_network_key_pool, mesh_network_key);
1396 }
1397 #else
1398 mesh_network_key_t * btstack_memory_mesh_network_key_get(void){
1399     return NULL;
1400 }
1401 void btstack_memory_mesh_network_key_free(mesh_network_key_t *mesh_network_key){
1402     UNUSED(mesh_network_key);
1403 };
1404 #endif
1405 #elif defined(HAVE_MALLOC)
1406 
1407 typedef struct {
1408     btstack_memory_buffer_t tracking;
1409     mesh_network_key_t data;
1410 } btstack_memory_mesh_network_key_t;
1411 
1412 mesh_network_key_t * btstack_memory_mesh_network_key_get(void){
1413     btstack_memory_mesh_network_key_t * buffer = (btstack_memory_mesh_network_key_t *) malloc(sizeof(btstack_memory_mesh_network_key_t));
1414     if (buffer){
1415         memset(buffer, 0, sizeof(btstack_memory_mesh_network_key_t));
1416         btstack_memory_tracking_add(&buffer->tracking);
1417         return &buffer->data;
1418     } else {
1419         return NULL;
1420     }
1421 }
1422 void btstack_memory_mesh_network_key_free(mesh_network_key_t *mesh_network_key){
1423     // reconstruct buffer start
1424     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) mesh_network_key)[-1];
1425     btstack_memory_tracking_remove(buffer);
1426     free(buffer);
1427 }
1428 #endif
1429 
1430 
1431 // MARK: mesh_transport_key_t
1432 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_MESH_TRANSPORT_KEYS)
1433     #if defined(MAX_NO_MESH_TRANSPORT_KEYS)
1434         #error "Deprecated MAX_NO_MESH_TRANSPORT_KEYS defined instead of MAX_NR_MESH_TRANSPORT_KEYS. Please update your btstack_config.h to use MAX_NR_MESH_TRANSPORT_KEYS."
1435     #else
1436         #define MAX_NR_MESH_TRANSPORT_KEYS 0
1437     #endif
1438 #endif
1439 
1440 #ifdef MAX_NR_MESH_TRANSPORT_KEYS
1441 #if MAX_NR_MESH_TRANSPORT_KEYS > 0
1442 static mesh_transport_key_t mesh_transport_key_storage[MAX_NR_MESH_TRANSPORT_KEYS];
1443 static btstack_memory_pool_t mesh_transport_key_pool;
1444 mesh_transport_key_t * btstack_memory_mesh_transport_key_get(void){
1445     void * buffer = btstack_memory_pool_get(&mesh_transport_key_pool);
1446     if (buffer){
1447         memset(buffer, 0, sizeof(mesh_transport_key_t));
1448     }
1449     return (mesh_transport_key_t *) buffer;
1450 }
1451 void btstack_memory_mesh_transport_key_free(mesh_transport_key_t *mesh_transport_key){
1452     btstack_memory_pool_free(&mesh_transport_key_pool, mesh_transport_key);
1453 }
1454 #else
1455 mesh_transport_key_t * btstack_memory_mesh_transport_key_get(void){
1456     return NULL;
1457 }
1458 void btstack_memory_mesh_transport_key_free(mesh_transport_key_t *mesh_transport_key){
1459     UNUSED(mesh_transport_key);
1460 };
1461 #endif
1462 #elif defined(HAVE_MALLOC)
1463 
1464 typedef struct {
1465     btstack_memory_buffer_t tracking;
1466     mesh_transport_key_t data;
1467 } btstack_memory_mesh_transport_key_t;
1468 
1469 mesh_transport_key_t * btstack_memory_mesh_transport_key_get(void){
1470     btstack_memory_mesh_transport_key_t * buffer = (btstack_memory_mesh_transport_key_t *) malloc(sizeof(btstack_memory_mesh_transport_key_t));
1471     if (buffer){
1472         memset(buffer, 0, sizeof(btstack_memory_mesh_transport_key_t));
1473         btstack_memory_tracking_add(&buffer->tracking);
1474         return &buffer->data;
1475     } else {
1476         return NULL;
1477     }
1478 }
1479 void btstack_memory_mesh_transport_key_free(mesh_transport_key_t *mesh_transport_key){
1480     // reconstruct buffer start
1481     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) mesh_transport_key)[-1];
1482     btstack_memory_tracking_remove(buffer);
1483     free(buffer);
1484 }
1485 #endif
1486 
1487 
1488 // MARK: mesh_virtual_address_t
1489 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_MESH_VIRTUAL_ADDRESSS)
1490     #if defined(MAX_NO_MESH_VIRTUAL_ADDRESSS)
1491         #error "Deprecated MAX_NO_MESH_VIRTUAL_ADDRESSS defined instead of MAX_NR_MESH_VIRTUAL_ADDRESSS. Please update your btstack_config.h to use MAX_NR_MESH_VIRTUAL_ADDRESSS."
1492     #else
1493         #define MAX_NR_MESH_VIRTUAL_ADDRESSS 0
1494     #endif
1495 #endif
1496 
1497 #ifdef MAX_NR_MESH_VIRTUAL_ADDRESSS
1498 #if MAX_NR_MESH_VIRTUAL_ADDRESSS > 0
1499 static mesh_virtual_address_t mesh_virtual_address_storage[MAX_NR_MESH_VIRTUAL_ADDRESSS];
1500 static btstack_memory_pool_t mesh_virtual_address_pool;
1501 mesh_virtual_address_t * btstack_memory_mesh_virtual_address_get(void){
1502     void * buffer = btstack_memory_pool_get(&mesh_virtual_address_pool);
1503     if (buffer){
1504         memset(buffer, 0, sizeof(mesh_virtual_address_t));
1505     }
1506     return (mesh_virtual_address_t *) buffer;
1507 }
1508 void btstack_memory_mesh_virtual_address_free(mesh_virtual_address_t *mesh_virtual_address){
1509     btstack_memory_pool_free(&mesh_virtual_address_pool, mesh_virtual_address);
1510 }
1511 #else
1512 mesh_virtual_address_t * btstack_memory_mesh_virtual_address_get(void){
1513     return NULL;
1514 }
1515 void btstack_memory_mesh_virtual_address_free(mesh_virtual_address_t *mesh_virtual_address){
1516     UNUSED(mesh_virtual_address);
1517 };
1518 #endif
1519 #elif defined(HAVE_MALLOC)
1520 
1521 typedef struct {
1522     btstack_memory_buffer_t tracking;
1523     mesh_virtual_address_t data;
1524 } btstack_memory_mesh_virtual_address_t;
1525 
1526 mesh_virtual_address_t * btstack_memory_mesh_virtual_address_get(void){
1527     btstack_memory_mesh_virtual_address_t * buffer = (btstack_memory_mesh_virtual_address_t *) malloc(sizeof(btstack_memory_mesh_virtual_address_t));
1528     if (buffer){
1529         memset(buffer, 0, sizeof(btstack_memory_mesh_virtual_address_t));
1530         btstack_memory_tracking_add(&buffer->tracking);
1531         return &buffer->data;
1532     } else {
1533         return NULL;
1534     }
1535 }
1536 void btstack_memory_mesh_virtual_address_free(mesh_virtual_address_t *mesh_virtual_address){
1537     // reconstruct buffer start
1538     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) mesh_virtual_address)[-1];
1539     btstack_memory_tracking_remove(buffer);
1540     free(buffer);
1541 }
1542 #endif
1543 
1544 
1545 // MARK: mesh_subnet_t
1546 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_MESH_SUBNETS)
1547     #if defined(MAX_NO_MESH_SUBNETS)
1548         #error "Deprecated MAX_NO_MESH_SUBNETS defined instead of MAX_NR_MESH_SUBNETS. Please update your btstack_config.h to use MAX_NR_MESH_SUBNETS."
1549     #else
1550         #define MAX_NR_MESH_SUBNETS 0
1551     #endif
1552 #endif
1553 
1554 #ifdef MAX_NR_MESH_SUBNETS
1555 #if MAX_NR_MESH_SUBNETS > 0
1556 static mesh_subnet_t mesh_subnet_storage[MAX_NR_MESH_SUBNETS];
1557 static btstack_memory_pool_t mesh_subnet_pool;
1558 mesh_subnet_t * btstack_memory_mesh_subnet_get(void){
1559     void * buffer = btstack_memory_pool_get(&mesh_subnet_pool);
1560     if (buffer){
1561         memset(buffer, 0, sizeof(mesh_subnet_t));
1562     }
1563     return (mesh_subnet_t *) buffer;
1564 }
1565 void btstack_memory_mesh_subnet_free(mesh_subnet_t *mesh_subnet){
1566     btstack_memory_pool_free(&mesh_subnet_pool, mesh_subnet);
1567 }
1568 #else
1569 mesh_subnet_t * btstack_memory_mesh_subnet_get(void){
1570     return NULL;
1571 }
1572 void btstack_memory_mesh_subnet_free(mesh_subnet_t *mesh_subnet){
1573     UNUSED(mesh_subnet);
1574 };
1575 #endif
1576 #elif defined(HAVE_MALLOC)
1577 
1578 typedef struct {
1579     btstack_memory_buffer_t tracking;
1580     mesh_subnet_t data;
1581 } btstack_memory_mesh_subnet_t;
1582 
1583 mesh_subnet_t * btstack_memory_mesh_subnet_get(void){
1584     btstack_memory_mesh_subnet_t * buffer = (btstack_memory_mesh_subnet_t *) malloc(sizeof(btstack_memory_mesh_subnet_t));
1585     if (buffer){
1586         memset(buffer, 0, sizeof(btstack_memory_mesh_subnet_t));
1587         btstack_memory_tracking_add(&buffer->tracking);
1588         return &buffer->data;
1589     } else {
1590         return NULL;
1591     }
1592 }
1593 void btstack_memory_mesh_subnet_free(mesh_subnet_t *mesh_subnet){
1594     // reconstruct buffer start
1595     btstack_memory_buffer_t * buffer = &((btstack_memory_buffer_t *) mesh_subnet)[-1];
1596     btstack_memory_tracking_remove(buffer);
1597     free(buffer);
1598 }
1599 #endif
1600 
1601 
1602 #endif
1603 
1604 // init
1605 void btstack_memory_init(void){
1606 #ifdef HAVE_MALLOC
1607     // assert that there is no unexpected padding for combined buffer
1608     btstack_assert(sizeof(test_buffer_t) == sizeof(btstack_memory_buffer_t) + sizeof(void *));
1609 #endif
1610 
1611 #if MAX_NR_HCI_CONNECTIONS > 0
1612     btstack_memory_pool_create(&hci_connection_pool, hci_connection_storage, MAX_NR_HCI_CONNECTIONS, sizeof(hci_connection_t));
1613 #endif
1614 #if MAX_NR_L2CAP_SERVICES > 0
1615     btstack_memory_pool_create(&l2cap_service_pool, l2cap_service_storage, MAX_NR_L2CAP_SERVICES, sizeof(l2cap_service_t));
1616 #endif
1617 #if MAX_NR_L2CAP_CHANNELS > 0
1618     btstack_memory_pool_create(&l2cap_channel_pool, l2cap_channel_storage, MAX_NR_L2CAP_CHANNELS, sizeof(l2cap_channel_t));
1619 #endif
1620 #ifdef ENABLE_CLASSIC
1621 #if MAX_NR_RFCOMM_MULTIPLEXERS > 0
1622     btstack_memory_pool_create(&rfcomm_multiplexer_pool, rfcomm_multiplexer_storage, MAX_NR_RFCOMM_MULTIPLEXERS, sizeof(rfcomm_multiplexer_t));
1623 #endif
1624 #if MAX_NR_RFCOMM_SERVICES > 0
1625     btstack_memory_pool_create(&rfcomm_service_pool, rfcomm_service_storage, MAX_NR_RFCOMM_SERVICES, sizeof(rfcomm_service_t));
1626 #endif
1627 #if MAX_NR_RFCOMM_CHANNELS > 0
1628     btstack_memory_pool_create(&rfcomm_channel_pool, rfcomm_channel_storage, MAX_NR_RFCOMM_CHANNELS, sizeof(rfcomm_channel_t));
1629 #endif
1630 #if MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES > 0
1631     btstack_memory_pool_create(&btstack_link_key_db_memory_entry_pool, btstack_link_key_db_memory_entry_storage, MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES, sizeof(btstack_link_key_db_memory_entry_t));
1632 #endif
1633 #if MAX_NR_BNEP_SERVICES > 0
1634     btstack_memory_pool_create(&bnep_service_pool, bnep_service_storage, MAX_NR_BNEP_SERVICES, sizeof(bnep_service_t));
1635 #endif
1636 #if MAX_NR_BNEP_CHANNELS > 0
1637     btstack_memory_pool_create(&bnep_channel_pool, bnep_channel_storage, MAX_NR_BNEP_CHANNELS, sizeof(bnep_channel_t));
1638 #endif
1639 #if MAX_NR_HFP_CONNECTIONS > 0
1640     btstack_memory_pool_create(&hfp_connection_pool, hfp_connection_storage, MAX_NR_HFP_CONNECTIONS, sizeof(hfp_connection_t));
1641 #endif
1642 #if MAX_NR_HID_HOST_CONNECTIONS > 0
1643     btstack_memory_pool_create(&hid_host_connection_pool, hid_host_connection_storage, MAX_NR_HID_HOST_CONNECTIONS, sizeof(hid_host_connection_t));
1644 #endif
1645 #if MAX_NR_SERVICE_RECORD_ITEMS > 0
1646     btstack_memory_pool_create(&service_record_item_pool, service_record_item_storage, MAX_NR_SERVICE_RECORD_ITEMS, sizeof(service_record_item_t));
1647 #endif
1648 #if MAX_NR_AVDTP_STREAM_ENDPOINTS > 0
1649     btstack_memory_pool_create(&avdtp_stream_endpoint_pool, avdtp_stream_endpoint_storage, MAX_NR_AVDTP_STREAM_ENDPOINTS, sizeof(avdtp_stream_endpoint_t));
1650 #endif
1651 #if MAX_NR_AVDTP_CONNECTIONS > 0
1652     btstack_memory_pool_create(&avdtp_connection_pool, avdtp_connection_storage, MAX_NR_AVDTP_CONNECTIONS, sizeof(avdtp_connection_t));
1653 #endif
1654 #if MAX_NR_AVRCP_CONNECTIONS > 0
1655     btstack_memory_pool_create(&avrcp_connection_pool, avrcp_connection_storage, MAX_NR_AVRCP_CONNECTIONS, sizeof(avrcp_connection_t));
1656 #endif
1657 #if MAX_NR_AVRCP_BROWSING_CONNECTIONS > 0
1658     btstack_memory_pool_create(&avrcp_browsing_connection_pool, avrcp_browsing_connection_storage, MAX_NR_AVRCP_BROWSING_CONNECTIONS, sizeof(avrcp_browsing_connection_t));
1659 #endif
1660 #endif
1661 #ifdef ENABLE_BLE
1662 #if MAX_NR_GATT_CLIENTS > 0
1663     btstack_memory_pool_create(&gatt_client_pool, gatt_client_storage, MAX_NR_GATT_CLIENTS, sizeof(gatt_client_t));
1664 #endif
1665 #if MAX_NR_WHITELIST_ENTRIES > 0
1666     btstack_memory_pool_create(&whitelist_entry_pool, whitelist_entry_storage, MAX_NR_WHITELIST_ENTRIES, sizeof(whitelist_entry_t));
1667 #endif
1668 #if MAX_NR_SM_LOOKUP_ENTRIES > 0
1669     btstack_memory_pool_create(&sm_lookup_entry_pool, sm_lookup_entry_storage, MAX_NR_SM_LOOKUP_ENTRIES, sizeof(sm_lookup_entry_t));
1670 #endif
1671 #endif
1672 #ifdef ENABLE_MESH
1673 #if MAX_NR_MESH_NETWORK_PDUS > 0
1674     btstack_memory_pool_create(&mesh_network_pdu_pool, mesh_network_pdu_storage, MAX_NR_MESH_NETWORK_PDUS, sizeof(mesh_network_pdu_t));
1675 #endif
1676 #if MAX_NR_MESH_SEGMENTED_PDUS > 0
1677     btstack_memory_pool_create(&mesh_segmented_pdu_pool, mesh_segmented_pdu_storage, MAX_NR_MESH_SEGMENTED_PDUS, sizeof(mesh_segmented_pdu_t));
1678 #endif
1679 #if MAX_NR_MESH_UPPER_TRANSPORT_PDUS > 0
1680     btstack_memory_pool_create(&mesh_upper_transport_pdu_pool, mesh_upper_transport_pdu_storage, MAX_NR_MESH_UPPER_TRANSPORT_PDUS, sizeof(mesh_upper_transport_pdu_t));
1681 #endif
1682 #if MAX_NR_MESH_NETWORK_KEYS > 0
1683     btstack_memory_pool_create(&mesh_network_key_pool, mesh_network_key_storage, MAX_NR_MESH_NETWORK_KEYS, sizeof(mesh_network_key_t));
1684 #endif
1685 #if MAX_NR_MESH_TRANSPORT_KEYS > 0
1686     btstack_memory_pool_create(&mesh_transport_key_pool, mesh_transport_key_storage, MAX_NR_MESH_TRANSPORT_KEYS, sizeof(mesh_transport_key_t));
1687 #endif
1688 #if MAX_NR_MESH_VIRTUAL_ADDRESSS > 0
1689     btstack_memory_pool_create(&mesh_virtual_address_pool, mesh_virtual_address_storage, MAX_NR_MESH_VIRTUAL_ADDRESSS, sizeof(mesh_virtual_address_t));
1690 #endif
1691 #if MAX_NR_MESH_SUBNETS > 0
1692     btstack_memory_pool_create(&mesh_subnet_pool, mesh_subnet_storage, MAX_NR_MESH_SUBNETS, sizeof(mesh_subnet_t));
1693 #endif
1694 #endif
1695 }
1696