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