diff --git a/src/Makefile.in b/src/Makefile.in index 5fa4af2c0..49f9a3fe5 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -16,6 +16,7 @@ libBTstack_SOURCES = btstack.c hci_cmds.c linked_list.c run_loop.c $(run_loop_so BTdaemon_SOURCES = $(libBTstack_SOURCES) \ $(platform_sources) \ + btstack_memory.c \ daemon.c \ hci.c \ hci_dump.c \ diff --git a/src/btstack_memory.c b/src/btstack_memory.c new file mode 100644 index 000000000..51be1f506 --- /dev/null +++ b/src/btstack_memory.c @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2011 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * btstsack_memory.h + * + * @brief BTstack memory management via configurable memory pools + * + * @note code semi-atuomatically generated by btstack_memory_generate.py + * + */ + +#include "btstack_memory.h" +#include + +#include + +#include "../config.h" +#include "hci.h" +#include "l2cap.h" +#include "rfcomm.h" + +// MARK: hci_connection_t +#ifdef MAX_NO_HCI_CONNECTIONS +static hci_connection_t hci_connection_storage[MAX_NO_HCI_CONNECTIONS]; +static memory_pool_t hci_connection_pool; +void * btstack_memory_hci_connection_get(void){ + return memory_pool_get(&hci_connection_pool); +} +void btstack_memory_hci_connection_free(void *hci_connection){ + memory_pool_free(&hci_connection_pool, hci_connection); +} +#elif defined(HAVE_MALLOC) +void * btstack_memory_hci_connection_get(void){ + return malloc(sizeof(hci_connection_t)); +} +void btstack_memory_hci_connection_free(void *hci_connection){ + free(hci_connection); +} +#else +#error BTstack needs at least one hci_connection_t, but neither MAX_NO_HCI_CONNECTIONS nor HAVE_MALLOC are defined +#endif + + +// MARK: l2cap_service_t +#ifdef MAX_NO_L2CAP_SERVICES +static l2cap_service_t l2cap_service_storage[MAX_NO_L2CAP_SERVICES]; +static memory_pool_t l2cap_service_pool; +void * btstack_memory_l2cap_service_get(void){ + return memory_pool_get(&l2cap_service_pool); +} +void btstack_memory_l2cap_service_free(void *l2cap_service){ + memory_pool_free(&l2cap_service_pool, l2cap_service); +} +#elif defined(HAVE_MALLOC) +void * btstack_memory_l2cap_service_get(void){ + return malloc(sizeof(l2cap_service_t)); +} +void btstack_memory_l2cap_service_free(void *l2cap_service){ + free(l2cap_service); +} +#else +#error BTstack needs at least one l2cap_service_t, but neither MAX_NO_L2CAP_SERVICES nor HAVE_MALLOC are defined +#endif + + +// MARK: l2cap_channel_t +#ifdef MAX_NO_L2CAP_CHANNELS +static l2cap_channel_t l2cap_channel_storage[MAX_NO_L2CAP_CHANNELS]; +static memory_pool_t l2cap_channel_pool; +void * btstack_memory_l2cap_channel_get(void){ + return memory_pool_get(&l2cap_channel_pool); +} +void btstack_memory_l2cap_channel_free(void *l2cap_channel){ + memory_pool_free(&l2cap_channel_pool, l2cap_channel); +} +#elif defined(HAVE_MALLOC) +void * btstack_memory_l2cap_channel_get(void){ + return malloc(sizeof(l2cap_channel_t)); +} +void btstack_memory_l2cap_channel_free(void *l2cap_channel){ + free(l2cap_channel); +} +#else +#error BTstack needs at least one l2cap_channel_t, but neither MAX_NO_L2CAP_CHANNELS nor HAVE_MALLOC are defined +#endif + + +// MARK: rfcomm_multiplexer_t +#ifdef MAX_NO_RFCOMM_MULTIPLEXERS +static rfcomm_multiplexer_t rfcomm_multiplexer_storage[MAX_NO_RFCOMM_MULTIPLEXERS]; +static memory_pool_t rfcomm_multiplexer_pool; +void * btstack_memory_rfcomm_multiplexer_get(void){ + return memory_pool_get(&rfcomm_multiplexer_pool); +} +void btstack_memory_rfcomm_multiplexer_free(void *rfcomm_multiplexer){ + memory_pool_free(&rfcomm_multiplexer_pool, rfcomm_multiplexer); +} +#elif defined(HAVE_MALLOC) +void * btstack_memory_rfcomm_multiplexer_get(void){ + return malloc(sizeof(rfcomm_multiplexer_t)); +} +void btstack_memory_rfcomm_multiplexer_free(void *rfcomm_multiplexer){ + free(rfcomm_multiplexer); +} +#else +#error BTstack needs at least one rfcomm_multiplexer_t, but neither MAX_NO_RFCOMM_MULTIPLEXERS nor HAVE_MALLOC are defined +#endif + + +// MARK: rfcomm_service_t +#ifdef MAX_NO_RFCOMM_SERVICES +static rfcomm_service_t rfcomm_service_storage[MAX_NO_RFCOMM_SERVICES]; +static memory_pool_t rfcomm_service_pool; +void * btstack_memory_rfcomm_service_get(void){ + return memory_pool_get(&rfcomm_service_pool); +} +void btstack_memory_rfcomm_service_free(void *rfcomm_service){ + memory_pool_free(&rfcomm_service_pool, rfcomm_service); +} +#elif defined(HAVE_MALLOC) +void * btstack_memory_rfcomm_service_get(void){ + return malloc(sizeof(rfcomm_service_t)); +} +void btstack_memory_rfcomm_service_free(void *rfcomm_service){ + free(rfcomm_service); +} +#else +#error BTstack needs at least one rfcomm_service_t, but neither MAX_NO_RFCOMM_SERVICES nor HAVE_MALLOC are defined +#endif + + +// MARK: rfcomm_channel_t +#ifdef MAX_NO_RFCOMM_CHANNELS +static rfcomm_channel_t rfcomm_channel_storage[MAX_NO_RFCOMM_CHANNELS]; +static memory_pool_t rfcomm_channel_pool; +void * btstack_memory_rfcomm_channel_get(void){ + return memory_pool_get(&rfcomm_channel_pool); +} +void btstack_memory_rfcomm_channel_free(void *rfcomm_channel){ + memory_pool_free(&rfcomm_channel_pool, rfcomm_channel); +} +#elif defined(HAVE_MALLOC) +void * btstack_memory_rfcomm_channel_get(void){ + return malloc(sizeof(rfcomm_channel_t)); +} +void btstack_memory_rfcomm_channel_free(void *rfcomm_channel){ + free(rfcomm_channel); +} +#else +#error BTstack needs at least one rfcomm_channel_t, but neither MAX_NO_RFCOMM_CHANNELS nor HAVE_MALLOC are defined +#endif + +// init +void btstack_memory_init(void){ +#ifdef MAX_NO_HCI_CONNECTIONS + memory_pool_create(&hci_connection_pool, hci_connection_storage, MAX_NO_HCI_CONNECTIONS, sizeof(hci_connection_t)); +#endif +#ifdef MAX_NO_L2CAP_SERVICES + memory_pool_create(&l2cap_service_pool, l2cap_service_storage, MAX_NO_L2CAP_SERVICES, sizeof(l2cap_service_t)); +#endif +#ifdef MAX_NO_L2CAP_CHANNELS + memory_pool_create(&l2cap_channel_pool, l2cap_channel_storage, MAX_NO_L2CAP_CHANNELS, sizeof(l2cap_channel_t)); +#endif +#ifdef MAX_NO_RFCOMM_MULTIPLEXERS + memory_pool_create(&rfcomm_multiplexer_pool, rfcomm_multiplexer_storage, MAX_NO_RFCOMM_MULTIPLEXERS, sizeof(rfcomm_multiplexer_t)); +#endif +#ifdef MAX_NO_RFCOMM_SERVICES + memory_pool_create(&rfcomm_service_pool, rfcomm_service_storage, MAX_NO_RFCOMM_SERVICES, sizeof(rfcomm_service_t)); +#endif +#ifdef MAX_NO_RFCOMM_CHANNELS + memory_pool_create(&rfcomm_channel_pool, rfcomm_channel_storage, MAX_NO_RFCOMM_CHANNELS, sizeof(rfcomm_channel_t)); +#endif +} diff --git a/src/btstack_memory.h b/src/btstack_memory.h new file mode 100644 index 000000000..025cb288d --- /dev/null +++ b/src/btstack_memory.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * btstsack_memory.h + * + * @brief BTstack memory management via configurable memory pools + * + */ + +#pragma once + +void btstack_memory_init(void); + +void * btstack_memory_hci_connection_get(void); +void btstack_memory_hci_connection_free(void *hci_connection); +void * btstack_memory_l2cap_service_get(void); +void btstack_memory_l2cap_service_free(void *l2cap_service); +void * btstack_memory_l2cap_channel_get(void); +void btstack_memory_l2cap_channel_free(void *l2cap_channel); +void * btstack_memory_rfcomm_multiplexer_get(void); +void btstack_memory_rfcomm_multiplexer_free(void *rfcomm_multiplexer); +void * btstack_memory_rfcomm_service_get(void); +void btstack_memory_rfcomm_service_free(void *rfcomm_service); +void * btstack_memory_rfcomm_channel_get(void); +void btstack_memory_rfcomm_channel_free(void *rfcomm_channel); + diff --git a/src/hci.c b/src/hci.c index 0e9780848..97b1b5f00 100644 --- a/src/hci.c +++ b/src/hci.c @@ -46,13 +46,14 @@ #include // gethostbyname #endif +#include "btstack_memory.h" #include "debug.h" #include "hci_dump.h" #include #include -// temp +// tmpe #include "l2cap.h" #define HCI_CONNECTION_TIMEOUT_MS 10000 @@ -104,7 +105,7 @@ static void hci_connection_timestamp(hci_connection_t *connection){ * @return connection OR NULL, if not found */ static hci_connection_t * create_connection_for_addr(bd_addr_t addr){ - hci_connection_t * conn = malloc( sizeof(hci_connection_t) ); + hci_connection_t * conn = btstack_memory_hci_connection_get(); if (!conn) return NULL; BD_ADDR_COPY(conn->address, addr); conn->con_handle = 0xffff; @@ -343,7 +344,7 @@ static void hci_shutdown_connection(hci_connection_t *conn){ run_loop_remove_timer(&conn->timeout); #endif linked_list_remove(&hci_stack.connections, (linked_item_t *) conn); - free( conn ); + btstack_memory_hci_connection_free( conn ); // now it's gone hci_emit_nr_connections_changed(); @@ -443,7 +444,7 @@ static void event_handler(uint8_t *packet, int size){ } else { // connection failed, remove entry linked_list_remove(&hci_stack.connections, (linked_item_t *) conn); - free( conn ); + btstack_memory_hci_connection_free( conn ); // if authentication error, also delete link key if (packet[2] == 0x05) {