1 /*
2 	belle-sip - SIP (RFC3261) library.
3     Copyright (C) 2010  Belledonne Communications SARL
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #ifndef BELLE_SIP_MAINLOOP_H
20 #define BELLE_SIP_MAINLOOP_H
21 
22 
23 #define BELLE_SIP_EVENT_READ 1
24 #define BELLE_SIP_EVENT_WRITE (1<<1)
25 #define BELLE_SIP_EVENT_ERROR (1<<2)
26 #define BELLE_SIP_EVENT_TIMEOUT (1<<3)
27 
28 typedef struct belle_sip_source belle_sip_source_t;
29 
30 BELLESIP_EXPORT int belle_sip_source_set_events(belle_sip_source_t* source, int event_mask);
31 BELLESIP_EXPORT belle_sip_socket_t belle_sip_source_get_socket(const belle_sip_source_t* source);
32 
33 /**
34  * Callback function prototype for main loop notifications.
35  * Return value is important:
36  * BELLE_SIP_STOP => source is removed from main loop.
37  * BELLE_SIP_CONTINUE => source is kept, timeout is restarted if any according to last expiry time
38  * BELLE_SIP_CONTINUE_WITHOUT_CATCHUP => source is kept, timeout is restarted if any according to current time
39 **/
40 typedef int (*belle_sip_source_func_t)(void *user_data, unsigned int events);
41 
42 /*
43  * Call back fonction invoked when source is removed from main loop
44  */
45 typedef void (*belle_sip_source_remove_callback_t)(belle_sip_source_t *);
46 
47 typedef void (*belle_sip_callback_t)(void *user_data);
48 
49 typedef struct belle_sip_main_loop belle_sip_main_loop_t;
50 
51 #define BELLE_SIP_CONTINUE_WITHOUT_CATCHUP 2
52 #define BELLE_SIP_CONTINUE	1
53 #define BELLE_SIP_STOP		0
54 
55 BELLE_SIP_BEGIN_DECLS
56 
57 BELLESIP_EXPORT void belle_sip_main_loop_add_source(belle_sip_main_loop_t *ml, belle_sip_source_t *source);
58 
59 BELLESIP_EXPORT void belle_sip_main_loop_remove_source(belle_sip_main_loop_t *ml, belle_sip_source_t *source);
60 
61 /**
62  * Creates a mainloop.
63 **/
64 BELLESIP_EXPORT belle_sip_main_loop_t *belle_sip_main_loop_new(void);
65 
66 /**
67  * Adds a timeout into the main loop
68  * @param ml
69  * @param func a callback function to be called to notify timeout expiration
70  * @param data a pointer to be passed to the callback
71  * @param timeout_value_ms duration of the timeout.
72  * @returns timeout id
73 **/
74 BELLESIP_EXPORT unsigned long belle_sip_main_loop_add_timeout(belle_sip_main_loop_t *ml, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms);
75 
76 /**
77  * Adds a timeout into the main loop
78  * The caller of this function is responsible for freeing (with belle_sip_object_unref()) the returned belle_sip_source_t object when it is no longer
79  * needed.
80  * @param ml
81  * @param func a callback function to be called to notify timeout expiration
82  * @param data a pointer to be passed to the callback
83  * @param timeout_value_ms duration of the timeout.
84  * @param timer_name name of the timer, can be null
85  * @returns timeout belle_sip_source_t  with ref count = 1
86 **/
87 BELLESIP_EXPORT belle_sip_source_t* belle_sip_main_loop_create_timeout(belle_sip_main_loop_t *ml
88 							, belle_sip_source_func_t func
89 							, void *data
90 							, unsigned int timeout_value_ms
91 							,const char* timer_name);
92 
93 /**
94  * Adds a timeout into the main loop
95  * The caller of this function is responsible for freeing (with belle_sip_object_unref()) the returned belle_sip_source_t object when it is no longer
96  * needed.
97  * @param ml
98  * @param func a callback function to be called to notify timeout expiration
99  * @param data a pointer to be passed to the callback
100  * @param timeout_value_ms duration of the timeout.
101  * @param timer_name name of the timer, can be null
102  * @param function called when source is removed, can be null
103  * @returns timeout belle_sip_source_t  with ref count = 1
104  **/
105 BELLESIP_EXPORT belle_sip_source_t* belle_sip_main_loop_create_timeout_with_remove_cb (belle_sip_main_loop_t *ml
106 																					   , belle_sip_source_func_t func
107 																					   , void *data
108 																					   , unsigned int timeout_value_ms
109 																					   , const char* timer_name
110 																					   , belle_sip_source_remove_callback_t remove_func);
111 
112 
113 /**
114  * Schedule an arbitrary task at next main loop iteration.
115 **/
116 BELLESIP_EXPORT void belle_sip_main_loop_do_later(belle_sip_main_loop_t *ml, belle_sip_callback_t func, void *data);
117 
118 /**
119  * Creates a timeout source, similarly to belle_sip_main_loop_add_timeout().
120  * However in this case the timeout must be entered manually using belle_sip_main_loop_add_source().
121  * Its pointer can be used to remove it from the source (that is cancelling it).
122 **/
123 BELLESIP_EXPORT belle_sip_source_t * belle_sip_timeout_source_new(belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms);
124 
125 BELLESIP_EXPORT void belle_sip_source_set_timeout(belle_sip_source_t *s, unsigned int value_ms);
126 /**
127  * Cancel a source. Will be removed at next iterate. It is not freed.
128  **/
129 BELLESIP_EXPORT void belle_sip_source_cancel(belle_sip_source_t * src);
130 
131 
132 BELLESIP_EXPORT unsigned int belle_sip_source_get_timeout(const belle_sip_source_t *s);
133 
134 BELLESIP_EXPORT belle_sip_source_t * belle_sip_socket_source_new(belle_sip_source_func_t func, void *data, belle_sip_socket_t fd, unsigned int events, unsigned int timeout_value_ms);
135 /*
136  * register a callback invoked once source is removed from mainloop
137  */
138 BELLESIP_EXPORT void belle_sip_source_set_remove_cb(belle_sip_source_t *s, belle_sip_source_remove_callback_t func);
139 
140 BELLESIP_EXPORT unsigned long belle_sip_source_get_id(const belle_sip_source_t *s);
141 
142 BELLESIP_EXPORT void * belle_sip_source_get_user_data(const belle_sip_source_t *s);
143 BELLESIP_EXPORT void belle_sip_source_set_user_data(belle_sip_source_t *s, void *user_data);
144 
145 BELLESIP_EXPORT belle_sip_source_t *belle_sip_main_loop_find_source(belle_sip_main_loop_t *ml, unsigned long id);
146 
147 /**
148  * Executes the main loop forever (or until belle_sip_main_loop_quit() is called)
149 **/
150 BELLESIP_EXPORT void belle_sip_main_loop_run(belle_sip_main_loop_t *ml);
151 
152 /**
153  * Executes the main loop for the time specified in milliseconds.
154 **/
155 BELLESIP_EXPORT void belle_sip_main_loop_sleep(belle_sip_main_loop_t *ml, int milliseconds);
156 
157 /**
158  * Break out the main loop.
159 **/
160 BELLESIP_EXPORT int belle_sip_main_loop_quit(belle_sip_main_loop_t *ml);
161 
162 /**
163  * Cancel (removes) a source. It is not freed.
164 **/
165 BELLESIP_EXPORT void belle_sip_main_loop_cancel_source(belle_sip_main_loop_t *ml, unsigned long id);
166 
167 BELLE_SIP_END_DECLS
168 #ifndef BELLE_SIP_USE_STL
169 #define BELLE_SIP_USE_STL 1
170 #endif
171 #if __cplusplus >= 201103L && BELLE_SIP_USE_STL
172 #include <functional>
173 typedef std::function<int (unsigned int)> belle_sip_source_cpp_func_t;
belle_sip_source_cpp_func(belle_sip_source_cpp_func_t * user_data,unsigned int events)174 BELLESIP_EXPORT inline int belle_sip_source_cpp_func(belle_sip_source_cpp_func_t* user_data, unsigned int events)
175 {
176 	int result = (*user_data)(events);
177 	return result;
178 }
belle_sip_source_on_remove(belle_sip_source_t * source)179 BELLESIP_EXPORT inline void belle_sip_source_on_remove(belle_sip_source_t* source)
180 {
181 	delete static_cast<belle_sip_source_cpp_func_t *>(belle_sip_source_get_user_data(source));
182 	belle_sip_source_set_user_data(source,NULL);
183 }
184 
185 /*purpose of this function is to simplify c++ timer integration.
186  * ex:
187  * std::string helloworld("Hello world):
188  * belle_sip_source_cpp_func_t *func = new belle_sip_source_cpp_func_t([helloworld](unsigned int events) {
189  *						std::cout << helloworld << std::endl;
190  *						return BELLE_SIP_STOP;
191  *					});
192  *create timer
193  *mTimer = belle_sip_main_loop_create_cpp_timeout( mainloop
194  *												, func
195  *												, 1000
196  *												,"timer for c++");
197  *
198  */
199 
belle_sip_main_loop_create_cpp_timeout(belle_sip_main_loop_t * ml,belle_sip_source_cpp_func_t * func,unsigned int timeout_value_ms,const char * timer_name)200 BELLESIP_EXPORT inline belle_sip_source_t * belle_sip_main_loop_create_cpp_timeout(belle_sip_main_loop_t *ml
201 																				 , belle_sip_source_cpp_func_t *func
202 																				 , unsigned int timeout_value_ms
203 																				 , const char* timer_name)
204 {
205 	belle_sip_source_t* source = belle_sip_main_loop_create_timeout(  ml
206 																	, (belle_sip_source_func_t)belle_sip_source_cpp_func
207 																	, func
208 																	, timeout_value_ms
209 																	, timer_name);
210 	belle_sip_source_set_remove_cb(source,belle_sip_source_on_remove);
211 	return source;
212 }
213 
214 #endif
215 
216 #endif
217