1 /* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 /** 39 * @title Run Loop 40 * 41 */ 42 43 #ifndef btstack_run_loop_H 44 #define btstack_run_loop_H 45 46 #include "btstack_config.h" 47 48 #include "btstack_bool.h" 49 #include "btstack_linked_list.h" 50 51 #include <stdint.h> 52 53 #if defined __cplusplus 54 extern "C" { 55 #endif 56 57 /** 58 * Callback types for run loop data sources 59 */ 60 typedef enum { 61 DATA_SOURCE_CALLBACK_POLL = 1 << 0, 62 DATA_SOURCE_CALLBACK_READ = 1 << 1, 63 DATA_SOURCE_CALLBACK_WRITE = 1 << 2, 64 } btstack_data_source_callback_type_t; 65 66 typedef struct btstack_data_source { 67 // linked item 68 btstack_linked_item_t item; 69 70 // item to watch in run loop 71 union { 72 // file descriptor for posix systems 73 int fd; 74 // handle on windows 75 void * handle; 76 } source; 77 78 // callback to call for enabled callback types 79 void (*process)(struct btstack_data_source *ds, btstack_data_source_callback_type_t callback_type); 80 81 // flags storing enabled callback types 82 uint16_t flags; 83 84 } btstack_data_source_t; 85 86 typedef struct btstack_timer_source { 87 btstack_linked_item_t item; 88 // timeout in system ticks (HAVE_EMBEDDED_TICK) or milliseconds (HAVE_EMBEDDED_TIME_MS) 89 uint32_t timeout; 90 // will be called when timer fired 91 void (*process)(struct btstack_timer_source *ts); 92 void * context; 93 } btstack_timer_source_t; 94 95 typedef struct btstack_run_loop { 96 void (*init)(void); 97 void (*add_data_source)(btstack_data_source_t * data_source); 98 bool (*remove_data_source)(btstack_data_source_t * data_source); 99 void (*enable_data_source_callbacks)(btstack_data_source_t * data_source, uint16_t callbacks); 100 void (*disable_data_source_callbacks)(btstack_data_source_t * data_source, uint16_t callbacks); 101 void (*set_timer)(btstack_timer_source_t * timer, uint32_t timeout_in_ms); 102 void (*add_timer)(btstack_timer_source_t *timer); 103 bool (*remove_timer)(btstack_timer_source_t *timer); 104 void (*execute)(void); 105 void (*dump_timer)(void); 106 uint32_t (*get_time_ms)(void); 107 } btstack_run_loop_t; 108 109 110 /* 111 * BTstack Run Loop Base Implementation 112 * Portable implementation of timer and data source management as base for platform specific implementations 113 */ 114 115 // private data (access only by run loop implementations) 116 extern btstack_linked_list_t btstack_run_loop_base_timers; 117 extern btstack_linked_list_t btstack_run_loop_base_data_sources; 118 119 /** 120 * @brief Init 121 */ 122 void btstack_run_loop_base_init(void); 123 124 /** 125 * @brief Add timer source. 126 * @param timer to add 127 */ 128 void btstack_run_loop_base_add_timer(btstack_timer_source_t * timer); 129 130 /** 131 * @brief Remove timer source. 132 * @param timer to remove 133 * @returns true if timer was removed 134 */ 135 bool btstack_run_loop_base_remove_timer(btstack_timer_source_t * timer); 136 137 /** 138 * @brief Process timers: remove expired timers from list and call their process function 139 * @param now 140 */ 141 void btstack_run_loop_base_process_timers(uint32_t now); 142 143 /** 144 * @brief Dump list of timers via log_info 145 */ 146 void btstack_run_loop_base_dump_timer(void); 147 148 /** 149 * @brief Get time until first timer fires 150 * @returns -1 if no timers, time until next timeout otherwise 151 */ 152 int32_t btstack_run_loop_base_get_time_until_timeout(uint32_t now); 153 154 /** 155 * @brief Add data source to run loop 156 * @param data_source to add 157 */ 158 void btstack_run_loop_base_add_data_source(btstack_data_source_t * data_source); 159 160 /** 161 * @brief Remove data source from run loop 162 * @param data_source to remove 163 * @returns true if data srouce was removed 164 */ 165 bool btstack_run_loop_base_remove_data_source(btstack_data_source_t * data_source); 166 167 /** 168 * @brief Enable callbacks for a data source 169 * @param data_source to remove 170 * @param callback_types to enable 171 */ 172 void btstack_run_loop_base_enable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callback_types); 173 174 /** 175 * @brief Enable callbacks for a data source 176 * @param data_source to remove 177 * @param callback_types to disable 178 */ 179 void btstack_run_loop_base_disable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callback_types); 180 181 /** 182 * @brief Poll data sources. It calls the procss function for all data sources where DATA_SOURCE_CALLBACK_POLL is set 183 */ 184 void btstack_run_loop_base_poll_data_sources(void); 185 186 187 /* API_START */ 188 189 /** 190 * @brief Init main run loop. Must be called before any other run loop call. 191 * 192 * Use btstack_run_loop_$(btstack_run_loop_TYPE)_get_instance() from btstack_run_loop_$(btstack_run_loop_TYPE).h to get instance 193 */ 194 void btstack_run_loop_init(const btstack_run_loop_t * run_loop); 195 196 /** 197 * @brief Set timer based on current time in milliseconds. 198 */ 199 void btstack_run_loop_set_timer(btstack_timer_source_t * timer, uint32_t timeout_in_ms); 200 201 /** 202 * @brief Set callback that will be executed when timer expires. 203 */ 204 void btstack_run_loop_set_timer_handler(btstack_timer_source_t * timer, void (*process)(btstack_timer_source_t * _timer)); 205 206 /** 207 * @brief Set context for this timer 208 */ 209 void btstack_run_loop_set_timer_context(btstack_timer_source_t * timer, void * context); 210 211 /** 212 * @brief Get context for this timer 213 */ 214 void * btstack_run_loop_get_timer_context(btstack_timer_source_t * timer); 215 216 /** 217 * @brief Add timer source. 218 */ 219 void btstack_run_loop_add_timer(btstack_timer_source_t * timer); 220 221 /** 222 * @brief Remove timer source. 223 */ 224 int btstack_run_loop_remove_timer(btstack_timer_source_t * timer); 225 226 /** 227 * @brief Get current time in ms 228 * @note 32-bit ms counter will overflow after approx. 52 days 229 */ 230 uint32_t btstack_run_loop_get_time_ms(void); 231 232 /** 233 * @brief Dump timers using log_info 234 */ 235 void btstack_run_loop_timer_dump(void); 236 237 238 /** 239 * @brief Set data source callback. 240 */ 241 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)); 242 243 /** 244 * @brief Set data source file descriptor. 245 * @param data_source 246 * @param fd file descriptor 247 * @note No effect if port doensn't have file descriptors 248 */ 249 void btstack_run_loop_set_data_source_fd(btstack_data_source_t * data_source, int fd); 250 251 /** 252 * @brief Get data source file descriptor. 253 * @param data_source 254 */ 255 int btstack_run_loop_get_data_source_fd(btstack_data_source_t * data_source); 256 257 /** 258 * @brief Set data source file descriptor. 259 * @param data_source 260 * @param handle 261 * @note No effect if port doensn't have file descriptors 262 */ 263 void btstack_run_loop_set_data_source_handle(btstack_data_source_t * data_source, void * handle); 264 265 /** 266 * @brief Get data source file descriptor. 267 * @param data_source 268 */ 269 void * btstack_run_loop_get_data_source_handle(btstack_data_source_t * data_source); 270 271 /** 272 * @brief Enable callbacks for a data source 273 * @param data_source to remove 274 * @param callback types to enable 275 */ 276 void btstack_run_loop_enable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks); 277 278 /** 279 * @brief Enable callbacks for a data source 280 * @param data_source to remove 281 * @param callback types to disable 282 */ 283 void btstack_run_loop_disable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks); 284 285 /** 286 * @brief Add data source to run loop 287 * @param data_source to add 288 */ 289 void btstack_run_loop_add_data_source(btstack_data_source_t * data_source); 290 291 /** 292 * @brief Remove data source from run loop 293 * @param data_source to remove 294 */ 295 int btstack_run_loop_remove_data_source(btstack_data_source_t * data_source); 296 297 /** 298 * @brief Execute configured run loop. This function does not return. 299 */ 300 void btstack_run_loop_execute(void); 301 302 /** 303 * @brief De-Init Run Loop 304 */ 305 void btstack_run_loop_deinit(void); 306 307 /* API_END */ 308 309 310 311 #if defined __cplusplus 312 } 313 #endif 314 315 #endif // btstack_run_loop_H 316