1 #ifndef SWITCH_CPP_H
2 #define SWITCH_CPP_H
3 
4 
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8 #ifdef DOH
9 }
10 #endif
11 #include <switch.h>
12 #define this_check(x) do { if (!this) { switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "object is not initalized\n"); return x;}} while(0)
13 #define this_check_void() do { if (!this) { switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "object is not initalized\n"); return;}} while(0)
14 #define sanity_check(x) do { if (!(session && allocated)) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid),SWITCH_LOG_ERROR, "session is not initalized\n"); return x;}} while(0)
15 #define sanity_check_noreturn do { if (!(session && allocated)) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid),SWITCH_LOG_ERROR, "session is not initalized\n"); return;}} while(0)
16 #define init_vars() allocated = 0;						\
17 	session = NULL;										\
18 	channel = NULL;										\
19 	uuid = NULL;										\
20 	tts_name = NULL;									\
21 	voice_name = NULL;									\
22 	xml_cdr_text = NULL;								\
23 	memset(&args, 0, sizeof(args));						\
24 	ap = NULL;											\
25 	flags = 0;											\
26 	on_hangup = NULL;									\
27 	memset(&cb_state, 0, sizeof(cb_state));				\
28 	hook_state = CS_NEW;								\
29 	fhp = NULL;											\
30 	cause = SWITCH_CAUSE_NONE
31 
32 //// C++ Interface: switch_to_cpp_mempool//// Description: This class allows for overloading the new operator to allocate from a switch_memory_pool_t//// Author: Yossi Neiman <freeswitch@cartissolutions.com>, (C) 2007//// Copyright: See COPYING file that comes with this distribution//
33 #if 0
34 #ifndef SWITCHTOMEMPOOL
35 #define SWITCHTOMEMPOOL
36 class SwitchToMempool {
37   public:
SwitchToMempool()38 	SwitchToMempool() {
39 	} SwitchToMempool(switch_memory_pool_t *mem) {
40 		memorypool = mem;
41 	}
new(switch_size_t num_bytes,switch_memory_pool_t * mem)42 	void *operator  new(switch_size_t num_bytes, switch_memory_pool_t *mem) {
43 		void *ptr = switch_core_alloc(mem, (switch_size_t) num_bytes);
44 		return ptr;
45 	}
46   protected:
47 	switch_memory_pool_t *memorypool;
48 };
49 #endif
50 #endif
51 
52 /*
53 
54 Overview: once you create an object that inherits this class, since
55           the memory pool is then a class data member, you can continue to
56           allocate objects from the memory pool.
57           objects from within the class
58 
59 Notes on usage:
60 
61 1.  The derived class will need to also overload the ctor so that it accepts a memory pool object as a parameter.
62 2.  Instantiation of a class would then look something like this:   Foo *bar = new(memory_pool) Foo(memory_pool);
63 
64 Note that the first parameter to the new operator is implicitly handled by c++...  not sure I like that but it's how it is...
65 
66 */
67 
68 
69 SWITCH_DECLARE(void) setGlobalVariable(char *var_name, char *var_val);
70 SWITCH_DECLARE(char *) getGlobalVariable(char *var_name);
71 
72 SWITCH_DECLARE(void) consoleLog(char *level_str, char *msg);
73 SWITCH_DECLARE(void) consoleLog2(char *level_str, char *file, char *func, int line, char *msg);
74 SWITCH_DECLARE(void) consoleCleanLog(char *msg);
75 SWITCH_DECLARE(bool) running(void);
76 
77 SWITCH_DECLARE(bool) email(char *to, char *from, char *headers = NULL, char *body = NULL,
78     char *file = NULL, char *convert_cmd = NULL, char *convert_ext = NULL);
79 
80 
81 	 class CoreSession;
82 
83 	 class IVRMenu {
84 	   protected:
85 		 switch_ivr_menu_t *menu;
86 		 switch_memory_pool_t *pool;
87 	   public:
88 		 SWITCH_DECLARE_CONSTRUCTOR IVRMenu(IVRMenu * main,
89 											const char *name,
90 											const char *greeting_sound,
91 											const char *short_greeting_sound,
92 											const char *invalid_sound,
93 											const char *exit_sound,
94 											const char *transfer_sound,
95 											const char *confirm_macro,
96 											const char *confirm_key,
97 											const char *tts_engine,
98 											const char *tts_voice,
99 											int confirm_attempts, int inter_timeout, int digit_len,
100 											int timeout, int max_failures, int max_timeouts);
101 		 virtual SWITCH_DECLARE_CONSTRUCTOR ~ IVRMenu();
102 		 SWITCH_DECLARE(void) bindAction(char *action, const char *arg, const char *bind);
103 		 SWITCH_DECLARE(void) execute(CoreSession * session, const char *name);
104 	 };
105 
106 
107 	 class API {
108 	   protected:
109 		 char time_buf[64];
110 		 switch_core_session_t *session;
111 	   public:
112 		 SWITCH_DECLARE_CONSTRUCTOR API(CoreSession *s = NULL);
113 		 virtual SWITCH_DECLARE_CONSTRUCTOR ~ API();
114 		 SWITCH_DECLARE(const char *) execute(const char *command, const char *data = NULL);
115 		 SWITCH_DECLARE(const char *) executeString(const char *command);
116 		 SWITCH_DECLARE(char *) getTime(void);
117 	 };
118 
119 
120 	 typedef struct input_callback_state {
121 		 void *function;		// pointer to the language specific callback function
122 		 // eg, PyObject *pyfunc
123 		 void *threadState;		// pointer to the language specific thread state
124 		 // eg, PyThreadState *threadState
125 		 void *extra;			// currently used to store a switch_file_handle_t
126 		 char *funcargs;		// extra string that will be passed to callback function
127 	 } input_callback_state_t;
128 
129 	 typedef enum {
130 		 S_HUP = (1 << 0),
131 		 S_FREE = (1 << 1),
132 		 S_RDLOCK = (1 << 2)
133 	 } session_flag_t;
134 
135      class DTMF {
136 	 public:
137 		 char digit;
138 		 uint32_t duration;
139 		 SWITCH_DECLARE_CONSTRUCTOR DTMF(char idigit, uint32_t iduration = SWITCH_DEFAULT_DTMF_DURATION);
140 		 virtual SWITCH_DECLARE_CONSTRUCTOR ~DTMF();
141      };
142 
143 	 class Stream {
144 	   protected:
145 		 switch_stream_handle_t mystream;
146 		 switch_stream_handle_t *stream_p;
147 		 int mine;
148 	   public:
149 		 SWITCH_DECLARE_CONSTRUCTOR Stream(void);
150 		 SWITCH_DECLARE_CONSTRUCTOR Stream(switch_stream_handle_t *);
151 		 virtual SWITCH_DECLARE_CONSTRUCTOR ~ Stream();
152 		 SWITCH_DECLARE(const char *) read(int *len);
153 		 SWITCH_DECLARE(void) write(const char *data);
154 		 SWITCH_DECLARE(void) raw_write(const char *data, int len);
155 		 SWITCH_DECLARE(const char *) get_data(void);
156 	 };
157 
158 	 class Event {
159 	   protected:
160 	   public:
161 		 switch_event_t *event;
162 		 char *serialized_string;
163 		 int mine;
164 
165 		 SWITCH_DECLARE_CONSTRUCTOR Event(const char *type, const char *subclass_name = NULL);
166 		 SWITCH_DECLARE_CONSTRUCTOR Event(switch_event_t *wrap_me, int free_me = 0);
167 		 virtual SWITCH_DECLARE_CONSTRUCTOR ~ Event();
168 		 SWITCH_DECLARE(int) chat_execute(const char *app, const char *data = NULL);
169 		 SWITCH_DECLARE(int) chat_send(const char *dest_proto = NULL);
170 		 SWITCH_DECLARE(const char *) serialize(const char *format = NULL);
171 		 SWITCH_DECLARE(bool) setPriority(switch_priority_t priority = SWITCH_PRIORITY_NORMAL);
172 		 SWITCH_DECLARE(const char *) getHeader(const char *header_name);
173 		 SWITCH_DECLARE(char *) getBody(void);
174 		 SWITCH_DECLARE(const char *) getType(void);
175 		 SWITCH_DECLARE(bool) addBody(const char *value);
176 		 SWITCH_DECLARE(bool) addHeader(const char *header_name, const char *value);
177 		 SWITCH_DECLARE(bool) delHeader(const char *header_name);
178 		 SWITCH_DECLARE(bool) fire(void);
179 
180 	 };
181 
182      class EventConsumer {
183 	 protected:
184 		 switch_memory_pool_t *pool;
185 		 int ready;
186 	 public:
187 		 switch_queue_t *events;
188 		 switch_event_types_t e_event_id;
189 		 char *e_callback;
190 		 char *e_subclass_name;
191 		 char *e_cb_arg;
192 		 switch_event_node_t *enodes[SWITCH_EVENT_ALL + 1];
193 		 uint32_t node_index;
194 
195 		 SWITCH_DECLARE_CONSTRUCTOR EventConsumer(const char *event_name = NULL, const char *subclass_name = "", int len = 5000);
196 		 SWITCH_DECLARE_CONSTRUCTOR ~ EventConsumer();
197 		 SWITCH_DECLARE(int) bind(const char *event_name, const char *subclass_name = "");
198 		 SWITCH_DECLARE(Event *) pop(int block = 0, int timeout = 0);
199 		 SWITCH_DECLARE(void) cleanup();
200 	 };
201 
202 #ifdef SWIG
203 	 class CoreSession {
204 #else
205 	 class SWITCH_DECLARE_CLASS CoreSession {
206 #endif
207 	   protected:
208 		 switch_input_args_t args;	// holds ptr to cb function and input_callback_state struct
209 		 // which has a language specific callback function
210 		 switch_input_args_t *ap;	// ptr to args .. (is this really needed?)
211 		 // instead set them here first
212 		 char *xml_cdr_text;
213 		 void store_file_handle(switch_file_handle_t *fh);
214 		 void *on_hangup;		// language specific callback function, cast as void *
215 		 switch_file_handle_t *fhp;
216 		 char dtmf_buf[512];
217 
218 	   public:
219 		 SWITCH_DECLARE_CONSTRUCTOR CoreSession();
220 		 SWITCH_DECLARE_CONSTRUCTOR CoreSession(char *nuuid, CoreSession *a_leg = NULL);
221 		 SWITCH_DECLARE_CONSTRUCTOR CoreSession(switch_core_session_t *new_session);
222 		 virtual SWITCH_DECLARE_CONSTRUCTOR ~ CoreSession();
223 		 switch_core_session_t *session;
224 		 switch_channel_t *channel;
225 		 unsigned int flags;
226 		 int allocated;
227 		 input_callback_state cb_state;	// callback state, always pointed to by the buf
228 		 // field in this->args
229 		 switch_channel_state_t hook_state;	// store hookstate for on_hangup callback
230 		 switch_call_cause_t cause;
231 
232 		 char *uuid;
233 		 char *tts_name;
234 		 char *voice_name;
235 
236 		 SWITCH_DECLARE(int) insertFile(const char *file, const char *insert_file, int sample_point);
237 		 SWITCH_DECLARE(int) answer();
238 		 SWITCH_DECLARE(int) print(char *txt);
239 		 SWITCH_DECLARE(int) preAnswer();
240 		 SWITCH_DECLARE(void) hangup(const char *cause = "normal_clearing");
241 		 SWITCH_DECLARE(void) hangupState(void);
242 		 SWITCH_DECLARE(void) setVariable(char *var, char *val);
243 		 SWITCH_DECLARE(void) setPrivate(char *var, void *val);
244 		 SWITCH_DECLARE(void *) getPrivate(char *var);
245 		 SWITCH_DECLARE(const char *) getVariable(char *var);
246 		 SWITCH_DECLARE(switch_status_t) process_callback_result(char *result);
247 		 SWITCH_DECLARE(void) say(const char *tosay, const char *module_name, const char *say_type, const char *say_method,
248 								  const char *say_gender = NULL);
249 		 SWITCH_DECLARE(void) sayPhrase(const char *phrase_name, const char *phrase_data = "", const char *phrase_lang = NULL);
250 		 SWITCH_DECLARE(const char *) hangupCause();
251 		 SWITCH_DECLARE(const char *) getState();
252 
253 	/** \brief Record to a file
254 	 * \param file_name
255 	 * \param <[max_len]> maximum length of the recording in seconds
256 	 * \param <[silence_threshold]> energy level audio must fall below
257 	 *        to be considered silence (500 is a good starting point).
258 	 * \param <[silence_secs]> seconds of silence to interrupt the record.
259 	 */
260 		 SWITCH_DECLARE(int) recordFile(char *file_name, int time_limit = 0, int silence_threshold = 0, int silence_hits = 0);
261 
262 	/** \brief Set attributes of caller data for purposes of outgoing calls
263 	 * \param var - the variable name, eg, "caller_id_name"
264 	 * \param val - the data to set, eg, "bob"
265 	 */
266 
267 	/** \brief Originate a call to a destination
268 	 *
269 	 * \param a_leg_session - the session where the call is originating from
270 	 *                        and also the session in which _this_ session was
271 	 *                        created
272 	 * \param dest - a string representing destination, eg, sofia/mydomain.com/foo\@bar.com
273 	 * \param timeout - time to wait for call to be answered
274 	 * \return an int status code indicating success or failure
275 	 *
276 	 */
277 		 SWITCH_DECLARE(int) originate(CoreSession * a_leg_session, char *dest, int timeout = 60, switch_state_handler_table_t *handlers = NULL);
278 
279 
280 		 SWITCH_DECLARE(virtual void) destroy(void);
281 
282 	/** \brief set a DTMF callback function
283 	 *
284 	 * The DTMF callback function will be set and persist
285 	 * for the life of the session, and be called when a dtmf
286 	 * is pressed by user during streamfile(), collectDigits(), and
287 	 * certain other methods are executing.
288 	 *
289 	 */
290 		 SWITCH_DECLARE(void) setDTMFCallback(void *cbfunc, char *funcargs);
291 
292 		 SWITCH_DECLARE(int) speak(char *text);
293 		 SWITCH_DECLARE(void) set_tts_parms(char *tts_name, char *voice_name);
294 		 SWITCH_DECLARE(void) set_tts_params(char *tts_name, char *voice_name);
295 
296 	/**
297 	 * For timeout milliseconds, call the dtmf function set previously
298 	 * by setDTMFCallback whenever a dtmf or event is received
299 	 */
300 		 SWITCH_DECLARE(int) collectDigits(int abs_timeout);
301 		 SWITCH_DECLARE(int) collectDigits(int digit_timeout, int abs_timeout);
302 
303 	/**
304 	 * Collect up to maxdigits digits worth of digits
305 	 * and store them in dtmf_buf.  In the case of mod_python, the
306 	 * dtmf_buf parameter is configured to act as a _return_ value,
307 	 * (see mod_python.i).  This does NOT call any callbacks upon
308 	 * receiving dtmf digits.  For that, use collectDigits.
309 	 */
310 		 SWITCH_DECLARE(char *) getDigits(int maxdigits, char *terminators, int timeout);
311 		 SWITCH_DECLARE(char *) getDigits(int maxdigits, char *terminators, int timeout, int interdigit);
312 		 SWITCH_DECLARE(char *) getDigits(int maxdigits, char *terminators, int timeout, int interdigit, int abstimeout);
313 		 SWITCH_DECLARE(int) transfer(char *extension, char *dialplan = NULL, char *context = NULL);
314 
315 
316 		 SWITCH_DECLARE(char *) read(int min_digits, int max_digits,
317 									 const char *prompt_audio_file, int timeout, const char *valid_terminators, int digit_timeout = 0);
318 
319 
320 		SWITCH_DECLARE(void) detectSpeech(char *arg0, char *arg1 = NULL, char *arg2 = NULL, char *arg3 = NULL);
321 
322 
323 	/** \brief Play a file into channel and collect dtmfs
324 	 *
325 	 * See API docs in switch_ivr.h: switch_play_and_get_digits(..)
326 	 *
327 	 * NOTE: this does not call any dtmf callbacks set by
328 	 *       setDTMFCallback(..) as it uses its own internal callback
329 	 *       handler.
330 	 */
331 		 SWITCH_DECLARE(char *) playAndGetDigits(int min_digits,
332 												 int max_digits,
333 												 int max_tries,
334 												 int timeout, char *terminators, char *audio_files, char *bad_input_audio_files,
335 												 char *digits_regex, const char *var_name = NULL, int digit_timeout = 0,
336 												 const char *transfer_on_failure = NULL);
337 
338 
339 	/** \brief Play a file and detect speech
340 	 * See API docs switch_ivr_play_and_detect_speech(...)
341 	 */
342 
343 		SWITCH_DECLARE(char *) playAndDetectSpeech(char *file, char *engine, char *grammar);
344 
345 
346 	/** \brief Play a file that resides on disk into the channel
347 	 *
348 	 * \param file - the path to the .wav/.mp3 to be played
349 	 * \param starting_sample_count - the index of the sample to
350 	 *                                start playing from
351 	 * \return an int status code indicating success or failure
352 	 *
353 	 */
354 		 SWITCH_DECLARE(int) streamFile(char *file, int starting_sample_count = 0);
355 		 SWITCH_DECLARE(int) sleep(int ms, int sync=0);
356 
357 	/** \brief flush any pending events
358 	 */
359 		 SWITCH_DECLARE(int) flushEvents();
360 
361 	/** \brief flush any pending digits
362 	 */
363 		 SWITCH_DECLARE(int) flushDigits();
364 
365 		 SWITCH_DECLARE(int) setAutoHangup(bool val);
366 
367 	/** \brief Set the hangup callback function
368 	 * \param hangup_func - language specific function ptr cast into void *
369 	 */
370 		 SWITCH_DECLARE(void) setHangupHook(void *hangup_func);
371 
372 		 SWITCH_DECLARE(bool) ready();
373 		 SWITCH_DECLARE(bool) bridged();
374 		 SWITCH_DECLARE(bool) answered();
375 		 SWITCH_DECLARE(bool) mediaReady();
376 
377 		 SWITCH_DECLARE(void) waitForAnswer(CoreSession *calling_session);
378 
379 		 SWITCH_DECLARE(void) execute(const char *app, const char *data = NULL);
380 
381 		 SWITCH_DECLARE(void) sendEvent(Event * sendME);
382 
383 		 SWITCH_DECLARE(void) setEventData(Event * e);
384 		 SWITCH_DECLARE(char *) getXMLCDR();
385 
386 		 virtual bool begin_allow_threads() = 0;
387 		 virtual bool end_allow_threads() = 0;
388 
389 	/** \brief Get the uuid of this session
390 	 * \return the uuid of this session
391 	 */
get_uuid()392 		 const char *get_uuid() const {
393 			 return uuid ? uuid : (char *) "uninitialized";
394 		 };
395 
396 	/** \brief Get the callback function arguments associated with this session
397 	 * \return a const reference to the callback function arguments
398 	 */
get_cb_args()399 		 const switch_input_args_t &get_cb_args() const {
400 			 return args;
401 		 };
402 
403 	/** \brief Callback to the language specific hangup callback
404 	 */
405 		 virtual void check_hangup_hook() = 0;
406 
407 		 virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype) = 0;
408 
409 		 SWITCH_DECLARE(void) consoleLog(char *level_str, char *msg);
410 		 SWITCH_DECLARE(void) consoleLog2(char *level_str, char *file, char *func, int line, char *msg);
411 	 };
412 
413 
414 /* ---- functions not bound to CoreSession instance ----- */
415 
416 SWITCH_DECLARE(void) console_log(char *level_str, char *msg);
417 SWITCH_DECLARE(void) console_log2(char *level_str, char *file, char *func, int line, char *msg);
418 SWITCH_DECLARE(void) console_clean_log(char *msg);
419 SWITCH_DECLARE(void) switch_msleep(unsigned ms);
420 
421 /** \brief bridge the audio of session_b into session_a
422  *
423  * NOTE: the stuff regarding the dtmf callback might be completely
424  *       wrong and has not been reviewed or tested
425  */
426 SWITCH_DECLARE(void) bridge(CoreSession & session_a, CoreSession & session_b);
427 
428 
429 /** \brief the actual hangup hook called back by freeswitch core
430  *         which in turn gets the session and calls the appropriate
431  *         instance method to complete the callback.
432  */
433 SWITCH_DECLARE_NONSTD(switch_status_t) hanguphook(switch_core_session_t *session);
434 
435 SWITCH_DECLARE_NONSTD(switch_status_t) dtmf_callback(switch_core_session_t *session,
436 													 void *input, switch_input_type_t itype, void *buf, unsigned int buflen);
437 
438 
439 
440 #ifdef __cplusplus
441 }
442 #endif
443 
444 #endif
445 /* For Emacs:
446  * Local Variables:
447  * mode:c
448  * indent-tabs-mode:t
449  * tab-width:4
450  * c-basic-offset:4
451  * End:
452  * For VIM:
453  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
454  */
455