xref: /btstack/src/btstack_run_loop.c (revision f04a41aef748acd99ba03bfb238643ec30bfde30)
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
2315d50271SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
2415d50271SMatthias Ringwald  * RINGWALD 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 
38ab2c6ae4SMatthias 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 <stdio.h>
4915d50271SMatthias Ringwald #include <stdlib.h>  // exit()
5015d50271SMatthias Ringwald 
5115d50271SMatthias Ringwald 
5215d50271SMatthias Ringwald #include "btstack_debug.h"
537907f069SMatthias Ringwald #include "btstack_config.h"
5415d50271SMatthias Ringwald 
55528a4a3bSMatthias Ringwald static const btstack_run_loop_t * the_run_loop = NULL;
5615d50271SMatthias Ringwald 
57528a4a3bSMatthias Ringwald extern const btstack_run_loop_t btstack_run_loop_embedded;
5815d50271SMatthias Ringwald 
5915d50271SMatthias Ringwald // assert run loop initialized
60528a4a3bSMatthias Ringwald static void btstack_run_loop_assert(void){
6115d50271SMatthias Ringwald     if (!the_run_loop){
62528a4a3bSMatthias Ringwald         log_error("ERROR: run_loop function called before btstack_run_loop_init!");
6315d50271SMatthias Ringwald         while(1);
6415d50271SMatthias Ringwald     }
6515d50271SMatthias Ringwald }
6615d50271SMatthias Ringwald 
6715d50271SMatthias Ringwald 
68ec820d77SMatthias Ringwald void btstack_run_loop_set_timer_handler(btstack_timer_source_t *ts, void (*process)(btstack_timer_source_t *_ts)){
6915d50271SMatthias Ringwald     ts->process = process;
7015d50271SMatthias Ringwald };
7115d50271SMatthias Ringwald 
72896424b7SMatthias Ringwald void btstack_run_loop_set_data_source_handler(btstack_data_source_t *ds, void (*process)(btstack_data_source_t *_ds,  btstack_data_source_callback_type_t callback_type)){
7315d50271SMatthias Ringwald     ds->process = process;
7415d50271SMatthias Ringwald };
7515d50271SMatthias Ringwald 
763a5c43eeSMatthias Ringwald void btstack_run_loop_set_data_source_fd(btstack_data_source_t *ds, int fd){
773a5c43eeSMatthias Ringwald     ds->fd = fd;
783a5c43eeSMatthias Ringwald }
793a5c43eeSMatthias Ringwald 
803a5c43eeSMatthias Ringwald int btstack_run_loop_get_data_source_fd(btstack_data_source_t *ds){
813a5c43eeSMatthias Ringwald     return ds->fd;
823a5c43eeSMatthias Ringwald }
833a5c43eeSMatthias Ringwald 
84*f04a41aeSMatthias Ringwald void btstack_run_loop_set_data_source_handle(btstack_data_source_t *ds, void * handle){
85*f04a41aeSMatthias Ringwald     ds->handle = handle;
86*f04a41aeSMatthias Ringwald }
87*f04a41aeSMatthias Ringwald 
88*f04a41aeSMatthias Ringwald void * btstack_run_loop_get_data_source_handle(btstack_data_source_t *ds){
89*f04a41aeSMatthias Ringwald     return ds->handle;
90*f04a41aeSMatthias Ringwald }
91*f04a41aeSMatthias Ringwald 
920d70dd62SMatthias Ringwald void btstack_run_loop_enable_data_source_callbacks(btstack_data_source_t *ds, uint16_t callbacks){
930d70dd62SMatthias Ringwald     btstack_run_loop_assert();
940d70dd62SMatthias Ringwald     if (the_run_loop->enable_data_source_callbacks){
954ea196a4SMatthias Ringwald         the_run_loop->enable_data_source_callbacks(ds, callbacks);
960d70dd62SMatthias Ringwald     } else {
970d70dd62SMatthias Ringwald         log_error("btstack_run_loop_remove_data_source not implemented");
980d70dd62SMatthias Ringwald     }
99896424b7SMatthias Ringwald }
100896424b7SMatthias Ringwald 
1010d70dd62SMatthias Ringwald void btstack_run_loop_disable_data_source_callbacks(btstack_data_source_t *ds, uint16_t callbacks){
1020d70dd62SMatthias Ringwald     btstack_run_loop_assert();
1030d70dd62SMatthias Ringwald     if (the_run_loop->disable_data_source_callbacks){
1044ea196a4SMatthias Ringwald         the_run_loop->disable_data_source_callbacks(ds, callbacks);
1050d70dd62SMatthias Ringwald     } else {
1060d70dd62SMatthias Ringwald         log_error("btstack_run_loop_disable_data_source_callbacks not implemented");
1070d70dd62SMatthias Ringwald     }
108896424b7SMatthias Ringwald }
10915d50271SMatthias Ringwald 
11015d50271SMatthias Ringwald /**
11115d50271SMatthias Ringwald  * Add data_source to run_loop
11215d50271SMatthias Ringwald  */
113ec820d77SMatthias Ringwald void btstack_run_loop_add_data_source(btstack_data_source_t *ds){
114528a4a3bSMatthias Ringwald     btstack_run_loop_assert();
11515d50271SMatthias Ringwald     if (the_run_loop->add_data_source){
11615d50271SMatthias Ringwald         the_run_loop->add_data_source(ds);
11715d50271SMatthias Ringwald     } else {
118528a4a3bSMatthias Ringwald         log_error("btstack_run_loop_add_data_source not implemented");
11915d50271SMatthias Ringwald     }
12015d50271SMatthias Ringwald }
12115d50271SMatthias Ringwald 
12215d50271SMatthias Ringwald /**
12315d50271SMatthias Ringwald  * Remove data_source from run loop
12415d50271SMatthias Ringwald  */
125ec820d77SMatthias Ringwald int btstack_run_loop_remove_data_source(btstack_data_source_t *ds){
126528a4a3bSMatthias Ringwald     btstack_run_loop_assert();
12715d50271SMatthias Ringwald     if (the_run_loop->remove_data_source){
12815d50271SMatthias Ringwald         return the_run_loop->remove_data_source(ds);
12915d50271SMatthias Ringwald     } else {
130528a4a3bSMatthias Ringwald         log_error("btstack_run_loop_remove_data_source not implemented");
13115d50271SMatthias Ringwald         return 0;
13215d50271SMatthias Ringwald     }
13315d50271SMatthias Ringwald }
13415d50271SMatthias Ringwald 
135ec820d77SMatthias Ringwald void btstack_run_loop_set_timer(btstack_timer_source_t *a, uint32_t timeout_in_ms){
136528a4a3bSMatthias Ringwald     btstack_run_loop_assert();
13715d50271SMatthias Ringwald     the_run_loop->set_timer(a, timeout_in_ms);
13815d50271SMatthias Ringwald }
13915d50271SMatthias Ringwald 
14015d50271SMatthias Ringwald /**
141fd939756SMatthias Ringwald  * @brief Set context for this timer
142fd939756SMatthias Ringwald  */
143fd939756SMatthias Ringwald void btstack_run_loop_set_timer_context(btstack_timer_source_t *ts, void * context){
144fd939756SMatthias Ringwald     ts->context = context;
145fd939756SMatthias Ringwald }
146fd939756SMatthias Ringwald 
147fd939756SMatthias Ringwald /**
148fd939756SMatthias Ringwald  * @brief Get context for this timer
149fd939756SMatthias Ringwald  */
150fd939756SMatthias Ringwald void * btstack_run_loop_get_timer_context(btstack_timer_source_t *ts){
151fd939756SMatthias Ringwald     return ts->context;
152fd939756SMatthias Ringwald }
153fd939756SMatthias Ringwald 
154fd939756SMatthias Ringwald /**
15515d50271SMatthias Ringwald  * Add timer to run_loop (keep list sorted)
15615d50271SMatthias Ringwald  */
157ec820d77SMatthias Ringwald void btstack_run_loop_add_timer(btstack_timer_source_t *ts){
158528a4a3bSMatthias Ringwald     btstack_run_loop_assert();
15915d50271SMatthias Ringwald     the_run_loop->add_timer(ts);
16015d50271SMatthias Ringwald }
16115d50271SMatthias Ringwald 
16215d50271SMatthias Ringwald /**
16315d50271SMatthias Ringwald  * Remove timer from run loop
16415d50271SMatthias Ringwald  */
165ec820d77SMatthias Ringwald int btstack_run_loop_remove_timer(btstack_timer_source_t *ts){
166528a4a3bSMatthias Ringwald     btstack_run_loop_assert();
16715d50271SMatthias Ringwald     return the_run_loop->remove_timer(ts);
16815d50271SMatthias Ringwald }
16915d50271SMatthias Ringwald 
17015d50271SMatthias Ringwald /**
17115d50271SMatthias Ringwald  * @brief Get current time in ms
17215d50271SMatthias Ringwald  */
173528a4a3bSMatthias Ringwald uint32_t btstack_run_loop_get_time_ms(void){
174528a4a3bSMatthias Ringwald     btstack_run_loop_assert();
17515d50271SMatthias Ringwald     return the_run_loop->get_time_ms();
17615d50271SMatthias Ringwald }
17715d50271SMatthias Ringwald 
17815d50271SMatthias Ringwald 
179528a4a3bSMatthias Ringwald void btstack_run_loop_timer_dump(void){
180528a4a3bSMatthias Ringwald     btstack_run_loop_assert();
18115d50271SMatthias Ringwald     the_run_loop->dump_timer();
18215d50271SMatthias Ringwald }
18315d50271SMatthias Ringwald 
18415d50271SMatthias Ringwald /**
18515d50271SMatthias Ringwald  * Execute run_loop
18615d50271SMatthias Ringwald  */
187528a4a3bSMatthias Ringwald void btstack_run_loop_execute(void){
188528a4a3bSMatthias Ringwald     btstack_run_loop_assert();
18915d50271SMatthias Ringwald     the_run_loop->execute();
19015d50271SMatthias Ringwald }
19115d50271SMatthias Ringwald 
19215d50271SMatthias Ringwald // init must be called before any other run_loop call
193528a4a3bSMatthias Ringwald void btstack_run_loop_init(const btstack_run_loop_t * run_loop){
19415d50271SMatthias Ringwald     if (the_run_loop){
19515d50271SMatthias Ringwald         log_error("ERROR: run loop initialized twice!");
19615d50271SMatthias Ringwald         while(1);
19715d50271SMatthias Ringwald     }
19815d50271SMatthias Ringwald     the_run_loop = run_loop;
19915d50271SMatthias Ringwald     the_run_loop->init();
20015d50271SMatthias Ringwald }
20115d50271SMatthias Ringwald 
202