1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  *
28  * switch_core_event_hook.h Core Event Hooks
29  *
30  */
31 #ifndef SWITCH_EVENT_HOOKS_H
32 #define SWITCH_EVENT_HOOKS_H
33 
34 #include <switch.h>
35 SWITCH_BEGIN_EXTERN_C typedef struct switch_io_event_hooks switch_io_event_hooks_t;
36 
37 typedef struct switch_io_event_hook_outgoing_channel switch_io_event_hook_outgoing_channel_t;
38 typedef struct switch_io_event_hook_receive_message switch_io_event_hook_receive_message_t;
39 typedef struct switch_io_event_hook_receive_event switch_io_event_hook_receive_event_t;
40 typedef struct switch_io_event_hook_read_frame switch_io_event_hook_read_frame_t;
41 typedef struct switch_io_event_hook_video_read_frame switch_io_event_hook_video_read_frame_t;
42 typedef struct switch_io_event_hook_write_frame switch_io_event_hook_write_frame_t;
43 typedef struct switch_io_event_hook_video_write_frame switch_io_event_hook_video_write_frame_t;
44 typedef struct switch_io_event_hook_text_read_frame switch_io_event_hook_text_read_frame_t;
45 typedef struct switch_io_event_hook_text_write_frame switch_io_event_hook_text_write_frame_t;
46 typedef struct switch_io_event_hook_kill_channel switch_io_event_hook_kill_channel_t;
47 typedef struct switch_io_event_hook_send_dtmf switch_io_event_hook_send_dtmf_t;
48 typedef struct switch_io_event_hook_recv_dtmf switch_io_event_hook_recv_dtmf_t;
49 typedef struct switch_io_event_hook_state_change switch_io_event_hook_state_change_t;
50 typedef struct switch_io_event_hook_state_run switch_io_event_hook_state_run_t;
51 typedef switch_status_t (*switch_outgoing_channel_hook_t)
52                 (switch_core_session_t *, switch_event_t *, switch_caller_profile_t *, switch_core_session_t *, switch_originate_flag_t);
53 typedef switch_status_t (*switch_receive_message_hook_t) (switch_core_session_t *, switch_core_session_message_t *);
54 typedef switch_status_t (*switch_receive_event_hook_t) (switch_core_session_t *, switch_event_t *);
55 typedef switch_status_t (*switch_read_frame_hook_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
56 typedef switch_status_t (*switch_video_read_frame_hook_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
57 typedef switch_status_t (*switch_write_frame_hook_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
58 typedef switch_status_t (*switch_video_write_frame_hook_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
59 typedef switch_status_t (*switch_text_read_frame_hook_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
60 typedef switch_status_t (*switch_text_write_frame_hook_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
61 typedef switch_status_t (*switch_kill_channel_hook_t) (switch_core_session_t *, int);
62 typedef switch_status_t (*switch_send_dtmf_hook_t) (switch_core_session_t *, const switch_dtmf_t *, switch_dtmf_direction_t direction);
63 typedef switch_status_t (*switch_recv_dtmf_hook_t) (switch_core_session_t *, const switch_dtmf_t *, switch_dtmf_direction_t direction);
64 typedef switch_status_t (*switch_state_change_hook_t) (switch_core_session_t *);
65 typedef switch_status_t (*switch_state_run_hook_t) (switch_core_session_t *);
66 
67 /*! \brief Node in which to store custom receive message callback hooks */
68 struct switch_io_event_hook_outgoing_channel {
69 	switch_outgoing_channel_hook_t outgoing_channel;
70 	struct switch_io_event_hook_outgoing_channel *next;
71 };
72 
73 /*! \brief Node in which to store custom receive message callback hooks */
74 struct switch_io_event_hook_receive_message {
75 	switch_receive_message_hook_t receive_message;
76 	struct switch_io_event_hook_receive_message *next;
77 };
78 
79 
80 /*! \brief Node in which to store custom receive message callback hooks */
81 struct switch_io_event_hook_receive_event {
82 	/*! the event callback hook */
83 	switch_receive_event_hook_t receive_event;
84 	struct switch_io_event_hook_receive_event *next;
85 };
86 
87 /*! \brief Node in which to store custom read frame channel callback hooks */
88 struct switch_io_event_hook_read_frame {
89 	/*! the read frame channel callback hook */
90 	switch_read_frame_hook_t read_frame;
91 	struct switch_io_event_hook_read_frame *next;
92 };
93 
94 /*! \brief Node in which to store custom read frame channel callback hooks */
95 struct switch_io_event_hook_video_read_frame {
96 	/*! the read frame channel callback hook */
97 	switch_read_frame_hook_t video_read_frame;
98 	struct switch_io_event_hook_video_read_frame *next;
99 };
100 
101 /*! \brief Node in which to store custom write_frame channel callback hooks */
102 struct switch_io_event_hook_write_frame {
103 	/*! the write_frame channel callback hook */
104 	switch_write_frame_hook_t write_frame;
105 	struct switch_io_event_hook_write_frame *next;
106 };
107 
108 /*! \brief Node in which to store custom video_write_frame channel callback hooks */
109 struct switch_io_event_hook_video_write_frame {
110 	/*! the video_write_frame channel callback hook */
111 	switch_video_write_frame_hook_t video_write_frame;
112 	struct switch_io_event_hook_video_write_frame *next;
113 };
114 
115 /*! \brief Node in which to store custom read frame channel callback hooks */
116 struct switch_io_event_hook_text_read_frame {
117 	/*! the read frame channel callback hook */
118 	switch_read_frame_hook_t text_read_frame;
119 	struct switch_io_event_hook_text_read_frame *next;
120 };
121 
122 /*! \brief Node in which to store custom video_write_frame channel callback hooks */
123 struct switch_io_event_hook_text_write_frame {
124 	/*! the video_write_frame channel callback hook */
125 	switch_video_write_frame_hook_t text_write_frame;
126 	struct switch_io_event_hook_text_write_frame *next;
127 };
128 
129 /*! \brief Node in which to store custom kill channel callback hooks */
130 struct switch_io_event_hook_kill_channel {
131 	/*! the kill channel callback hook */
132 	switch_kill_channel_hook_t kill_channel;
133 	struct switch_io_event_hook_kill_channel *next;
134 };
135 
136 /*! \brief Node in which to store custom send dtmf channel callback hooks */
137 struct switch_io_event_hook_send_dtmf {
138 	/*! the send dtmf channel callback hook */
139 	switch_send_dtmf_hook_t send_dtmf;
140 	struct switch_io_event_hook_send_dtmf *next;
141 };
142 
143 /*! \brief Node in which to store custom recv dtmf channel callback hooks */
144 struct switch_io_event_hook_recv_dtmf {
145 	/*! the recv dtmf channel callback hook */
146 	switch_recv_dtmf_hook_t recv_dtmf;
147 	struct switch_io_event_hook_recv_dtmf *next;
148 };
149 
150 /*! \brief Node in which to store state change callback hooks */
151 struct switch_io_event_hook_state_change {
152 	/*! the state change channel callback hook */
153 	switch_state_change_hook_t state_change;
154 	struct switch_io_event_hook_state_change *next;
155 };
156 
157 /*! \brief Node in which to store state run callback hooks */
158 struct switch_io_event_hook_state_run {
159 	/*! the state run channel callback hook */
160 	switch_state_run_hook_t state_run;
161 	struct switch_io_event_hook_state_run *next;
162 };
163 
164 
165 /*! \brief A table of lists of io_event_hooks to store the event hooks associated with a session */
166 struct switch_io_event_hooks {
167 	/*! a list of outgoing channel hooks */
168 	switch_io_event_hook_outgoing_channel_t *outgoing_channel;
169 	/*! a list of receive message hooks */
170 	switch_io_event_hook_receive_message_t *receive_message;
171 	/*! a list of queue message hooks */
172 	switch_io_event_hook_receive_event_t *receive_event;
173 	/*! a list of read frame hooks */
174 	switch_io_event_hook_read_frame_t *read_frame;
175 	/*! a list of video read frame hooks */
176 	switch_io_event_hook_video_read_frame_t *video_read_frame;
177 	/*! a list of write frame hooks */
178 	switch_io_event_hook_write_frame_t *write_frame;
179 	/*! a list of text write frame hooks */
180 	switch_io_event_hook_video_write_frame_t *video_write_frame;
181 	/*! a list of text write frame hooks */
182 	switch_io_event_hook_text_write_frame_t *text_write_frame;
183 	/*! a list of text read frame hooks */
184 	switch_io_event_hook_text_read_frame_t *text_read_frame;
185 	/*! a list of kill channel hooks */
186 	switch_io_event_hook_kill_channel_t *kill_channel;
187 	/*! a list of send dtmf hooks */
188 	switch_io_event_hook_send_dtmf_t *send_dtmf;
189 	/*! a list of recv dtmf hooks */
190 	switch_io_event_hook_recv_dtmf_t *recv_dtmf;
191 	/*! a list of state change hooks */
192 	switch_io_event_hook_state_change_t *state_change;
193 	switch_io_event_hook_state_run_t *state_run;
194 };
195 
196 extern switch_io_event_hooks_t switch_core_session_get_event_hooks(switch_core_session_t *session);
197 
198 #define NEW_HOOK_DECL_ADD_P(_NAME) SWITCH_DECLARE(switch_status_t) switch_core_event_hook_add_##_NAME \
199 															   (switch_core_session_t *session, switch_##_NAME##_hook_t _NAME)
200 
201 #define NEW_HOOK_DECL_REM_P(_NAME) SWITCH_DECLARE(switch_status_t) switch_core_event_hook_remove_##_NAME \
202 																   (switch_core_session_t *session, switch_##_NAME##_hook_t _NAME)
203 
204 #define NEW_HOOK_DECL(_NAME) NEW_HOOK_DECL_ADD_P(_NAME)					\
205 	{																	\
206 		switch_io_event_hook_##_NAME##_t *hook, *ptr;					\
207 		assert(_NAME != NULL);											\
208 		for (ptr = session->event_hooks._NAME; ptr && ptr->next; ptr = ptr->next) \
209 			if (ptr->_NAME == _NAME) return SWITCH_STATUS_FALSE;		\
210 		if (ptr && ptr->_NAME == _NAME) return SWITCH_STATUS_FALSE;		\
211 		if ((hook = switch_core_session_alloc(session, sizeof(*hook))) != 0) { \
212 			hook->_NAME = _NAME ;										\
213 			if (! session->event_hooks._NAME ) {						\
214 				session->event_hooks._NAME = hook;						\
215 			} else {													\
216 				switch_assert(ptr);                                     \
217 				ptr->next = hook;										\
218 			}															\
219 			return SWITCH_STATUS_SUCCESS;								\
220 		}																\
221 		return SWITCH_STATUS_MEMERR;									\
222 	}																	\
223 	NEW_HOOK_DECL_REM_P(_NAME)											\
224 	{																	\
225 		switch_io_event_hook_##_NAME##_t *ptr, *last = NULL;			\
226 		assert(_NAME != NULL);											\
227 		for (ptr = session->event_hooks._NAME; ptr; ptr = ptr->next) {	\
228 			if (ptr->_NAME == _NAME) {									\
229 				if (last) {												\
230 					last->next = ptr->next;								\
231 				} else {												\
232 					session->event_hooks._NAME = ptr->next;				\
233 				}														\
234 				return SWITCH_STATUS_SUCCESS;							\
235 			}															\
236 			last = ptr;													\
237 		}																\
238 		return SWITCH_STATUS_FALSE;										\
239 	}
240 
241 
242 NEW_HOOK_DECL_ADD_P(outgoing_channel);
243 NEW_HOOK_DECL_ADD_P(receive_message);
244 NEW_HOOK_DECL_ADD_P(receive_event);
245 NEW_HOOK_DECL_ADD_P(state_change);
246 NEW_HOOK_DECL_ADD_P(state_run);
247 NEW_HOOK_DECL_ADD_P(read_frame);
248 NEW_HOOK_DECL_ADD_P(write_frame);
249 NEW_HOOK_DECL_ADD_P(video_read_frame);
250 NEW_HOOK_DECL_ADD_P(video_write_frame);
251 NEW_HOOK_DECL_ADD_P(text_read_frame);
252 NEW_HOOK_DECL_ADD_P(text_write_frame);
253 NEW_HOOK_DECL_ADD_P(kill_channel);
254 NEW_HOOK_DECL_ADD_P(send_dtmf);
255 NEW_HOOK_DECL_ADD_P(recv_dtmf);
256 
257 NEW_HOOK_DECL_REM_P(outgoing_channel);
258 NEW_HOOK_DECL_REM_P(receive_message);
259 NEW_HOOK_DECL_REM_P(receive_event);
260 NEW_HOOK_DECL_REM_P(state_change);
261 NEW_HOOK_DECL_REM_P(state_run);
262 NEW_HOOK_DECL_REM_P(read_frame);
263 NEW_HOOK_DECL_REM_P(write_frame);
264 NEW_HOOK_DECL_REM_P(video_read_frame);
265 NEW_HOOK_DECL_REM_P(video_write_frame);
266 NEW_HOOK_DECL_REM_P(text_read_frame);
267 NEW_HOOK_DECL_REM_P(text_write_frame);
268 NEW_HOOK_DECL_REM_P(kill_channel);
269 NEW_HOOK_DECL_REM_P(send_dtmf);
270 NEW_HOOK_DECL_REM_P(recv_dtmf);
271 
272 
273 SWITCH_END_EXTERN_C
274 #endif
275 /* For Emacs:
276  * Local Variables:
277  * mode:c
278  * indent-tabs-mode:t
279  * tab-width:4
280  * c-basic-offset:4
281  * End:
282  * For VIM:
283  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
284  */
285