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