182636622SMatthias Ringwald /* 282636622SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 382636622SMatthias Ringwald * 482636622SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 582636622SMatthias Ringwald * modification, are permitted provided that the following conditions 682636622SMatthias Ringwald * are met: 782636622SMatthias Ringwald * 882636622SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 982636622SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 1082636622SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 1182636622SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 1282636622SMatthias Ringwald * documentation and/or other materials provided with the distribution. 1382636622SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 1482636622SMatthias Ringwald * contributors may be used to endorse or promote products derived 1582636622SMatthias Ringwald * from this software without specific prior written permission. 1682636622SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 1782636622SMatthias Ringwald * personal benefit and not for any commercial purpose or for 1882636622SMatthias Ringwald * monetary gain. 1982636622SMatthias Ringwald * 2082636622SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 2182636622SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2282636622SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 2382636622SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 2482636622SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2582636622SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2682636622SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 2782636622SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2882636622SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2982636622SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 3082636622SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3182636622SMatthias Ringwald * SUCH DAMAGE. 3282636622SMatthias Ringwald * 3382636622SMatthias Ringwald * Please inquire about commercial licensing options at 3482636622SMatthias Ringwald * [email protected] 3582636622SMatthias Ringwald * 3682636622SMatthias Ringwald */ 3782636622SMatthias Ringwald 38fe5a6c4eSMilanka Ringwald /** 399fb44c6dSMatthias Ringwald * BTstack Run Loop Abstraction 4082636622SMatthias Ringwald * 419fb44c6dSMatthias Ringwald * Provides generic functionality required by the Bluetooth stack and example applications: 429fb44c6dSMatthias Ringwald * - asynchronous IO for various devices Serial, USB, network sockets, console 439fb44c6dSMatthias Ringwald * - system time in milliseconds 449fb44c6dSMatthias Ringwald * - single shot timers 459fb44c6dSMatthias Ringwald * - integration for threaded environments 4682636622SMatthias Ringwald */ 4782636622SMatthias Ringwald 489fb44c6dSMatthias Ringwald #ifndef BTSTACK_RUN_LOOP_H 499fb44c6dSMatthias Ringwald #define BTSTACK_RUN_LOOP_H 5082636622SMatthias Ringwald 517907f069SMatthias Ringwald #include "btstack_config.h" 5282636622SMatthias Ringwald 53d58a1b5fSMatthias Ringwald #include "btstack_bool.h" 5482636622SMatthias Ringwald #include "btstack_linked_list.h" 559fb44c6dSMatthias Ringwald #include "btstack_defines.h" 5682636622SMatthias Ringwald 5782636622SMatthias Ringwald #include <stdint.h> 5882636622SMatthias Ringwald 5982636622SMatthias Ringwald #if defined __cplusplus 6082636622SMatthias Ringwald extern "C" { 6182636622SMatthias Ringwald #endif 6282636622SMatthias Ringwald 637cd5ef95SMatthias Ringwald /** 647cd5ef95SMatthias Ringwald * Callback types for run loop data sources 657cd5ef95SMatthias Ringwald */ 667cd5ef95SMatthias Ringwald typedef enum { 677cd5ef95SMatthias Ringwald DATA_SOURCE_CALLBACK_POLL = 1 << 0, 687cd5ef95SMatthias Ringwald DATA_SOURCE_CALLBACK_READ = 1 << 1, 697cd5ef95SMatthias Ringwald DATA_SOURCE_CALLBACK_WRITE = 1 << 2, 707cd5ef95SMatthias Ringwald } btstack_data_source_callback_type_t; 717cd5ef95SMatthias Ringwald 72ec820d77SMatthias Ringwald typedef struct btstack_data_source { 733aad8623SMatthias Ringwald // linked item 7482636622SMatthias Ringwald btstack_linked_item_t item; 753aad8623SMatthias Ringwald 763aad8623SMatthias Ringwald // item to watch in run loop 773aad8623SMatthias Ringwald union { 783aad8623SMatthias Ringwald // file descriptor for posix systems 795ed06181SMatthias Ringwald int fd; 803aad8623SMatthias Ringwald // handle on windows 813aad8623SMatthias Ringwald void * handle; 82398a95ecSMatthias Ringwald } source; 833aad8623SMatthias Ringwald 845ed06181SMatthias Ringwald // callback to call for enabled callback types 857cd5ef95SMatthias Ringwald void (*process)(struct btstack_data_source *ds, btstack_data_source_callback_type_t callback_type); 863aad8623SMatthias Ringwald 875ed06181SMatthias Ringwald // flags storing enabled callback types 885ed06181SMatthias Ringwald uint16_t flags; 893aad8623SMatthias Ringwald 90ec820d77SMatthias Ringwald } btstack_data_source_t; 9182636622SMatthias Ringwald 92eb886013SMatthias Ringwald typedef struct btstack_timer_source { 9382636622SMatthias Ringwald btstack_linked_item_t item; 94f316a845SMatthias Ringwald // timeout in system ticks (HAVE_EMBEDDED_TICK) or milliseconds (HAVE_EMBEDDED_TIME_MS) 95f316a845SMatthias Ringwald uint32_t timeout; 96fd939756SMatthias Ringwald // will be called when timer fired 97fd939756SMatthias Ringwald void (*process)(struct btstack_timer_source *ts); 98fd939756SMatthias Ringwald void * context; 99ec820d77SMatthias Ringwald } btstack_timer_source_t; 10082636622SMatthias Ringwald 101ec820d77SMatthias Ringwald typedef struct btstack_run_loop { 10282636622SMatthias Ringwald void (*init)(void); 1030d70dd62SMatthias Ringwald void (*add_data_source)(btstack_data_source_t * data_source); 104d58a1b5fSMatthias Ringwald bool (*remove_data_source)(btstack_data_source_t * data_source); 1050d70dd62SMatthias Ringwald void (*enable_data_source_callbacks)(btstack_data_source_t * data_source, uint16_t callbacks); 1060d70dd62SMatthias Ringwald void (*disable_data_source_callbacks)(btstack_data_source_t * data_source, uint16_t callbacks); 107ec820d77SMatthias Ringwald void (*set_timer)(btstack_timer_source_t * timer, uint32_t timeout_in_ms); 108ec820d77SMatthias Ringwald void (*add_timer)(btstack_timer_source_t *timer); 109d58a1b5fSMatthias Ringwald bool (*remove_timer)(btstack_timer_source_t *timer); 11082636622SMatthias Ringwald void (*execute)(void); 11182636622SMatthias Ringwald void (*dump_timer)(void); 11282636622SMatthias Ringwald uint32_t (*get_time_ms)(void); 1139fb44c6dSMatthias Ringwald void (*poll_data_sources_from_irq)(void); 1149fb44c6dSMatthias Ringwald void (*execute_on_main_thread)(btstack_context_callback_registration_t * callback_registration); 1159fb44c6dSMatthias Ringwald void (*trigger_exit)(void); 116528a4a3bSMatthias Ringwald } btstack_run_loop_t; 11782636622SMatthias Ringwald 118796f7837SMatthias Ringwald 119796f7837SMatthias Ringwald /* 120796f7837SMatthias Ringwald * BTstack Run Loop Base Implementation 121796f7837SMatthias Ringwald * Portable implementation of timer and data source management as base for platform specific implementations 122796f7837SMatthias Ringwald */ 123796f7837SMatthias Ringwald 124796f7837SMatthias Ringwald // private data (access only by run loop implementations) 125796f7837SMatthias Ringwald extern btstack_linked_list_t btstack_run_loop_base_timers; 126796f7837SMatthias Ringwald extern btstack_linked_list_t btstack_run_loop_base_data_sources; 127*7eaf37e0SMatthias Ringwald extern btstack_linked_list_t btstack_run_loop_base_callbacks; 128796f7837SMatthias Ringwald 129796f7837SMatthias Ringwald /** 130796f7837SMatthias Ringwald * @brief Init 131796f7837SMatthias Ringwald */ 132796f7837SMatthias Ringwald void btstack_run_loop_base_init(void); 133796f7837SMatthias Ringwald 134796f7837SMatthias Ringwald /** 135796f7837SMatthias Ringwald * @brief Add timer source. 136796f7837SMatthias Ringwald * @param timer to add 137796f7837SMatthias Ringwald */ 138796f7837SMatthias Ringwald void btstack_run_loop_base_add_timer(btstack_timer_source_t * timer); 139796f7837SMatthias Ringwald 140796f7837SMatthias Ringwald /** 141796f7837SMatthias Ringwald * @brief Remove timer source. 142796f7837SMatthias Ringwald * @param timer to remove 143796f7837SMatthias Ringwald * @returns true if timer was removed 144796f7837SMatthias Ringwald */ 145796f7837SMatthias Ringwald bool btstack_run_loop_base_remove_timer(btstack_timer_source_t * timer); 146796f7837SMatthias Ringwald 147796f7837SMatthias Ringwald /** 148796f7837SMatthias Ringwald * @brief Process timers: remove expired timers from list and call their process function 149796f7837SMatthias Ringwald * @param now 150796f7837SMatthias Ringwald */ 151796f7837SMatthias Ringwald void btstack_run_loop_base_process_timers(uint32_t now); 152796f7837SMatthias Ringwald 153796f7837SMatthias Ringwald /** 154796f7837SMatthias Ringwald * @brief Dump list of timers via log_info 155796f7837SMatthias Ringwald */ 156796f7837SMatthias Ringwald void btstack_run_loop_base_dump_timer(void); 157796f7837SMatthias Ringwald 158796f7837SMatthias Ringwald /** 159796f7837SMatthias Ringwald * @brief Get time until first timer fires 160796f7837SMatthias Ringwald * @returns -1 if no timers, time until next timeout otherwise 161796f7837SMatthias Ringwald */ 162796f7837SMatthias Ringwald int32_t btstack_run_loop_base_get_time_until_timeout(uint32_t now); 163796f7837SMatthias Ringwald 164796f7837SMatthias Ringwald /** 165796f7837SMatthias Ringwald * @brief Add data source to run loop 166796f7837SMatthias Ringwald * @param data_source to add 167796f7837SMatthias Ringwald */ 168796f7837SMatthias Ringwald void btstack_run_loop_base_add_data_source(btstack_data_source_t * data_source); 169796f7837SMatthias Ringwald 170796f7837SMatthias Ringwald /** 171796f7837SMatthias Ringwald * @brief Remove data source from run loop 172796f7837SMatthias Ringwald * @param data_source to remove 173796f7837SMatthias Ringwald * @returns true if data srouce was removed 174796f7837SMatthias Ringwald */ 175796f7837SMatthias Ringwald bool btstack_run_loop_base_remove_data_source(btstack_data_source_t * data_source); 176796f7837SMatthias Ringwald 177796f7837SMatthias Ringwald /** 178796f7837SMatthias Ringwald * @brief Enable callbacks for a data source 179796f7837SMatthias Ringwald * @param data_source to remove 180b45b7749SMilanka Ringwald * @param callback_types to enable 181796f7837SMatthias Ringwald */ 182b45b7749SMilanka Ringwald void btstack_run_loop_base_enable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callback_types); 183796f7837SMatthias Ringwald 184796f7837SMatthias Ringwald /** 185796f7837SMatthias Ringwald * @brief Enable callbacks for a data source 186796f7837SMatthias Ringwald * @param data_source to remove 187b45b7749SMilanka Ringwald * @param callback_types to disable 188796f7837SMatthias Ringwald */ 189b45b7749SMilanka Ringwald void btstack_run_loop_base_disable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callback_types); 190796f7837SMatthias Ringwald 191796f7837SMatthias Ringwald /** 192796f7837SMatthias Ringwald * @brief Poll data sources. It calls the procss function for all data sources where DATA_SOURCE_CALLBACK_POLL is set 193796f7837SMatthias Ringwald */ 194796f7837SMatthias Ringwald void btstack_run_loop_base_poll_data_sources(void); 195796f7837SMatthias Ringwald 196*7eaf37e0SMatthias Ringwald /** 197*7eaf37e0SMatthias Ringwald * @bried Add Callbacks to list of callbacks to execute with btstack_run_loop_base_execute_callbacks 198*7eaf37e0SMatthias Ringwald */ 199*7eaf37e0SMatthias Ringwald void btstack_run_loop_base_add_callback(btstack_context_callback_registration_t * callback_registration); 200*7eaf37e0SMatthias Ringwald 201*7eaf37e0SMatthias Ringwald /** 202*7eaf37e0SMatthias Ringwald * @bried Procss Callbacks: remove all callback-registrations and call the registered function with its context 203*7eaf37e0SMatthias Ringwald */ 204*7eaf37e0SMatthias Ringwald void btstack_run_loop_base_execute_callbacks(void); 205*7eaf37e0SMatthias Ringwald 20682636622SMatthias Ringwald 20782636622SMatthias Ringwald /* API_START */ 20882636622SMatthias Ringwald 20982636622SMatthias Ringwald /** 21082636622SMatthias Ringwald * @brief Init main run loop. Must be called before any other run loop call. 21182636622SMatthias Ringwald * 212528a4a3bSMatthias Ringwald * Use btstack_run_loop_$(btstack_run_loop_TYPE)_get_instance() from btstack_run_loop_$(btstack_run_loop_TYPE).h to get instance 21382636622SMatthias Ringwald */ 214528a4a3bSMatthias Ringwald void btstack_run_loop_init(const btstack_run_loop_t * run_loop); 21582636622SMatthias Ringwald 21682636622SMatthias Ringwald /** 21782636622SMatthias Ringwald * @brief Set timer based on current time in milliseconds. 21882636622SMatthias Ringwald */ 219b45b7749SMilanka Ringwald void btstack_run_loop_set_timer(btstack_timer_source_t * timer, uint32_t timeout_in_ms); 22082636622SMatthias Ringwald 22182636622SMatthias Ringwald /** 22282636622SMatthias Ringwald * @brief Set callback that will be executed when timer expires. 22382636622SMatthias Ringwald */ 224b45b7749SMilanka Ringwald void btstack_run_loop_set_timer_handler(btstack_timer_source_t * timer, void (*process)(btstack_timer_source_t * _timer)); 22582636622SMatthias Ringwald 22682636622SMatthias Ringwald /** 227fd939756SMatthias Ringwald * @brief Set context for this timer 228fd939756SMatthias Ringwald */ 229b45b7749SMilanka Ringwald void btstack_run_loop_set_timer_context(btstack_timer_source_t * timer, void * context); 230fd939756SMatthias Ringwald 231fd939756SMatthias Ringwald /** 232fd939756SMatthias Ringwald * @brief Get context for this timer 233fd939756SMatthias Ringwald */ 234b45b7749SMilanka Ringwald void * btstack_run_loop_get_timer_context(btstack_timer_source_t * timer); 235fd939756SMatthias Ringwald 236fd939756SMatthias Ringwald /** 237fd939756SMatthias Ringwald * @brief Add timer source. 23882636622SMatthias Ringwald */ 239ec820d77SMatthias Ringwald void btstack_run_loop_add_timer(btstack_timer_source_t * timer); 240fd939756SMatthias Ringwald 241fd939756SMatthias Ringwald /** 242fd939756SMatthias Ringwald * @brief Remove timer source. 243fd939756SMatthias Ringwald */ 244ec820d77SMatthias Ringwald int btstack_run_loop_remove_timer(btstack_timer_source_t * timer); 24582636622SMatthias Ringwald 24682636622SMatthias Ringwald /** 24782636622SMatthias Ringwald * @brief Get current time in ms 24882636622SMatthias Ringwald * @note 32-bit ms counter will overflow after approx. 52 days 24982636622SMatthias Ringwald */ 250528a4a3bSMatthias Ringwald uint32_t btstack_run_loop_get_time_ms(void); 25182636622SMatthias Ringwald 25282636622SMatthias Ringwald /** 253796f7837SMatthias Ringwald * @brief Dump timers using log_info 254796f7837SMatthias Ringwald */ 255796f7837SMatthias Ringwald void btstack_run_loop_timer_dump(void); 256796f7837SMatthias Ringwald 257796f7837SMatthias Ringwald 258796f7837SMatthias Ringwald /** 25982636622SMatthias Ringwald * @brief Set data source callback. 26082636622SMatthias Ringwald */ 261b45b7749SMilanka Ringwald void btstack_run_loop_set_data_source_handler(btstack_data_source_t * data_source, void (*process)(btstack_data_source_t * _data_source, btstack_data_source_callback_type_t callback_type)); 26282636622SMatthias Ringwald 26382636622SMatthias Ringwald /** 2643a5c43eeSMatthias Ringwald * @brief Set data source file descriptor. 265896424b7SMatthias Ringwald * @param data_source 266896424b7SMatthias Ringwald * @param fd file descriptor 2673a5c43eeSMatthias Ringwald * @note No effect if port doensn't have file descriptors 2683a5c43eeSMatthias Ringwald */ 269896424b7SMatthias Ringwald void btstack_run_loop_set_data_source_fd(btstack_data_source_t * data_source, int fd); 2703a5c43eeSMatthias Ringwald 2713a5c43eeSMatthias Ringwald /** 2723a5c43eeSMatthias Ringwald * @brief Get data source file descriptor. 273896424b7SMatthias Ringwald * @param data_source 2743a5c43eeSMatthias Ringwald */ 275896424b7SMatthias Ringwald int btstack_run_loop_get_data_source_fd(btstack_data_source_t * data_source); 2763a5c43eeSMatthias Ringwald 277f04a41aeSMatthias Ringwald /** 278f04a41aeSMatthias Ringwald * @brief Set data source file descriptor. 279f04a41aeSMatthias Ringwald * @param data_source 280f04a41aeSMatthias Ringwald * @param handle 281f04a41aeSMatthias Ringwald * @note No effect if port doensn't have file descriptors 282f04a41aeSMatthias Ringwald */ 283f04a41aeSMatthias Ringwald void btstack_run_loop_set_data_source_handle(btstack_data_source_t * data_source, void * handle); 284f04a41aeSMatthias Ringwald 285f04a41aeSMatthias Ringwald /** 286f04a41aeSMatthias Ringwald * @brief Get data source file descriptor. 287f04a41aeSMatthias Ringwald * @param data_source 288f04a41aeSMatthias Ringwald */ 289f04a41aeSMatthias Ringwald void * btstack_run_loop_get_data_source_handle(btstack_data_source_t * data_source); 290f04a41aeSMatthias Ringwald 2913a5c43eeSMatthias Ringwald /** 292896424b7SMatthias Ringwald * @brief Enable callbacks for a data source 293896424b7SMatthias Ringwald * @param data_source to remove 294896424b7SMatthias Ringwald * @param callback types to enable 29582636622SMatthias Ringwald */ 29624ced5a6SMatthias Ringwald void btstack_run_loop_enable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks); 297896424b7SMatthias Ringwald 298896424b7SMatthias Ringwald /** 299896424b7SMatthias Ringwald * @brief Enable callbacks for a data source 300896424b7SMatthias Ringwald * @param data_source to remove 301896424b7SMatthias Ringwald * @param callback types to disable 302896424b7SMatthias Ringwald */ 30324ced5a6SMatthias Ringwald void btstack_run_loop_disable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks); 304896424b7SMatthias Ringwald 305896424b7SMatthias Ringwald /** 306896424b7SMatthias Ringwald * @brief Add data source to run loop 307896424b7SMatthias Ringwald * @param data_source to add 308896424b7SMatthias Ringwald */ 309896424b7SMatthias Ringwald void btstack_run_loop_add_data_source(btstack_data_source_t * data_source); 310896424b7SMatthias Ringwald 311896424b7SMatthias Ringwald /** 312896424b7SMatthias Ringwald * @brief Remove data source from run loop 313896424b7SMatthias Ringwald * @param data_source to remove 314896424b7SMatthias Ringwald */ 315896424b7SMatthias Ringwald int btstack_run_loop_remove_data_source(btstack_data_source_t * data_source); 31682636622SMatthias Ringwald 31782636622SMatthias Ringwald /** 3189fb44c6dSMatthias Ringwald * @brief Poll data sources - called only from IRQ context 3199fb44c6dSMatthias Ringwald * @note Can be used to trigger processing of received peripheral data on the main thread 3209fb44c6dSMatthias Ringwald * by registering a data source with DATA_SOURCE_CALLBACK_POLL and calling this 3219fb44c6dSMatthias Ringwald * function from the IRQ handler. 3229fb44c6dSMatthias Ringwald */ 3239fb44c6dSMatthias Ringwald void btstack_run_loop_poll_data_sources_from_irq(void); 3249fb44c6dSMatthias Ringwald 3259fb44c6dSMatthias Ringwald 3269fb44c6dSMatthias Ringwald /** 32782636622SMatthias Ringwald * @brief Execute configured run loop. This function does not return. 32882636622SMatthias Ringwald */ 329528a4a3bSMatthias Ringwald void btstack_run_loop_execute(void); 33082636622SMatthias Ringwald 3313a2e2107SMatthias Ringwald /** 3329fb44c6dSMatthias Ringwald * @brief Registers callback with run loop and mark main thread as ready 3339fb44c6dSMatthias Ringwald * @note Callback can only be registered once 3349fb44c6dSMatthias Ringwald * @param callback_registration 3359fb44c6dSMatthias Ringwald */ 3369fb44c6dSMatthias Ringwald void btstack_run_loop_execute_on_main_thread(btstack_context_callback_registration_t * callback_registration); 3379fb44c6dSMatthias Ringwald 3389fb44c6dSMatthias Ringwald /** 3399fb44c6dSMatthias Ringwald * @brief Trigger exit of active run loop (started via btstack_run_loop_execute) if possible 3409fb44c6dSMatthias Ringwald * @note This is only supported if there's a loop in the btstack_run_loop_execute function. 3419fb44c6dSMatthias Ringwald * It is not supported if timers and data sources are only mapped to RTOS equivalents, e.g. 3429fb44c6dSMatthias Ringwald * in the Qt or Core Foundation implementations. 3439fb44c6dSMatthias Ringwald */ 3449fb44c6dSMatthias Ringwald void btstack_run_loop_trigger_exit(void); 3459fb44c6dSMatthias Ringwald 3469fb44c6dSMatthias Ringwald 3479fb44c6dSMatthias Ringwald /** 3483a2e2107SMatthias Ringwald * @brief De-Init Run Loop 3493a2e2107SMatthias Ringwald */ 3503a2e2107SMatthias Ringwald void btstack_run_loop_deinit(void); 3513a2e2107SMatthias Ringwald 35282636622SMatthias Ringwald /* API_END */ 35382636622SMatthias Ringwald 354796f7837SMatthias Ringwald 35582636622SMatthias Ringwald #if defined __cplusplus 35682636622SMatthias Ringwald } 35782636622SMatthias Ringwald #endif 35882636622SMatthias Ringwald 3599fb44c6dSMatthias Ringwald #endif // BTSTACK_RUN_LOOP_H 360