xref: /btstack/src/btstack_run_loop.c (revision 02453b4dd4df6c751b53bd4142d89051d376f9ec)
115d50271SMatthias Ringwald /*
215d50271SMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
315d50271SMatthias Ringwald  *
415d50271SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
515d50271SMatthias Ringwald  * modification, are permitted provided that the following conditions
615d50271SMatthias Ringwald  * are met:
715d50271SMatthias Ringwald  *
815d50271SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
915d50271SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
1015d50271SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
1115d50271SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
1215d50271SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
1315d50271SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
1415d50271SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
1515d50271SMatthias Ringwald  *    from this software without specific prior written permission.
1615d50271SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
1715d50271SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
1815d50271SMatthias Ringwald  *    monetary gain.
1915d50271SMatthias Ringwald  *
2015d50271SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
2115d50271SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2215d50271SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
232fca4dadSMilanka Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
242fca4dadSMilanka Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2515d50271SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2615d50271SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
2715d50271SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2815d50271SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2915d50271SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
3015d50271SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3115d50271SMatthias Ringwald  * SUCH DAMAGE.
3215d50271SMatthias Ringwald  *
3315d50271SMatthias Ringwald  * Please inquire about commercial licensing options at
3415d50271SMatthias Ringwald  * [email protected]
3515d50271SMatthias Ringwald  *
3615d50271SMatthias Ringwald  */
3715d50271SMatthias Ringwald 
38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "btstack_run_loop.c"
39ab2c6ae4SMatthias Ringwald 
4015d50271SMatthias Ringwald /*
4115d50271SMatthias Ringwald  *  run_loop.c
4215d50271SMatthias Ringwald  *
4315d50271SMatthias Ringwald  *  Created by Matthias Ringwald on 6/6/09.
4415d50271SMatthias Ringwald  */
4515d50271SMatthias Ringwald 
4615d50271SMatthias Ringwald #include "btstack_run_loop.h"
4715d50271SMatthias Ringwald 
4815d50271SMatthias Ringwald #include "btstack_debug.h"
497907f069SMatthias Ringwald #include "btstack_config.h"
50796f7837SMatthias Ringwald #include "btstack_util.h"
5115d50271SMatthias Ringwald 
52016e9464SMatthias Ringwald #include <inttypes.h>
53016e9464SMatthias Ringwald 
54528a4a3bSMatthias Ringwald static const btstack_run_loop_t * the_run_loop = NULL;
5515d50271SMatthias Ringwald 
56528a4a3bSMatthias Ringwald extern const btstack_run_loop_t btstack_run_loop_embedded;
5715d50271SMatthias Ringwald 
58796f7837SMatthias Ringwald /*
59796f7837SMatthias Ringwald  *  Portable implementation of timer and data source management as base for platform specific implementations
60796f7837SMatthias Ringwald  */
61796f7837SMatthias Ringwald 
62796f7837SMatthias Ringwald // private data (access only by run loop implementations)
63796f7837SMatthias Ringwald btstack_linked_list_t  btstack_run_loop_base_timers;
64796f7837SMatthias Ringwald btstack_linked_list_t  btstack_run_loop_base_data_sources;
657eaf37e0SMatthias Ringwald btstack_linked_list_t  btstack_run_loop_base_callbacks;
66796f7837SMatthias Ringwald 
btstack_run_loop_base_init(void)67796f7837SMatthias Ringwald void btstack_run_loop_base_init(void){
68796f7837SMatthias Ringwald     btstack_run_loop_base_timers = NULL;
69796f7837SMatthias Ringwald     btstack_run_loop_base_data_sources = NULL;
707eaf37e0SMatthias Ringwald     btstack_run_loop_base_callbacks = NULL;
71796f7837SMatthias Ringwald }
72796f7837SMatthias Ringwald 
btstack_run_loop_base_add_data_source(btstack_data_source_t * data_source)73b45b7749SMilanka Ringwald void btstack_run_loop_base_add_data_source(btstack_data_source_t * data_source){
74b45b7749SMilanka Ringwald     btstack_linked_list_add(&btstack_run_loop_base_data_sources, (btstack_linked_item_t *) data_source);
75796f7837SMatthias Ringwald }
76796f7837SMatthias Ringwald 
btstack_run_loop_base_remove_data_source(btstack_data_source_t * data_source)77b45b7749SMilanka Ringwald bool btstack_run_loop_base_remove_data_source(btstack_data_source_t * data_source){
78b45b7749SMilanka Ringwald     return btstack_linked_list_remove(&btstack_run_loop_base_data_sources, (btstack_linked_item_t *) data_source);
79796f7837SMatthias Ringwald }
80796f7837SMatthias Ringwald 
btstack_run_loop_base_enable_data_source_callbacks(btstack_data_source_t * data_source,uint16_t callback_types)81b45b7749SMilanka Ringwald void btstack_run_loop_base_enable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callback_types){
82b45b7749SMilanka Ringwald     data_source->flags |= callback_types;
83796f7837SMatthias Ringwald }
84796f7837SMatthias Ringwald 
btstack_run_loop_base_disable_data_source_callbacks(btstack_data_source_t * data_source,uint16_t callback_types)85b45b7749SMilanka Ringwald void btstack_run_loop_base_disable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callback_types){
86b45b7749SMilanka Ringwald     data_source->flags &= ~callback_types;
87796f7837SMatthias Ringwald }
88796f7837SMatthias Ringwald 
btstack_run_loop_base_remove_timer(btstack_timer_source_t * timer)89b45b7749SMilanka Ringwald bool btstack_run_loop_base_remove_timer(btstack_timer_source_t * timer){
90b45b7749SMilanka Ringwald     return btstack_linked_list_remove(&btstack_run_loop_base_timers, (btstack_linked_item_t *) timer);
91796f7837SMatthias Ringwald }
92796f7837SMatthias Ringwald 
btstack_run_loop_base_add_timer(btstack_timer_source_t * timer)93b45b7749SMilanka Ringwald void btstack_run_loop_base_add_timer(btstack_timer_source_t * timer){
94796f7837SMatthias Ringwald     btstack_linked_item_t *it;
95796f7837SMatthias Ringwald     for (it = (btstack_linked_item_t *) &btstack_run_loop_base_timers; it->next ; it = it->next){
96796f7837SMatthias Ringwald         btstack_timer_source_t * next = (btstack_timer_source_t *) it->next;
975332c7c0SMatthias Ringwald 
985332c7c0SMatthias Ringwald         if (next == timer){
99*02453b4dSDirk Helbig             log_error("Timer %p already registered! Please read source code comment.", (void*)timer);
1005332c7c0SMatthias Ringwald             //
1015332c7c0SMatthias Ringwald             // Dear BTstack User!
1025332c7c0SMatthias Ringwald             //
1035332c7c0SMatthias Ringwald             // If you hit the assert below, your application code tried to add a timer to the list of
1045332c7c0SMatthias Ringwald             // timers that's already in the timer list, i.e., it's already registered.
1055332c7c0SMatthias Ringwald             //
1065332c7c0SMatthias Ringwald             // As you've probably already modified the timer, just ignoring this might lead to unexpected
1075332c7c0SMatthias Ringwald             // and hard to debug issues. Instead, we decided to raise an assert in this case to help.
1085332c7c0SMatthias Ringwald             //
1095332c7c0SMatthias Ringwald             // Please do a backtrace and check where you register this timer.
1105332c7c0SMatthias Ringwald             // If you just want to restart it you can call btstack_run_loop_timer_remove(..) before restarting the timer.
1115332c7c0SMatthias Ringwald             //
1125332c7c0SMatthias Ringwald             btstack_assert(false);
1135332c7c0SMatthias Ringwald         }
1145332c7c0SMatthias Ringwald 
115b45b7749SMilanka Ringwald         int32_t delta = btstack_time_delta(timer->timeout, next->timeout);
116796f7837SMatthias Ringwald         if (delta < 0) break;
117796f7837SMatthias Ringwald     }
118b45b7749SMilanka Ringwald     timer->item.next = it->next;
119b45b7749SMilanka Ringwald     it->next = (btstack_linked_item_t *) timer;
120796f7837SMatthias Ringwald }
121796f7837SMatthias Ringwald 
btstack_run_loop_base_process_timers(uint32_t now)122796f7837SMatthias Ringwald void btstack_run_loop_base_process_timers(uint32_t now){
123796f7837SMatthias Ringwald     // process timers, exit when timeout is in the future
124796f7837SMatthias Ringwald     while (btstack_run_loop_base_timers) {
125b45b7749SMilanka Ringwald         btstack_timer_source_t * timer = (btstack_timer_source_t *) btstack_run_loop_base_timers;
126b45b7749SMilanka Ringwald         int32_t delta = btstack_time_delta(timer->timeout, now);
127796f7837SMatthias Ringwald         if (delta > 0) break;
128b45b7749SMilanka Ringwald         btstack_run_loop_base_remove_timer(timer);
129b45b7749SMilanka Ringwald         timer->process(timer);
130796f7837SMatthias Ringwald     }
131796f7837SMatthias Ringwald }
132796f7837SMatthias Ringwald 
btstack_run_loop_base_dump_timer(void)133796f7837SMatthias Ringwald void btstack_run_loop_base_dump_timer(void){
134796f7837SMatthias Ringwald #ifdef ENABLE_LOG_INFO
135796f7837SMatthias Ringwald     btstack_linked_item_t *it;
136796f7837SMatthias Ringwald     uint16_t i = 0;
137796f7837SMatthias Ringwald     for (it = (btstack_linked_item_t *) btstack_run_loop_base_timers; it ; it = it->next){
138b45b7749SMilanka Ringwald         btstack_timer_source_t * timer = (btstack_timer_source_t*) it;
139e8cbad60SDirk Helbig         log_info("timer %u (%p): timeout %" PRIbtstack_time_t "\n", i, (void *) timer, timer->timeout);
140796f7837SMatthias Ringwald     }
141796f7837SMatthias Ringwald #endif
142796f7837SMatthias Ringwald 
143796f7837SMatthias Ringwald }
144796f7837SMatthias Ringwald /**
145796f7837SMatthias Ringwald  * @brief Get time until first timer fires
1466b65794dSMilanka Ringwald  * @return -1 if no timers, time until next timeout otherwise
147796f7837SMatthias Ringwald  */
btstack_run_loop_base_get_time_until_timeout(uint32_t now)148796f7837SMatthias Ringwald int32_t btstack_run_loop_base_get_time_until_timeout(uint32_t now){
149796f7837SMatthias Ringwald     if (btstack_run_loop_base_timers == NULL) return -1;
150b45b7749SMilanka Ringwald     btstack_timer_source_t * timer = (btstack_timer_source_t *) btstack_run_loop_base_timers;
151b45b7749SMilanka Ringwald     uint32_t list_timeout  = timer->timeout;
152796f7837SMatthias Ringwald     int32_t delta = btstack_time_delta(list_timeout, now);
153796f7837SMatthias Ringwald     if (delta < 0){
154796f7837SMatthias Ringwald         delta = 0;
155796f7837SMatthias Ringwald     }
156796f7837SMatthias Ringwald     return delta;
157796f7837SMatthias Ringwald }
158796f7837SMatthias Ringwald 
btstack_run_loop_base_poll_data_sources(void)159796f7837SMatthias Ringwald void btstack_run_loop_base_poll_data_sources(void){
160796f7837SMatthias Ringwald     // poll data sources
161796f7837SMatthias Ringwald     btstack_data_source_t *ds;
162796f7837SMatthias Ringwald     btstack_data_source_t *next;
163796f7837SMatthias Ringwald     for (ds = (btstack_data_source_t *) btstack_run_loop_base_data_sources; ds != NULL ; ds = next){
164796f7837SMatthias Ringwald         next = (btstack_data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself
165796f7837SMatthias Ringwald         if (ds->flags & DATA_SOURCE_CALLBACK_POLL){
166796f7837SMatthias Ringwald             ds->process(ds, DATA_SOURCE_CALLBACK_POLL);
167796f7837SMatthias Ringwald         }
168796f7837SMatthias Ringwald     }
169796f7837SMatthias Ringwald }
170796f7837SMatthias Ringwald 
btstack_run_loop_base_add_callback(btstack_context_callback_registration_t * callback_registration)1717eaf37e0SMatthias Ringwald void btstack_run_loop_base_add_callback(btstack_context_callback_registration_t * callback_registration){
1727eaf37e0SMatthias Ringwald     btstack_linked_list_add_tail(&btstack_run_loop_base_callbacks, (btstack_linked_item_t *) callback_registration);
1737eaf37e0SMatthias Ringwald }
1747eaf37e0SMatthias Ringwald 
1757eaf37e0SMatthias Ringwald 
btstack_run_loop_base_execute_callbacks(void)1767eaf37e0SMatthias Ringwald void btstack_run_loop_base_execute_callbacks(void){
1777eaf37e0SMatthias Ringwald     while (1){
1787eaf37e0SMatthias Ringwald         btstack_context_callback_registration_t * callback_registration = (btstack_context_callback_registration_t *) btstack_linked_list_pop(&btstack_run_loop_base_callbacks);
1797eaf37e0SMatthias Ringwald         if (callback_registration == NULL){
1807eaf37e0SMatthias Ringwald             break;
1817eaf37e0SMatthias Ringwald         }
1827eaf37e0SMatthias Ringwald         (*callback_registration->callback)(callback_registration->context);
1837eaf37e0SMatthias Ringwald     }
1847eaf37e0SMatthias Ringwald }
1857eaf37e0SMatthias Ringwald 
1867eaf37e0SMatthias Ringwald 
187796f7837SMatthias Ringwald /**
188796f7837SMatthias Ringwald  * BTstack Run Loop Implementation, mainly dispatches to port-specific implementation
189796f7837SMatthias Ringwald  */
190796f7837SMatthias Ringwald 
191796f7837SMatthias Ringwald // main implementation
192796f7837SMatthias Ringwald 
btstack_run_loop_set_timer_handler(btstack_timer_source_t * timer,void (* process)(btstack_timer_source_t * _timer))193b45b7749SMilanka Ringwald void btstack_run_loop_set_timer_handler(btstack_timer_source_t * timer, void (*process)(btstack_timer_source_t * _timer)){
194b45b7749SMilanka Ringwald     timer->process = process;
195aadd60a1SMatthias Ringwald }
19615d50271SMatthias Ringwald 
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))197b45b7749SMilanka 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)){
198b45b7749SMilanka Ringwald     data_source->process = process;
199aadd60a1SMatthias Ringwald }
20015d50271SMatthias Ringwald 
btstack_run_loop_set_data_source_fd(btstack_data_source_t * data_source,int fd)201b45b7749SMilanka Ringwald void btstack_run_loop_set_data_source_fd(btstack_data_source_t * data_source, int fd){
202b45b7749SMilanka Ringwald     data_source->source.fd = fd;
2033a5c43eeSMatthias Ringwald }
2043a5c43eeSMatthias Ringwald 
btstack_run_loop_get_data_source_fd(btstack_data_source_t * data_source)205b45b7749SMilanka Ringwald int btstack_run_loop_get_data_source_fd(btstack_data_source_t * data_source){
206b45b7749SMilanka Ringwald     return data_source->source.fd;
2073a5c43eeSMatthias Ringwald }
2083a5c43eeSMatthias Ringwald 
btstack_run_loop_set_data_source_handle(btstack_data_source_t * data_source,void * handle)209b45b7749SMilanka Ringwald void btstack_run_loop_set_data_source_handle(btstack_data_source_t * data_source, void * handle){
210b45b7749SMilanka Ringwald     data_source->source.handle = handle;
211f04a41aeSMatthias Ringwald }
212f04a41aeSMatthias Ringwald 
btstack_run_loop_get_data_source_handle(btstack_data_source_t * data_source)213b45b7749SMilanka Ringwald void * btstack_run_loop_get_data_source_handle(btstack_data_source_t * data_source){
214b45b7749SMilanka Ringwald     return data_source->source.handle;
215f04a41aeSMatthias Ringwald }
216f04a41aeSMatthias Ringwald 
btstack_run_loop_enable_data_source_callbacks(btstack_data_source_t * data_source,uint16_t callbacks)217b45b7749SMilanka Ringwald void btstack_run_loop_enable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks){
21827e05778SMatthias Ringwald     btstack_assert(the_run_loop != NULL);
219141177f8SMatthias Ringwald     btstack_assert(the_run_loop->enable_data_source_callbacks != NULL);
220b45b7749SMilanka Ringwald     the_run_loop->enable_data_source_callbacks(data_source, callbacks);
221896424b7SMatthias Ringwald }
222896424b7SMatthias Ringwald 
btstack_run_loop_disable_data_source_callbacks(btstack_data_source_t * data_source,uint16_t callbacks)223b45b7749SMilanka Ringwald void btstack_run_loop_disable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks){
22427e05778SMatthias Ringwald     btstack_assert(the_run_loop != NULL);
225141177f8SMatthias Ringwald     btstack_assert(the_run_loop->enable_data_source_callbacks != NULL);
226b45b7749SMilanka Ringwald     the_run_loop->disable_data_source_callbacks(data_source, callbacks);
227896424b7SMatthias Ringwald }
22815d50271SMatthias Ringwald 
22915d50271SMatthias Ringwald /**
23015d50271SMatthias Ringwald  * Add data_source to run_loop
23115d50271SMatthias Ringwald  */
btstack_run_loop_add_data_source(btstack_data_source_t * data_source)232b45b7749SMilanka Ringwald void btstack_run_loop_add_data_source(btstack_data_source_t * data_source){
23327e05778SMatthias Ringwald     btstack_assert(the_run_loop != NULL);
234141177f8SMatthias Ringwald     btstack_assert(the_run_loop->enable_data_source_callbacks != NULL);
235b45b7749SMilanka Ringwald     btstack_assert(data_source->process != NULL);
236b45b7749SMilanka Ringwald     the_run_loop->add_data_source(data_source);
23715d50271SMatthias Ringwald }
23815d50271SMatthias Ringwald 
23915d50271SMatthias Ringwald /**
24015d50271SMatthias Ringwald  * Remove data_source from run loop
24115d50271SMatthias Ringwald  */
btstack_run_loop_remove_data_source(btstack_data_source_t * data_source)242b45b7749SMilanka Ringwald int btstack_run_loop_remove_data_source(btstack_data_source_t * data_source){
24327e05778SMatthias Ringwald     btstack_assert(the_run_loop != NULL);
2440ad702f3SMatthias Ringwald     btstack_assert(the_run_loop->disable_data_source_callbacks != NULL);
245b45b7749SMilanka Ringwald     btstack_assert(data_source->process != NULL);
246b45b7749SMilanka Ringwald     return the_run_loop->remove_data_source(data_source);
24715d50271SMatthias Ringwald }
24815d50271SMatthias Ringwald 
btstack_run_loop_poll_data_sources_from_irq(void)2499fb44c6dSMatthias Ringwald void btstack_run_loop_poll_data_sources_from_irq(void){
2509fb44c6dSMatthias Ringwald     btstack_assert(the_run_loop != NULL);
2519fb44c6dSMatthias Ringwald     btstack_assert(the_run_loop->poll_data_sources_from_irq != NULL);
2529fb44c6dSMatthias Ringwald     the_run_loop->poll_data_sources_from_irq();
2539fb44c6dSMatthias Ringwald }
2549fb44c6dSMatthias Ringwald 
btstack_run_loop_set_timer(btstack_timer_source_t * timer,uint32_t timeout_in_ms)255b45b7749SMilanka Ringwald void btstack_run_loop_set_timer(btstack_timer_source_t *timer, uint32_t timeout_in_ms){
25627e05778SMatthias Ringwald     btstack_assert(the_run_loop != NULL);
257b45b7749SMilanka Ringwald     the_run_loop->set_timer(timer, timeout_in_ms);
25815d50271SMatthias Ringwald }
25915d50271SMatthias Ringwald 
26015d50271SMatthias Ringwald /**
261fd939756SMatthias Ringwald  * @brief Set context for this timer
262fd939756SMatthias Ringwald  */
btstack_run_loop_set_timer_context(btstack_timer_source_t * timer,void * context)263b45b7749SMilanka Ringwald void btstack_run_loop_set_timer_context(btstack_timer_source_t * timer, void * context){
264b45b7749SMilanka Ringwald     timer->context = context;
265fd939756SMatthias Ringwald }
266fd939756SMatthias Ringwald 
267fd939756SMatthias Ringwald /**
268fd939756SMatthias Ringwald  * @brief Get context for this timer
269fd939756SMatthias Ringwald  */
btstack_run_loop_get_timer_context(btstack_timer_source_t * timer)270b45b7749SMilanka Ringwald void * btstack_run_loop_get_timer_context(btstack_timer_source_t * timer){
271b45b7749SMilanka Ringwald     return timer->context;
272fd939756SMatthias Ringwald }
273fd939756SMatthias Ringwald 
274fd939756SMatthias Ringwald /**
27515d50271SMatthias Ringwald  * Add timer to run_loop (keep list sorted)
27615d50271SMatthias Ringwald  */
btstack_run_loop_add_timer(btstack_timer_source_t * timer)277b45b7749SMilanka Ringwald void btstack_run_loop_add_timer(btstack_timer_source_t * timer){
27827e05778SMatthias Ringwald     btstack_assert(the_run_loop != NULL);
279b45b7749SMilanka Ringwald     btstack_assert(timer->process != NULL);
280b45b7749SMilanka Ringwald     the_run_loop->add_timer(timer);
28115d50271SMatthias Ringwald }
28215d50271SMatthias Ringwald 
28315d50271SMatthias Ringwald /**
28415d50271SMatthias Ringwald  * Remove timer from run loop
28515d50271SMatthias Ringwald  */
btstack_run_loop_remove_timer(btstack_timer_source_t * timer)286b45b7749SMilanka Ringwald int btstack_run_loop_remove_timer(btstack_timer_source_t * timer){
28727e05778SMatthias Ringwald     btstack_assert(the_run_loop != NULL);
288b45b7749SMilanka Ringwald     return the_run_loop->remove_timer(timer);
28915d50271SMatthias Ringwald }
29015d50271SMatthias Ringwald 
29115d50271SMatthias Ringwald /**
29215d50271SMatthias Ringwald  * @brief Get current time in ms
29315d50271SMatthias Ringwald  */
btstack_run_loop_get_time_ms(void)294528a4a3bSMatthias Ringwald uint32_t btstack_run_loop_get_time_ms(void){
29527e05778SMatthias Ringwald     btstack_assert(the_run_loop != NULL);
29615d50271SMatthias Ringwald     return the_run_loop->get_time_ms();
29715d50271SMatthias Ringwald }
29815d50271SMatthias Ringwald 
29915d50271SMatthias Ringwald 
btstack_run_loop_timer_dump(void)300528a4a3bSMatthias Ringwald void btstack_run_loop_timer_dump(void){
30127e05778SMatthias Ringwald     btstack_assert(the_run_loop != NULL);
30215d50271SMatthias Ringwald     the_run_loop->dump_timer();
30315d50271SMatthias Ringwald }
30415d50271SMatthias Ringwald 
30515d50271SMatthias Ringwald /**
30615d50271SMatthias Ringwald  * Execute run_loop
30715d50271SMatthias Ringwald  */
btstack_run_loop_execute(void)308528a4a3bSMatthias Ringwald void btstack_run_loop_execute(void){
30927e05778SMatthias Ringwald     btstack_assert(the_run_loop != NULL);
31015d50271SMatthias Ringwald     the_run_loop->execute();
31115d50271SMatthias Ringwald }
31215d50271SMatthias Ringwald 
btstack_run_loop_trigger_exit(void)3139fb44c6dSMatthias Ringwald void btstack_run_loop_trigger_exit(void){
3149fb44c6dSMatthias Ringwald     btstack_assert(the_run_loop != NULL);
3159fb44c6dSMatthias Ringwald     btstack_assert(the_run_loop->trigger_exit != NULL);
3169fb44c6dSMatthias Ringwald     the_run_loop->trigger_exit();
3179fb44c6dSMatthias Ringwald }
3189fb44c6dSMatthias Ringwald 
btstack_run_loop_execute_on_main_thread(btstack_context_callback_registration_t * callback_registration)3199fb44c6dSMatthias Ringwald void btstack_run_loop_execute_on_main_thread(btstack_context_callback_registration_t * callback_registration){
3209fb44c6dSMatthias Ringwald     btstack_assert(the_run_loop != NULL);
3219fb44c6dSMatthias Ringwald     btstack_assert(the_run_loop->execute_on_main_thread != NULL);
3229fb44c6dSMatthias Ringwald     the_run_loop->execute_on_main_thread(callback_registration);
3239fb44c6dSMatthias Ringwald }
3249fb44c6dSMatthias Ringwald 
32515d50271SMatthias Ringwald // init must be called before any other run_loop call
btstack_run_loop_init(const btstack_run_loop_t * run_loop)326528a4a3bSMatthias Ringwald void btstack_run_loop_init(const btstack_run_loop_t * run_loop){
32727e05778SMatthias Ringwald     btstack_assert(the_run_loop == NULL);
32815d50271SMatthias Ringwald     the_run_loop = run_loop;
32915d50271SMatthias Ringwald     the_run_loop->init();
33015d50271SMatthias Ringwald }
33115d50271SMatthias Ringwald 
btstack_run_loop_deinit(void)3323a2e2107SMatthias Ringwald void btstack_run_loop_deinit(void){
3333a2e2107SMatthias Ringwald     the_run_loop = NULL;
3343a2e2107SMatthias Ringwald }
3353a2e2107SMatthias Ringwald 
336