diff --git a/src/include/switch_cpp.h b/src/include/switch_cpp.h index 57f35aeeb3..86bb200038 100644 --- a/src/include/switch_cpp.h +++ b/src/include/switch_cpp.h @@ -11,6 +11,50 @@ extern "C" { #include +// +// 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 , (C) 2007 +// +// Copyright: See COPYING file that comes with this distribution +// + + +#ifndef SWITCHTOMEMPOOL +#define SWITCHTOMEMPOOL +class SwitchToMempool { + public: + SwitchToMempool() { } + SwitchToMempool(switch_memory_pool_t *mem) { memorypool = mem; } + void *operator new(switch_size_t num_bytes, switch_memory_pool_t *mem) + { + void *ptr = switch_core_alloc(mem, (switch_size_t) num_bytes); + return ptr; + } + protected: + switch_memory_pool_t *memorypool; +}; +#endif + + +/* + +Overview: once you create an object that inherits this class, since + the memory pool is then a class data member, you can continue to + allocate objects from the memory pool. + objects from within the class + +Notes on usage: + +1. The derived class will need to also overload the ctor so that it accepts a memory pool object as a parameter. +2. Instantiation of a class would then look something like this: Foo *bar = new(memory_pool) Foo(memory_pool); + +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... + +*/ + void console_log(char *level_str, char *msg); void console_clean_log(char *msg); @@ -40,6 +84,12 @@ typedef struct input_callback_state { char *funcargs; // extra string that will be passed to callback function } input_callback_state_t; +typedef enum { + S_HUP = (1 << 0), + S_FREE = (1 << 1), + S_RDLOCK = (1 << 2) +} session_flag_t; + class CoreSession { protected: @@ -52,6 +102,9 @@ class CoreSession { char *tts_name; char *voice_name; void store_file_handle(switch_file_handle_t *fh); + void *on_hangup; // language specific callback function, cast as void * + + public: CoreSession(); CoreSession(char *uuid); @@ -59,12 +112,14 @@ class CoreSession { virtual ~CoreSession(); switch_core_session_t *session; switch_channel_t *channel; + unsigned int flags; input_callback_state cb_state; // callback state, always pointed to by the buf // field in this->args + switch_channel_state_t hook_state; // store hookstate for on_hangup callback int answer(); int preAnswer(); - void hangup(char *cause); + virtual void hangup(char *cause); void setVariable(char *var, char *val); char *getVariable(char *var); @@ -118,19 +173,16 @@ class CoreSession { * is pressed by user during playFile(), streamfile(), and * certain other methods are executing. * - * Note that language specific sessions might need to create - * their own version of this with a slightly different signature - * (as done in freeswitch_python.h) */ - void setDTMFCallback(switch_input_callback_function_t cb, - void *buf, - uint32_t buflen); + void setDTMFCallback(void *cbfunc, char *funcargs); + int speak(char *text); void set_tts_parms(char *tts_name, char *voice_name); int getDigits(char *dtmf_buf, - int len, + int buflen, + int maxdigits, char *terminators, char *terminator, int timeout); @@ -165,11 +217,26 @@ class CoreSession { */ int streamfile(char *file, int starting_sample_count); + /** \brief flush any pending events + */ + int flushEvents(); + + /** \brief flush any pending digits + */ + int flushDigits(); + + int setAutoHangup(bool val); + + /** \brief Set the hangup callback function + * \param hangup_func - language specific function ptr cast into void * + */ + void setHangupHook(void *hangup_func); + bool ready(); void execute(char *app, char *data); - virtual void begin_allow_threads(); - virtual void end_allow_threads(); + virtual bool begin_allow_threads() = 0; + virtual bool end_allow_threads() = 0; /** \brief Get the uuid of this session * \return the uuid of this session @@ -181,6 +248,12 @@ class CoreSession { */ const switch_input_args_t& get_cb_args() const { return args; }; + /** \brief Callback to the language specific hangup callback + */ + virtual void check_hangup_hook() = 0; + + virtual switch_status_t run_dtmf_callback(void *input, + switch_input_type_t itype) = 0; }; @@ -200,6 +273,19 @@ void api_reply_delete(char *reply); void bridge(CoreSession &session_a, CoreSession &session_b); +/** \brief the actual hangup hook called back by freeswitch core + * which in turn gets the session and calls the appropriate + * instance method to complete the callback. + */ +switch_status_t hanguphook(switch_core_session_t *session); + +switch_status_t dtmf_callback(switch_core_session_t *session, + void *input, + switch_input_type_t itype, + void *buf, + unsigned int buflen); + + #ifdef __cplusplus } #endif diff --git a/src/mod/languages/mod_python/freeswitch.py b/src/mod/languages/mod_python/freeswitch.py index 046ce729f0..10721b4b17 100644 --- a/src/mod/languages/mod_python/freeswitch.py +++ b/src/mod/languages/mod_python/freeswitch.py @@ -80,16 +80,16 @@ class input_callback_state_t(_object): input_callback_state_t_swigregister = _freeswitch.input_callback_state_t_swigregister input_callback_state_t_swigregister(input_callback_state_t) +S_HUP = _freeswitch.S_HUP +S_FREE = _freeswitch.S_FREE +S_RDLOCK = _freeswitch.S_RDLOCK class CoreSession(_object): __swig_setmethods__ = {} __setattr__ = lambda self, name, value: _swig_setattr(self, CoreSession, name, value) __swig_getmethods__ = {} __getattr__ = lambda self, name: _swig_getattr(self, CoreSession, name) + def __init__(self): raise AttributeError, "No constructor defined" __repr__ = _swig_repr - def __init__(self, *args): - this = _freeswitch.new_CoreSession(*args) - try: self.this.append(this) - except: self.this = this __swig_destroy__ = _freeswitch.delete_CoreSession __del__ = lambda self : None; __swig_setmethods__["session"] = _freeswitch.CoreSession_session_set @@ -98,9 +98,15 @@ class CoreSession(_object): __swig_setmethods__["channel"] = _freeswitch.CoreSession_channel_set __swig_getmethods__["channel"] = _freeswitch.CoreSession_channel_get if _newclass:channel = _swig_property(_freeswitch.CoreSession_channel_get, _freeswitch.CoreSession_channel_set) + __swig_setmethods__["flags"] = _freeswitch.CoreSession_flags_set + __swig_getmethods__["flags"] = _freeswitch.CoreSession_flags_get + if _newclass:flags = _swig_property(_freeswitch.CoreSession_flags_get, _freeswitch.CoreSession_flags_set) __swig_setmethods__["cb_state"] = _freeswitch.CoreSession_cb_state_set __swig_getmethods__["cb_state"] = _freeswitch.CoreSession_cb_state_get if _newclass:cb_state = _swig_property(_freeswitch.CoreSession_cb_state_get, _freeswitch.CoreSession_cb_state_set) + __swig_setmethods__["hook_state"] = _freeswitch.CoreSession_hook_state_set + __swig_getmethods__["hook_state"] = _freeswitch.CoreSession_hook_state_get + if _newclass:hook_state = _swig_property(_freeswitch.CoreSession_hook_state_get, _freeswitch.CoreSession_hook_state_set) def answer(*args): return _freeswitch.CoreSession_answer(*args) def preAnswer(*args): return _freeswitch.CoreSession_preAnswer(*args) def hangup(*args): return _freeswitch.CoreSession_hangup(*args) @@ -117,17 +123,26 @@ class CoreSession(_object): def transfer(*args): return _freeswitch.CoreSession_transfer(*args) def playAndGetDigits(*args): return _freeswitch.CoreSession_playAndGetDigits(*args) def streamfile(*args): return _freeswitch.CoreSession_streamfile(*args) + def flushEvents(*args): return _freeswitch.CoreSession_flushEvents(*args) + def flushDigits(*args): return _freeswitch.CoreSession_flushDigits(*args) + def setAutoHangup(*args): return _freeswitch.CoreSession_setAutoHangup(*args) + def setHangupHook(*args): return _freeswitch.CoreSession_setHangupHook(*args) def ready(*args): return _freeswitch.CoreSession_ready(*args) def execute(*args): return _freeswitch.CoreSession_execute(*args) def begin_allow_threads(*args): return _freeswitch.CoreSession_begin_allow_threads(*args) def end_allow_threads(*args): return _freeswitch.CoreSession_end_allow_threads(*args) def get_uuid(*args): return _freeswitch.CoreSession_get_uuid(*args) def get_cb_args(*args): return _freeswitch.CoreSession_get_cb_args(*args) + def check_hangup_hook(*args): return _freeswitch.CoreSession_check_hangup_hook(*args) + def run_dtmf_callback(*args): return _freeswitch.CoreSession_run_dtmf_callback(*args) CoreSession_swigregister = _freeswitch.CoreSession_swigregister CoreSession_swigregister(CoreSession) bridge = _freeswitch.bridge -PythonDTMFCallback = _freeswitch.PythonDTMFCallback +hanguphook = _freeswitch.hanguphook +dtmf_callback = _freeswitch.dtmf_callback +S_SWAPPED_IN = _freeswitch.S_SWAPPED_IN +S_SWAPPED_OUT = _freeswitch.S_SWAPPED_OUT class PySession(CoreSession): __swig_setmethods__ = {} for _s in [CoreSession]: __swig_setmethods__.update(getattr(_s,'__swig_setmethods__',{})) @@ -143,8 +158,12 @@ class PySession(CoreSession): __swig_destroy__ = _freeswitch.delete_PySession __del__ = lambda self : None; def setDTMFCallback(*args): return _freeswitch.PySession_setDTMFCallback(*args) + def setHangupHook(*args): return _freeswitch.PySession_setHangupHook(*args) + def check_hangup_hook(*args): return _freeswitch.PySession_check_hangup_hook(*args) + def hangup(*args): return _freeswitch.PySession_hangup(*args) def begin_allow_threads(*args): return _freeswitch.PySession_begin_allow_threads(*args) def end_allow_threads(*args): return _freeswitch.PySession_end_allow_threads(*args) + def run_dtmf_callback(*args): return _freeswitch.PySession_run_dtmf_callback(*args) PySession_swigregister = _freeswitch.PySession_swigregister PySession_swigregister(PySession) diff --git a/src/mod/languages/mod_python/freeswitch_python.cpp b/src/mod/languages/mod_python/freeswitch_python.cpp index bbfdc27d7f..89c3727ec3 100644 --- a/src/mod/languages/mod_python/freeswitch_python.cpp +++ b/src/mod/languages/mod_python/freeswitch_python.cpp @@ -1,7 +1,7 @@ #include "freeswitch_python.h" #define sanity_check(x) do { if (!session) { switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "session is not initalized\n"); return x;}} while(0) -#define init_vars() do { caller_profile.source = "mod_python"; } while(0) +#define init_vars() do { caller_profile.source = "mod_python"; swapstate = S_SWAPPED_IN; } while(0) PySession::PySession() : CoreSession() { @@ -24,80 +24,107 @@ void PySession::setDTMFCallback(PyObject *pyfunc, char *funcargs) sanity_check(); if (!PyCallable_Check(pyfunc)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF function is not a python function."); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF function is not a python function.\n"); + return; } - else { - cb_state.funcargs = funcargs; - cb_state.function = (void *) pyfunc; + Py_XINCREF(pyfunc); + CoreSession::setDTMFCallback((void *) pyfunc, funcargs); - args.buf = &cb_state; - args.buflen = sizeof(cb_state); // not sure what this is used for, copy mod_spidermonkey - - // we cannot set the actual callback to a python function, because - // the callback is a function pointer with a specific signature. - // so, set it to the following c function which will act as a proxy, - // finding the python callback in the args callback args structure - args.input_callback = PythonDTMFCallback; // defined in mod_python.i - ap = &args; +} + +void PySession::setHangupHook(PyObject *pyfunc) { + + if (!PyCallable_Check(pyfunc)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Hangup hook is not a python function.\n"); + return; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmf callback was set, pyfunc: %p. cb_state: %p\n", pyfunc, &cb_state); + // without this Py_XINCREF, there will be segfaults. basically the python + // interpreter will not know that it should not GC this object. + // callback example: http://docs.python.org/ext/callingPython.html + Py_XINCREF(pyfunc); + CoreSession::setHangupHook((void *) pyfunc); } -void PySession::begin_allow_threads(void) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::begin_allow_threads() called\n"); - - // swap out threadstate and store in instance variable - threadState = (void *) PyEval_SaveThread(); - cb_state.threadState = threadState; - args.buf = &cb_state; - ap = &args; -} - -void PySession::end_allow_threads(void) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::end_allow_threads() called\n"); - // swap in threadstate from instance variable saved earlier - PyEval_RestoreThread(((PyThreadState *)threadState)); -} - -PySession::~PySession() { - // Should we do any cleanup here? - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::~PySession desctructor\n"); -} - - -/* ----- functions not bound to PySession instance ------ */ - - -switch_status_t PythonDTMFCallback(switch_core_session_t *session, - void *input, - switch_input_type_t itype, - void *buf, - unsigned int buflen) -{ - PyObject *func, *arglist; +void PySession::check_hangup_hook() { + PyObject *func; PyObject *result; char *resultStr; - char *funcargs; - input_callback_state_t *cb_state; - switch_file_handle_t *fh = NULL; - PyThreadState *threadState = NULL; + bool did_swap_in = false; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "check_hangup_hook called\n"); + + if (!session) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No valid session\n"); + return; + } + + // The did_swap_in boolean was added to fix the following problem: + // Design flaw - we swap in threadstate based on the assumption that thread state + // is currently _swapped out_ when this hangup hook is called. However, nothing known to + // guarantee that, and if thread state is already swapped in when this is invoked, + // bad things will happen. + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "check hangup hook end_allow_threads\n"); + did_swap_in = end_allow_threads(); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PythonDTMFCallback\n"); + if (on_hangup == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "on_hangup is null\n"); + return; + } - if (!buf) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buf pointer is null"); + func = (PyObject *) on_hangup; + + // TODO: to match js implementation, should pass the _python_ PySession + // object instance wrapping this C++ PySession instance. but how do we do that? + // for now, pass the uuid since its better than nothing + PyObject* func_arg = Py_BuildValue("(s)", uuid); + + result = PyEval_CallObject(func, func_arg); + Py_XDECREF(func_arg); + + if (result) { + resultStr = (char *) PyString_AsString(result); + // currently just ignore the result + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to call python hangup callback\n"); + PyErr_Print(); + PyErr_Clear(); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "check hangup hook begin_allow_threads\n"); + if (did_swap_in) { + begin_allow_threads(); + } + + Py_XDECREF(result); + +} + +switch_status_t PySession::run_dtmf_callback(void *input, + switch_input_type_t itype) { + + PyObject *func, *arglist; + PyObject *pyresult; + char *resultStr; + char *funcargs; + switch_file_handle_t *fh = NULL; + bool did_swap_in = false; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "run_dtmf_callback\n"); + + + if (!cb_state.function) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "cb_state->function is null\n"); return SWITCH_STATUS_FALSE; - } - - cb_state = (input_callback_state *) buf; + } - func = (PyObject *) cb_state->function; + func = (PyObject *) cb_state.function; if (!func) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cb_state->function is null\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "cb_state->function is null\n"); return SWITCH_STATUS_FALSE; } else { @@ -108,7 +135,7 @@ switch_status_t PythonDTMFCallback(switch_core_session_t *session, return SWITCH_STATUS_FALSE; } - funcargs = (char *) cb_state->funcargs; + funcargs = (char *) cb_state.funcargs; arglist = Py_BuildValue("(sis)", input, itype, funcargs); if (!arglist) { @@ -116,36 +143,127 @@ switch_status_t PythonDTMFCallback(switch_core_session_t *session, return SWITCH_STATUS_FALSE; } - threadState = (PyThreadState *) cb_state->threadState; - if (!threadState) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error, invalid threadstate\n"); - return SWITCH_STATUS_FALSE; - } - else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "restoring threadstate: %p\n", threadState); - } - - PyEval_RestoreThread(threadState); // nasty stuff happens when py interp has no thread state - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "restored threadstate, calling python function: %p\n", func); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "run_dtmf_callback end_allow_threads\n"); + did_swap_in = end_allow_threads(); - result = PyEval_CallObject(func, arglist); + pyresult = PyEval_CallObject(func, arglist); - threadState = PyEval_SaveThread(); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "called python function\n"); - - Py_DECREF(arglist); // Trash arglist - if (result && result != Py_None) { - resultStr = (char *) PyString_AsString(result); - Py_XDECREF(result); - return process_callback_result(resultStr, cb_state, session); + Py_XDECREF(arglist); // Trash arglist + if (pyresult && pyresult != Py_None) { + resultStr = (char *) PyString_AsString(pyresult); + switch_status_t cbresult = process_callback_result(resultStr, &cb_state, session); + return cbresult; } else { - return SWITCH_STATUS_FALSE; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error calling python callback\n"); + PyErr_Print(); + PyErr_Clear(); } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "run_dtmf_callback begin_allow_threads\n"); + if (did_swap_in) { + begin_allow_threads(); + } + Py_XDECREF(pyresult); + + return SWITCH_STATUS_SUCCESS; + +} + +bool PySession::begin_allow_threads(void) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::begin_allow_threads() called\n"); + + // swap out threadstate and store in instance variable + switch_channel_t *channel = switch_core_session_get_channel(session); + PyThreadState *swapin_tstate = (PyThreadState *) switch_channel_get_private(channel, "SwapInThreadState"); + // so lets assume the thread state was swapped in when the python script was started, + // therefore swapin_tstate will be NULL (because there is nothing to swap in, since its + // _already_ swapped in.) + if (swapin_tstate == NULL) { + // currently swapped in + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Threadstate swap-out!\n"); + swapin_tstate = PyEval_SaveThread(); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "swapin_tstate: %p\n", swapin_tstate); + // give future swapper-inners something to actually swap in + switch_channel_set_private(channel, "SwapInThreadState", (void *) swapin_tstate); + cb_state.threadState = threadState; // TODO: get rid of this + args.buf = &cb_state; + ap = &args; + return true; + + } + else { + // currently swapped out + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Threadstate already swapd-out! Skipping\n"); + return false; + } + +} + +bool PySession::end_allow_threads(void) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::end_allow_threads() called\n"); + // swap in threadstate from instance variable saved earlier + switch_channel_t *channel = switch_core_session_get_channel(session); + PyThreadState *swapin_tstate = (PyThreadState *) switch_channel_get_private(channel, "SwapInThreadState"); + if (swapin_tstate == NULL) { + // currently swapped in + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Threadstate double swap-in! Skipping\n"); + return false; + } + else { + // currently swapped out + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Threadstate swap-in!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "swapin_tstate: %p\n", swapin_tstate); + PyEval_RestoreThread(swapin_tstate); + // dont give any swapper-inners the opportunity to do a double swap + switch_channel_set_private(channel, "SwapInThreadState", NULL); + return true; + } + + +} + +void PySession::hangup(char *cause) { + + + // since we INCREF'd this function pointer earlier (so the py gc didnt reclaim it) + // we have to DECREF it, or else the PySession dtor will never get called and + // a zombie channel will be left over using up resources + + if (cb_state.function != NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "xdecref on cb_state_function\n"); + PyObject * func = (PyObject *) cb_state.function; + Py_XDECREF(func); + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "cb_state.function is null\n"); + } + + + CoreSession::hangup(cause); + +} + + +PySession::~PySession() { + // Should we do any cleanup here? + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::~PySession started\n"); + + if (on_hangup) { + PyObject * func = (PyObject *) on_hangup; + Py_XDECREF(func); + } + + + if (cb_state.function != NULL) { + PyObject * func = (PyObject *) cb_state.function; + Py_XDECREF(func); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::~PySession finished\n"); + } @@ -154,3 +272,6 @@ switch_status_t PythonDTMFCallback(switch_core_session_t *session, + + + diff --git a/src/mod/languages/mod_python/freeswitch_python.h b/src/mod/languages/mod_python/freeswitch_python.h index a0bc60c901..66ca177f1a 100644 --- a/src/mod/languages/mod_python/freeswitch_python.h +++ b/src/mod/languages/mod_python/freeswitch_python.h @@ -14,12 +14,10 @@ extern "C" { -switch_status_t PythonDTMFCallback(switch_core_session *session, - void *input, - switch_input_type_t itype, - void *buf, - unsigned int buflen); - +typedef enum { + S_SWAPPED_IN = (1 << 0), + S_SWAPPED_OUT = (1 << 1) +} swap_state_t; void console_log(char *level_str, char *msg); void console_clean_log(char *msg); @@ -29,14 +27,21 @@ void api_reply_delete(char *reply); class PySession : public CoreSession { private: void *threadState; + int swapstate; public: PySession(); PySession(char *uuid); PySession(switch_core_session_t *session); ~PySession(); void setDTMFCallback(PyObject *pyfunc, char *funcargs); - void begin_allow_threads(); - void end_allow_threads(); + void setHangupHook(PyObject *pyfunc); + void check_hangup_hook(); + void hangup(char *cause); + bool begin_allow_threads(); + bool end_allow_threads(); + + switch_status_t run_dtmf_callback(void *input, + switch_input_type_t itype); }; diff --git a/src/mod/languages/mod_python/mod_python.c b/src/mod/languages/mod_python/mod_python.c index 9707e8259f..07e477d31c 100644 --- a/src/mod/languages/mod_python/mod_python.c +++ b/src/mod/languages/mod_python/mod_python.c @@ -49,11 +49,12 @@ PyThreadState *mainThreadState = NULL; void init_freeswitch(void); static switch_api_interface_t python_run_interface; + SWITCH_MODULE_LOAD_FUNCTION(mod_python_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_python_shutdown); SWITCH_MODULE_DEFINITION(mod_python, mod_python_load, mod_python_shutdown, NULL); -static void eval_some_python(char *uuid, char *args) +static void eval_some_python(char *uuid, char *args, switch_core_session_t *session) { PyThreadState *tstate = NULL; char *dupargs = NULL; @@ -92,6 +93,11 @@ static void eval_some_python(char *uuid, char *args) // swap in thread state PyEval_AcquireThread(tstate); + if (session) { + // record the fact that thread state is swapped in + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_set_private(channel, "SwapInThreadState", NULL); + } init_freeswitch(); // import the module @@ -138,7 +144,9 @@ static void eval_some_python(char *uuid, char *args) } // invoke the handler + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call python script \n"); result = PyEval_CallObjectWithKeywords(function, arg, (PyObject *)NULL); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Finished calling python script \n"); // check the result and print out any errors if (!result) { @@ -160,7 +168,29 @@ static void eval_some_python(char *uuid, char *args) Py_XDECREF(result); // swap out thread state - PyEval_ReleaseThread(tstate); + if (session) { + // record the fact that thread state is swapped in + switch_channel_t *channel = switch_core_session_get_channel(session); + PyThreadState *swapin_tstate = (PyThreadState *) switch_channel_get_private(channel, "SwapInThreadState"); + // so lets assume nothing in the python script swapped any thread state in + // or out .. thread state will currently be swapped in, and the SwapInThreadState + // will be null + if (swapin_tstate == NULL) { + // swap it out + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Threadstate mod_python.c swap-out! \n"); + // PyEval_ReleaseThread(cur_tstate); + swapin_tstate = (void *) PyEval_SaveThread(); + switch_channel_set_private(channel, "SwapInThreadState", (void *) swapin_tstate); + } + else { + // thread state is already swapped out, so, nothing for us to do + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "according to chan priv data, already swapped out \n"); + } + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Threadstate mod_python.c swap-out! \n"); + PyEval_ReleaseThread(tstate); + } switch_safe_free(dupargs); @@ -169,7 +199,7 @@ static void eval_some_python(char *uuid, char *args) static void python_function(switch_core_session_t *session, char *data) { - eval_some_python(switch_core_session_get_uuid(session), (char *)data); + eval_some_python(switch_core_session_get_uuid(session), (char *)data, session); } @@ -183,7 +213,7 @@ static void *SWITCH_THREAD_FUNC py_thread_run(switch_thread_t *thread, void *obj switch_memory_pool_t *pool; struct switch_py_thread *pt = (struct switch_py_thread *) obj; - eval_some_python(NULL, strdup(pt->args)); + eval_some_python(NULL, strdup(pt->args), NULL); pool = pt->pool; switch_core_destroy_memory_pool(&pool); diff --git a/src/mod/languages/mod_python/mod_python.i b/src/mod/languages/mod_python/mod_python.i index e7529a18b0..737cf856b9 100644 --- a/src/mod/languages/mod_python/mod_python.i +++ b/src/mod/languages/mod_python/mod_python.i @@ -9,12 +9,16 @@ %cstring_bounded_mutable(char *dtmf_buf, 128); %cstring_bounded_mutable(char *terminator, 8); + /** insert the following includes into generated code so it compiles */ %{ #include "switch_cpp.h" #include "freeswitch_python.h" %} + +%ignore SwitchToMempool; + /** * tell swig to grok everything defined in these header files and * build all sorts of c wrappers and python shadows of the c wrappers. diff --git a/src/mod/languages/mod_python/mod_python_wrap.cpp b/src/mod/languages/mod_python/mod_python_wrap.cpp index 1752bcefb9..beeb43a5a4 100644 --- a/src/mod/languages/mod_python/mod_python_wrap.cpp +++ b/src/mod/languages/mod_python/mod_python_wrap.cpp @@ -2469,14 +2469,14 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_PySession swig_types[1] #define SWIGTYPE_p_char swig_types[2] #define SWIGTYPE_p_input_callback_state swig_types[3] -#define SWIGTYPE_p_switch_channel_t swig_types[4] -#define SWIGTYPE_p_switch_core_session swig_types[5] -#define SWIGTYPE_p_switch_core_session_t swig_types[6] -#define SWIGTYPE_p_switch_input_args_t swig_types[7] -#define SWIGTYPE_p_switch_input_callback_function_t swig_types[8] -#define SWIGTYPE_p_switch_input_type_t swig_types[9] -#define SWIGTYPE_p_switch_status_t swig_types[10] -#define SWIGTYPE_p_uint32_t swig_types[11] +#define SWIGTYPE_p_session_flag_t swig_types[4] +#define SWIGTYPE_p_swap_state_t swig_types[5] +#define SWIGTYPE_p_switch_channel_state_t swig_types[6] +#define SWIGTYPE_p_switch_channel_t swig_types[7] +#define SWIGTYPE_p_switch_core_session_t swig_types[8] +#define SWIGTYPE_p_switch_input_args_t swig_types[9] +#define SWIGTYPE_p_switch_input_type_t swig_types[10] +#define SWIGTYPE_p_switch_status_t swig_types[11] #define SWIGTYPE_p_void swig_types[12] static swig_type_info *swig_types[14]; static swig_module_info swig_module = {swig_types, 13, 0, 0, 0, 0}; @@ -2767,68 +2767,6 @@ SWIG_CanCastAsInteger(double *d, double min, double max) { } -SWIGINTERN int -SWIG_AsVal_long (PyObject *obj, long* val) -{ - if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - long v = PyInt_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { - if (val) *val = (long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_int (PyObject * obj, int *val) -{ - long v; - int res = SWIG_AsVal_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v < INT_MIN || v > INT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = static_cast< int >(v); - } - } - return res; -} - - -SWIGINTERNINLINE PyObject* - SWIG_From_bool (bool value) -{ - return PyBool_FromLong(value ? 1 : 0); -} - - SWIGINTERN int SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) { @@ -2888,6 +2826,101 @@ SWIG_AsVal_unsigned_SS_int (PyObject * obj, unsigned int *val) return res; } + +SWIGINTERNINLINE PyObject* +SWIG_From_unsigned_SS_long (unsigned long value) +{ + return (value > LONG_MAX) ? + PyLong_FromUnsignedLong(value) : PyInt_FromLong(static_cast< long >(value)); +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_unsigned_SS_int (unsigned int value) +{ + return SWIG_From_unsigned_SS_long (value); +} + + +SWIGINTERN int +SWIG_AsVal_long (PyObject *obj, long* val) +{ + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + long v = PyInt_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { + if (val) *val = (long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +SWIGINTERN int +SWIG_AsVal_int (PyObject * obj, int *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < INT_MIN || v > INT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = static_cast< int >(v); + } + } + return res; +} + + +SWIGINTERN int +SWIG_AsVal_bool (PyObject *obj, bool *val) +{ + if (obj == Py_True) { + if (val) *val = true; + return SWIG_OK; + } else if (obj == Py_False) { + if (val) *val = false; + return SWIG_OK; + } else { + long v = 0; + int res = SWIG_AddCast(SWIG_AsVal_long (obj, val ? &v : 0)); + if (SWIG_IsOK(res) && val) *val = v ? true : false; + return res; + } +} + + +SWIGINTERNINLINE PyObject* + SWIG_From_bool (bool value) +{ + return PyBool_FromLong(value ? 1 : 0); +} + #ifdef __cplusplus extern "C" { #endif @@ -3311,103 +3344,6 @@ SWIGINTERN PyObject *input_callback_state_t_swigregister(PyObject *SWIGUNUSEDPAR return SWIG_Py_Void(); } -SWIGINTERN PyObject *_wrap_new_CoreSession__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - CoreSession *result = 0 ; - - if (!PyArg_ParseTuple(args,(char *)":new_CoreSession")) SWIG_fail; - result = (CoreSession *)new CoreSession(); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CoreSession, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_CoreSession__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - CoreSession *result = 0 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:new_CoreSession",&obj0)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_CoreSession" "', argument " "1"" of type '" "char *""'"); - } - arg1 = reinterpret_cast< char * >(buf1); - result = (CoreSession *)new CoreSession(arg1); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CoreSession, SWIG_POINTER_NEW | 0 ); - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) delete[] buf1; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_CoreSession__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; - CoreSession *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:new_CoreSession",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_switch_core_session_t, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_CoreSession" "', argument " "1"" of type '" "switch_core_session_t *""'"); - } - arg1 = reinterpret_cast< switch_core_session_t * >(argp1); - result = (CoreSession *)new CoreSession(arg1); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CoreSession, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_CoreSession(PyObject *self, PyObject *args) { - int argc; - PyObject *argv[2]; - int ii; - - if (!PyTuple_Check(args)) SWIG_fail; - argc = PyObject_Length(args); - for (ii = 0; (ii < argc) && (ii < 1); ii++) { - argv[ii] = PyTuple_GET_ITEM(args,ii); - } - if (argc == 0) { - return _wrap_new_CoreSession__SWIG_0(self, args); - } - if (argc == 1) { - int _v; - void *vptr = 0; - int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_switch_core_session_t, 0); - _v = SWIG_CheckState(res); - if (_v) { - return _wrap_new_CoreSession__SWIG_2(self, args); - } - } - if (argc == 1) { - int _v; - int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0); - _v = SWIG_CheckState(res); - if (_v) { - return _wrap_new_CoreSession__SWIG_1(self, args); - } - } - -fail: - SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_CoreSession'.\n Possible C/C++ prototypes are:\n CoreSession()\n CoreSession(char *)\n CoreSession(switch_core_session_t *)\n"); - return NULL; -} - - SWIGINTERN PyObject *_wrap_delete_CoreSession(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; @@ -3536,6 +3472,59 @@ fail: } +SWIGINTERN PyObject *_wrap_CoreSession_flags_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + unsigned int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + unsigned int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:CoreSession_flags_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_flags_set" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + ecode2 = SWIG_AsVal_unsigned_SS_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CoreSession_flags_set" "', argument " "2"" of type '" "unsigned int""'"); + } + arg2 = static_cast< unsigned int >(val2); + if (arg1) (arg1)->flags = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_CoreSession_flags_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + unsigned int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:CoreSession_flags_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_flags_get" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + result = (unsigned int) ((arg1)->flags); + resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result)); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_CoreSession_cb_state_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; @@ -3589,6 +3578,67 @@ fail: } +SWIGINTERN PyObject *_wrap_CoreSession_hook_state_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + switch_channel_state_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:CoreSession_hook_state_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_hook_state_set" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + { + res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_switch_channel_state_t, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_hook_state_set" "', argument " "2"" of type '" "switch_channel_state_t""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "CoreSession_hook_state_set" "', argument " "2"" of type '" "switch_channel_state_t""'"); + } else { + switch_channel_state_t * temp = reinterpret_cast< switch_channel_state_t * >(argp2); + arg2 = *temp; + if (SWIG_IsNewObj(res2)) delete temp; + } + } + if (arg1) (arg1)->hook_state = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_CoreSession_hook_state_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + switch_channel_state_t result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:CoreSession_hook_state_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_hook_state_get" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + result = ((arg1)->hook_state); + resultobj = SWIG_NewPointerObj((new switch_channel_state_t(static_cast< const switch_channel_state_t& >(result))), SWIGTYPE_p_switch_channel_state_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_CoreSession_answer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; @@ -3960,61 +4010,39 @@ fail: SWIGINTERN PyObject *_wrap_CoreSession_setDTMFCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; - switch_input_callback_function_t arg2 ; - void *arg3 = (void *) 0 ; - uint32_t arg4 ; + void *arg2 = (void *) 0 ; + char *arg3 = (char *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - void *argp2 ; - int res2 = 0 ; + int res2 ; int res3 ; - void *argp4 ; - int res4 = 0 ; + char *buf3 = 0 ; + int alloc3 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OOOO:CoreSession_setDTMFCallback",&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + if (!PyArg_ParseTuple(args,(char *)"OOO:CoreSession_setDTMFCallback",&obj0,&obj1,&obj2)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_setDTMFCallback" "', argument " "1"" of type '" "CoreSession *""'"); } arg1 = reinterpret_cast< CoreSession * >(argp1); - { - res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_switch_input_callback_function_t, 0 | 0); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_setDTMFCallback" "', argument " "2"" of type '" "switch_input_callback_function_t""'"); - } - if (!argp2) { - SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "CoreSession_setDTMFCallback" "', argument " "2"" of type '" "switch_input_callback_function_t""'"); - } else { - switch_input_callback_function_t * temp = reinterpret_cast< switch_input_callback_function_t * >(argp2); - arg2 = *temp; - if (SWIG_IsNewObj(res2)) delete temp; - } + res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_setDTMFCallback" "', argument " "2"" of type '" "void *""'"); } - res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3), 0, 0); + res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3); if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "CoreSession_setDTMFCallback" "', argument " "3"" of type '" "void *""'"); + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "CoreSession_setDTMFCallback" "', argument " "3"" of type '" "char *""'"); } - { - res4 = SWIG_ConvertPtr(obj3, &argp4, SWIGTYPE_p_uint32_t, 0 | 0); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "CoreSession_setDTMFCallback" "', argument " "4"" of type '" "uint32_t""'"); - } - if (!argp4) { - SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "CoreSession_setDTMFCallback" "', argument " "4"" of type '" "uint32_t""'"); - } else { - uint32_t * temp = reinterpret_cast< uint32_t * >(argp4); - arg4 = *temp; - if (SWIG_IsNewObj(res4)) delete temp; - } - } - (arg1)->setDTMFCallback(arg2,arg3,arg4); + arg3 = reinterpret_cast< char * >(buf3); + (arg1)->setDTMFCallback(arg2,arg3); resultobj = SWIG_Py_Void(); + if (alloc3 == SWIG_NEWOBJ) delete[] buf3; return resultobj; fail: + if (alloc3 == SWIG_NEWOBJ) delete[] buf3; return NULL; } @@ -4103,9 +4131,10 @@ SWIGINTERN PyObject *_wrap_CoreSession_getDigits(PyObject *SWIGUNUSEDPARM(self), CoreSession *arg1 = (CoreSession *) 0 ; char *arg2 = (char *) 0 ; int arg3 ; - char *arg4 = (char *) 0 ; + int arg4 ; char *arg5 = (char *) 0 ; - int arg6 ; + char *arg6 = (char *) 0 ; + int arg7 ; int result; void *argp1 = 0 ; int res1 = 0 ; @@ -4116,24 +4145,27 @@ SWIGINTERN PyObject *_wrap_CoreSession_getDigits(PyObject *SWIGUNUSEDPARM(self), int alloc2 = 0 ; int val3 ; int ecode3 = 0 ; - int res4 ; - char *buf4 = 0 ; - int alloc4 = 0 ; + int val4 ; + int ecode4 = 0 ; int res5 ; - char temp5[8+1] ; - char *t5 = 0 ; - size_t n5 = 0 ; + char *buf5 = 0 ; int alloc5 = 0 ; - int val6 ; - int ecode6 = 0 ; + int res6 ; + char temp6[8+1] ; + char *t6 = 0 ; + size_t n6 = 0 ; + int alloc6 = 0 ; + int val7 ; + int ecode7 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; + PyObject * obj6 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OOOOOO:CoreSession_getDigits",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; + if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:CoreSession_getDigits",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_getDigits" "', argument " "1"" of type '" "CoreSession *""'"); @@ -4153,35 +4185,40 @@ SWIGINTERN PyObject *_wrap_CoreSession_getDigits(PyObject *SWIGUNUSEDPARM(self), SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "CoreSession_getDigits" "', argument " "3"" of type '" "int""'"); } arg3 = static_cast< int >(val3); - res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "CoreSession_getDigits" "', argument " "4"" of type '" "char *""'"); - } - arg4 = reinterpret_cast< char * >(buf4); - res5 = SWIG_AsCharPtrAndSize(obj4, &t5, &n5, &alloc5); - if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "CoreSession_getDigits" "', argument " "5"" of type '" "char *terminator""'"); - } - if ( n5 > (size_t) 8 ) n5 = (size_t) 8; - memcpy(temp5, t5, sizeof(char)*n5); - if (alloc5 == SWIG_NEWOBJ) delete[] t5; - temp5[n5 - 1] = 0; - arg5 = (char *) temp5; - ecode6 = SWIG_AsVal_int(obj5, &val6); - if (!SWIG_IsOK(ecode6)) { - SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "CoreSession_getDigits" "', argument " "6"" of type '" "int""'"); + ecode4 = SWIG_AsVal_int(obj3, &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "CoreSession_getDigits" "', argument " "4"" of type '" "int""'"); } - arg6 = static_cast< int >(val6); - result = (int)(arg1)->getDigits(arg2,arg3,arg4,arg5,arg6); + arg4 = static_cast< int >(val4); + res5 = SWIG_AsCharPtrAndSize(obj4, &buf5, NULL, &alloc5); + if (!SWIG_IsOK(res5)) { + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "CoreSession_getDigits" "', argument " "5"" of type '" "char *""'"); + } + arg5 = reinterpret_cast< char * >(buf5); + res6 = SWIG_AsCharPtrAndSize(obj5, &t6, &n6, &alloc6); + if (!SWIG_IsOK(res6)) { + SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "CoreSession_getDigits" "', argument " "6"" of type '" "char *terminator""'"); + } + if ( n6 > (size_t) 8 ) n6 = (size_t) 8; + memcpy(temp6, t6, sizeof(char)*n6); + if (alloc6 == SWIG_NEWOBJ) delete[] t6; + temp6[n6 - 1] = 0; + arg6 = (char *) temp6; + ecode7 = SWIG_AsVal_int(obj6, &val7); + if (!SWIG_IsOK(ecode7)) { + SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "CoreSession_getDigits" "', argument " "7"" of type '" "int""'"); + } + arg7 = static_cast< int >(val7); + result = (int)(arg1)->getDigits(arg2,arg3,arg4,arg5,arg6,arg7); resultobj = SWIG_From_int(static_cast< int >(result)); arg2[128] = 0; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_FromCharPtr(arg2)); - arg5[8] = 0; - resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_FromCharPtr(arg5)); - if (alloc4 == SWIG_NEWOBJ) delete[] buf4; + arg6[8] = 0; + resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_FromCharPtr(arg6)); + if (alloc5 == SWIG_NEWOBJ) delete[] buf5; return resultobj; fail: - if (alloc4 == SWIG_NEWOBJ) delete[] buf4; + if (alloc5 == SWIG_NEWOBJ) delete[] buf5; return NULL; } @@ -4411,6 +4448,109 @@ fail: } +SWIGINTERN PyObject *_wrap_CoreSession_flushEvents(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:CoreSession_flushEvents",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_flushEvents" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + result = (int)(arg1)->flushEvents(); + resultobj = SWIG_From_int(static_cast< int >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_CoreSession_flushDigits(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:CoreSession_flushDigits",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_flushDigits" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + result = (int)(arg1)->flushDigits(); + resultobj = SWIG_From_int(static_cast< int >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_CoreSession_setAutoHangup(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + bool arg2 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + bool val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:CoreSession_setAutoHangup",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_setAutoHangup" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + ecode2 = SWIG_AsVal_bool(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CoreSession_setAutoHangup" "', argument " "2"" of type '" "bool""'"); + } + arg2 = static_cast< bool >(val2); + result = (int)(arg1)->setAutoHangup(arg2); + resultobj = SWIG_From_int(static_cast< int >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_CoreSession_setHangupHook(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + void *arg2 = (void *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:CoreSession_setHangupHook",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_setHangupHook" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_setHangupHook" "', argument " "2"" of type '" "void *""'"); + } + (arg1)->setHangupHook(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_CoreSession_ready(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; @@ -4481,6 +4621,7 @@ fail: SWIGINTERN PyObject *_wrap_CoreSession_begin_allow_threads(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; + bool result; void *argp1 = 0 ; int res1 = 0 ; PyObject * obj0 = 0 ; @@ -4491,8 +4632,8 @@ SWIGINTERN PyObject *_wrap_CoreSession_begin_allow_threads(PyObject *SWIGUNUSEDP SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_begin_allow_threads" "', argument " "1"" of type '" "CoreSession *""'"); } arg1 = reinterpret_cast< CoreSession * >(argp1); - (arg1)->begin_allow_threads(); - resultobj = SWIG_Py_Void(); + result = (bool)(arg1)->begin_allow_threads(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); return resultobj; fail: return NULL; @@ -4502,6 +4643,7 @@ fail: SWIGINTERN PyObject *_wrap_CoreSession_end_allow_threads(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; + bool result; void *argp1 = 0 ; int res1 = 0 ; PyObject * obj0 = 0 ; @@ -4512,8 +4654,8 @@ SWIGINTERN PyObject *_wrap_CoreSession_end_allow_threads(PyObject *SWIGUNUSEDPAR SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_end_allow_threads" "', argument " "1"" of type '" "CoreSession *""'"); } arg1 = reinterpret_cast< CoreSession * >(argp1); - (arg1)->end_allow_threads(); - resultobj = SWIG_Py_Void(); + result = (bool)(arg1)->end_allow_threads(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); return resultobj; fail: return NULL; @@ -4567,6 +4709,73 @@ fail: } +SWIGINTERN PyObject *_wrap_CoreSession_check_hangup_hook(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:CoreSession_check_hangup_hook",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_check_hangup_hook" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + (arg1)->check_hangup_hook(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_CoreSession_run_dtmf_callback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + void *arg2 = (void *) 0 ; + switch_input_type_t arg3 ; + switch_status_t result; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + void *argp3 ; + int res3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OOO:CoreSession_run_dtmf_callback",&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_run_dtmf_callback" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_run_dtmf_callback" "', argument " "2"" of type '" "void *""'"); + } + { + res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_switch_input_type_t, 0 | 0); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "CoreSession_run_dtmf_callback" "', argument " "3"" of type '" "switch_input_type_t""'"); + } + if (!argp3) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "CoreSession_run_dtmf_callback" "', argument " "3"" of type '" "switch_input_type_t""'"); + } else { + switch_input_type_t * temp = reinterpret_cast< switch_input_type_t * >(argp3); + arg3 = *temp; + if (SWIG_IsNewObj(res3)) delete temp; + } + } + result = (arg1)->run_dtmf_callback(arg2,arg3); + resultobj = SWIG_NewPointerObj((new switch_status_t(static_cast< const switch_status_t& >(result))), SWIGTYPE_p_switch_status_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *CoreSession_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; @@ -4610,9 +4819,31 @@ fail: } -SWIGINTERN PyObject *_wrap_PythonDTMFCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { +SWIGINTERN PyObject *_wrap_hanguphook(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; - switch_core_session *arg1 = (switch_core_session *) 0 ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_status_t result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:hanguphook",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_switch_core_session_t, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "hanguphook" "', argument " "1"" of type '" "switch_core_session_t *""'"); + } + arg1 = reinterpret_cast< switch_core_session_t * >(argp1); + result = hanguphook(arg1); + resultobj = SWIG_NewPointerObj((new switch_status_t(static_cast< const switch_status_t& >(result))), SWIGTYPE_p_switch_status_t, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_dtmf_callback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; void *arg2 = (void *) 0 ; switch_input_type_t arg3 ; void *arg4 = (void *) 0 ; @@ -4632,23 +4863,23 @@ SWIGINTERN PyObject *_wrap_PythonDTMFCallback(PyObject *SWIGUNUSEDPARM(self), Py PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OOOOO:PythonDTMFCallback",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_switch_core_session, 0 | 0 ); + if (!PyArg_ParseTuple(args,(char *)"OOOOO:dtmf_callback",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_switch_core_session_t, 0 | 0 ); if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PythonDTMFCallback" "', argument " "1"" of type '" "switch_core_session *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dtmf_callback" "', argument " "1"" of type '" "switch_core_session_t *""'"); } - arg1 = reinterpret_cast< switch_core_session * >(argp1); + arg1 = reinterpret_cast< switch_core_session_t * >(argp1); res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PythonDTMFCallback" "', argument " "2"" of type '" "void *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "dtmf_callback" "', argument " "2"" of type '" "void *""'"); } { res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_switch_input_type_t, 0 | 0); if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "PythonDTMFCallback" "', argument " "3"" of type '" "switch_input_type_t""'"); + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "dtmf_callback" "', argument " "3"" of type '" "switch_input_type_t""'"); } if (!argp3) { - SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PythonDTMFCallback" "', argument " "3"" of type '" "switch_input_type_t""'"); + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "dtmf_callback" "', argument " "3"" of type '" "switch_input_type_t""'"); } else { switch_input_type_t * temp = reinterpret_cast< switch_input_type_t * >(argp3); arg3 = *temp; @@ -4657,14 +4888,14 @@ SWIGINTERN PyObject *_wrap_PythonDTMFCallback(PyObject *SWIGUNUSEDPARM(self), Py } res4 = SWIG_ConvertPtr(obj3,SWIG_as_voidptrptr(&arg4), 0, 0); if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "PythonDTMFCallback" "', argument " "4"" of type '" "void *""'"); + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "dtmf_callback" "', argument " "4"" of type '" "void *""'"); } ecode5 = SWIG_AsVal_unsigned_SS_int(obj4, &val5); if (!SWIG_IsOK(ecode5)) { - SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "PythonDTMFCallback" "', argument " "5"" of type '" "unsigned int""'"); + SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "dtmf_callback" "', argument " "5"" of type '" "unsigned int""'"); } arg5 = static_cast< unsigned int >(val5); - result = PythonDTMFCallback(arg1,arg2,arg3,arg4,arg5); + result = dtmf_callback(arg1,arg2,arg3,arg4,arg5); resultobj = SWIG_NewPointerObj((new switch_status_t(static_cast< const switch_status_t& >(result))), SWIGTYPE_p_switch_status_t, SWIG_POINTER_OWN | 0 ); return resultobj; fail: @@ -4827,9 +5058,88 @@ fail: } +SWIGINTERN PyObject *_wrap_PySession_setHangupHook(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + PySession *arg1 = (PySession *) 0 ; + PyObject *arg2 = (PyObject *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:PySession_setHangupHook",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PySession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySession_setHangupHook" "', argument " "1"" of type '" "PySession *""'"); + } + arg1 = reinterpret_cast< PySession * >(argp1); + arg2 = obj1; + (arg1)->setHangupHook(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_PySession_check_hangup_hook(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + PySession *arg1 = (PySession *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:PySession_check_hangup_hook",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PySession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySession_check_hangup_hook" "', argument " "1"" of type '" "PySession *""'"); + } + arg1 = reinterpret_cast< PySession * >(argp1); + (arg1)->check_hangup_hook(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_PySession_hangup(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + PySession *arg1 = (PySession *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:PySession_hangup",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PySession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySession_hangup" "', argument " "1"" of type '" "PySession *""'"); + } + arg1 = reinterpret_cast< PySession * >(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PySession_hangup" "', argument " "2"" of type '" "char *""'"); + } + arg2 = reinterpret_cast< char * >(buf2); + (arg1)->hangup(arg2); + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + return NULL; +} + + SWIGINTERN PyObject *_wrap_PySession_begin_allow_threads(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; PySession *arg1 = (PySession *) 0 ; + bool result; void *argp1 = 0 ; int res1 = 0 ; PyObject * obj0 = 0 ; @@ -4840,8 +5150,8 @@ SWIGINTERN PyObject *_wrap_PySession_begin_allow_threads(PyObject *SWIGUNUSEDPAR SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySession_begin_allow_threads" "', argument " "1"" of type '" "PySession *""'"); } arg1 = reinterpret_cast< PySession * >(argp1); - (arg1)->begin_allow_threads(); - resultobj = SWIG_Py_Void(); + result = (bool)(arg1)->begin_allow_threads(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); return resultobj; fail: return NULL; @@ -4851,6 +5161,7 @@ fail: SWIGINTERN PyObject *_wrap_PySession_end_allow_threads(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; PySession *arg1 = (PySession *) 0 ; + bool result; void *argp1 = 0 ; int res1 = 0 ; PyObject * obj0 = 0 ; @@ -4861,8 +5172,54 @@ SWIGINTERN PyObject *_wrap_PySession_end_allow_threads(PyObject *SWIGUNUSEDPARM( SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySession_end_allow_threads" "', argument " "1"" of type '" "PySession *""'"); } arg1 = reinterpret_cast< PySession * >(argp1); - (arg1)->end_allow_threads(); - resultobj = SWIG_Py_Void(); + result = (bool)(arg1)->end_allow_threads(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_PySession_run_dtmf_callback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + PySession *arg1 = (PySession *) 0 ; + void *arg2 = (void *) 0 ; + switch_input_type_t arg3 ; + switch_status_t result; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + void *argp3 ; + int res3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OOO:PySession_run_dtmf_callback",&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PySession, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySession_run_dtmf_callback" "', argument " "1"" of type '" "PySession *""'"); + } + arg1 = reinterpret_cast< PySession * >(argp1); + res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PySession_run_dtmf_callback" "', argument " "2"" of type '" "void *""'"); + } + { + res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_switch_input_type_t, 0 | 0); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "PySession_run_dtmf_callback" "', argument " "3"" of type '" "switch_input_type_t""'"); + } + if (!argp3) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PySession_run_dtmf_callback" "', argument " "3"" of type '" "switch_input_type_t""'"); + } else { + switch_input_type_t * temp = reinterpret_cast< switch_input_type_t * >(argp3); + arg3 = *temp; + if (SWIG_IsNewObj(res3)) delete temp; + } + } + result = (arg1)->run_dtmf_callback(arg2,arg3); + resultobj = SWIG_NewPointerObj((new switch_status_t(static_cast< const switch_status_t& >(result))), SWIGTYPE_p_switch_status_t, SWIG_POINTER_OWN | 0 ); return resultobj; fail: return NULL; @@ -4893,14 +5250,17 @@ static PyMethodDef SwigMethods[] = { { (char *)"new_input_callback_state_t", _wrap_new_input_callback_state_t, METH_VARARGS, NULL}, { (char *)"delete_input_callback_state_t", _wrap_delete_input_callback_state_t, METH_VARARGS, NULL}, { (char *)"input_callback_state_t_swigregister", input_callback_state_t_swigregister, METH_VARARGS, NULL}, - { (char *)"new_CoreSession", _wrap_new_CoreSession, METH_VARARGS, NULL}, { (char *)"delete_CoreSession", _wrap_delete_CoreSession, METH_VARARGS, NULL}, { (char *)"CoreSession_session_set", _wrap_CoreSession_session_set, METH_VARARGS, NULL}, { (char *)"CoreSession_session_get", _wrap_CoreSession_session_get, METH_VARARGS, NULL}, { (char *)"CoreSession_channel_set", _wrap_CoreSession_channel_set, METH_VARARGS, NULL}, { (char *)"CoreSession_channel_get", _wrap_CoreSession_channel_get, METH_VARARGS, NULL}, + { (char *)"CoreSession_flags_set", _wrap_CoreSession_flags_set, METH_VARARGS, NULL}, + { (char *)"CoreSession_flags_get", _wrap_CoreSession_flags_get, METH_VARARGS, NULL}, { (char *)"CoreSession_cb_state_set", _wrap_CoreSession_cb_state_set, METH_VARARGS, NULL}, { (char *)"CoreSession_cb_state_get", _wrap_CoreSession_cb_state_get, METH_VARARGS, NULL}, + { (char *)"CoreSession_hook_state_set", _wrap_CoreSession_hook_state_set, METH_VARARGS, NULL}, + { (char *)"CoreSession_hook_state_get", _wrap_CoreSession_hook_state_get, METH_VARARGS, NULL}, { (char *)"CoreSession_answer", _wrap_CoreSession_answer, METH_VARARGS, NULL}, { (char *)"CoreSession_preAnswer", _wrap_CoreSession_preAnswer, METH_VARARGS, NULL}, { (char *)"CoreSession_hangup", _wrap_CoreSession_hangup, METH_VARARGS, NULL}, @@ -4917,20 +5277,31 @@ static PyMethodDef SwigMethods[] = { { (char *)"CoreSession_transfer", _wrap_CoreSession_transfer, METH_VARARGS, NULL}, { (char *)"CoreSession_playAndGetDigits", _wrap_CoreSession_playAndGetDigits, METH_VARARGS, NULL}, { (char *)"CoreSession_streamfile", _wrap_CoreSession_streamfile, METH_VARARGS, NULL}, + { (char *)"CoreSession_flushEvents", _wrap_CoreSession_flushEvents, METH_VARARGS, NULL}, + { (char *)"CoreSession_flushDigits", _wrap_CoreSession_flushDigits, METH_VARARGS, NULL}, + { (char *)"CoreSession_setAutoHangup", _wrap_CoreSession_setAutoHangup, METH_VARARGS, NULL}, + { (char *)"CoreSession_setHangupHook", _wrap_CoreSession_setHangupHook, METH_VARARGS, NULL}, { (char *)"CoreSession_ready", _wrap_CoreSession_ready, METH_VARARGS, NULL}, { (char *)"CoreSession_execute", _wrap_CoreSession_execute, METH_VARARGS, NULL}, { (char *)"CoreSession_begin_allow_threads", _wrap_CoreSession_begin_allow_threads, METH_VARARGS, NULL}, { (char *)"CoreSession_end_allow_threads", _wrap_CoreSession_end_allow_threads, METH_VARARGS, NULL}, { (char *)"CoreSession_get_uuid", _wrap_CoreSession_get_uuid, METH_VARARGS, NULL}, { (char *)"CoreSession_get_cb_args", _wrap_CoreSession_get_cb_args, METH_VARARGS, NULL}, + { (char *)"CoreSession_check_hangup_hook", _wrap_CoreSession_check_hangup_hook, METH_VARARGS, NULL}, + { (char *)"CoreSession_run_dtmf_callback", _wrap_CoreSession_run_dtmf_callback, METH_VARARGS, NULL}, { (char *)"CoreSession_swigregister", CoreSession_swigregister, METH_VARARGS, NULL}, { (char *)"bridge", _wrap_bridge, METH_VARARGS, NULL}, - { (char *)"PythonDTMFCallback", _wrap_PythonDTMFCallback, METH_VARARGS, NULL}, + { (char *)"hanguphook", _wrap_hanguphook, METH_VARARGS, NULL}, + { (char *)"dtmf_callback", _wrap_dtmf_callback, METH_VARARGS, NULL}, { (char *)"new_PySession", _wrap_new_PySession, METH_VARARGS, NULL}, { (char *)"delete_PySession", _wrap_delete_PySession, METH_VARARGS, NULL}, { (char *)"PySession_setDTMFCallback", _wrap_PySession_setDTMFCallback, METH_VARARGS, NULL}, + { (char *)"PySession_setHangupHook", _wrap_PySession_setHangupHook, METH_VARARGS, NULL}, + { (char *)"PySession_check_hangup_hook", _wrap_PySession_check_hangup_hook, METH_VARARGS, NULL}, + { (char *)"PySession_hangup", _wrap_PySession_hangup, METH_VARARGS, NULL}, { (char *)"PySession_begin_allow_threads", _wrap_PySession_begin_allow_threads, METH_VARARGS, NULL}, { (char *)"PySession_end_allow_threads", _wrap_PySession_end_allow_threads, METH_VARARGS, NULL}, + { (char *)"PySession_run_dtmf_callback", _wrap_PySession_run_dtmf_callback, METH_VARARGS, NULL}, { (char *)"PySession_swigregister", PySession_swigregister, METH_VARARGS, NULL}, { NULL, NULL, 0, NULL } }; @@ -4945,14 +5316,14 @@ static swig_type_info _swigt__p_CoreSession = {"_p_CoreSession", "CoreSession *" static swig_type_info _swigt__p_PySession = {"_p_PySession", "PySession *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_input_callback_state = {"_p_input_callback_state", "input_callback_state *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_session_flag_t = {"_p_session_flag_t", "enum session_flag_t *|session_flag_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_swap_state_t = {"_p_swap_state_t", "enum swap_state_t *|swap_state_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_switch_channel_state_t = {"_p_switch_channel_state_t", "switch_channel_state_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_switch_channel_t = {"_p_switch_channel_t", "switch_channel_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_switch_core_session = {"_p_switch_core_session", "switch_core_session *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_switch_core_session_t = {"_p_switch_core_session_t", "switch_core_session_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_switch_input_args_t = {"_p_switch_input_args_t", "switch_input_args_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_switch_input_callback_function_t = {"_p_switch_input_callback_function_t", "switch_input_callback_function_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_switch_input_type_t = {"_p_switch_input_type_t", "switch_input_type_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_switch_status_t = {"_p_switch_status_t", "switch_status_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_uint32_t = {"_p_uint32_t", "uint32_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_void = {"_p_void", "void *", 0, 0, (void*)0, 0}; static swig_type_info *swig_type_initial[] = { @@ -4960,14 +5331,14 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_PySession, &_swigt__p_char, &_swigt__p_input_callback_state, + &_swigt__p_session_flag_t, + &_swigt__p_swap_state_t, + &_swigt__p_switch_channel_state_t, &_swigt__p_switch_channel_t, - &_swigt__p_switch_core_session, &_swigt__p_switch_core_session_t, &_swigt__p_switch_input_args_t, - &_swigt__p_switch_input_callback_function_t, &_swigt__p_switch_input_type_t, &_swigt__p_switch_status_t, - &_swigt__p_uint32_t, &_swigt__p_void, }; @@ -4975,14 +5346,14 @@ static swig_cast_info _swigc__p_CoreSession[] = { {&_swigt__p_CoreSession, 0, 0 static swig_cast_info _swigc__p_PySession[] = { {&_swigt__p_PySession, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_input_callback_state[] = { {&_swigt__p_input_callback_state, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_session_flag_t[] = { {&_swigt__p_session_flag_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_swap_state_t[] = { {&_swigt__p_swap_state_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_switch_channel_state_t[] = { {&_swigt__p_switch_channel_state_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_switch_channel_t[] = { {&_swigt__p_switch_channel_t, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_switch_core_session[] = { {&_swigt__p_switch_core_session, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_switch_core_session_t[] = { {&_swigt__p_switch_core_session_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_switch_input_args_t[] = { {&_swigt__p_switch_input_args_t, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_switch_input_callback_function_t[] = { {&_swigt__p_switch_input_callback_function_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_switch_input_type_t[] = { {&_swigt__p_switch_input_type_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_switch_status_t[] = { {&_swigt__p_switch_status_t, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_uint32_t[] = { {&_swigt__p_uint32_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_void[] = { {&_swigt__p_void, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info *swig_cast_initial[] = { @@ -4990,14 +5361,14 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_PySession, _swigc__p_char, _swigc__p_input_callback_state, + _swigc__p_session_flag_t, + _swigc__p_swap_state_t, + _swigc__p_switch_channel_state_t, _swigc__p_switch_channel_t, - _swigc__p_switch_core_session, _swigc__p_switch_core_session_t, _swigc__p_switch_input_args_t, - _swigc__p_switch_input_callback_function_t, _swigc__p_switch_input_type_t, _swigc__p_switch_status_t, - _swigc__p_uint32_t, _swigc__p_void, }; @@ -5519,5 +5890,10 @@ SWIGEXPORT void SWIG_init(void) { SWIG_InstallConstants(d,swig_const_table); + SWIG_Python_SetConstant(d, "S_HUP",SWIG_From_int(static_cast< int >(S_HUP))); + SWIG_Python_SetConstant(d, "S_FREE",SWIG_From_int(static_cast< int >(S_FREE))); + SWIG_Python_SetConstant(d, "S_RDLOCK",SWIG_From_int(static_cast< int >(S_RDLOCK))); + SWIG_Python_SetConstant(d, "S_SWAPPED_IN",SWIG_From_int(static_cast< int >(S_SWAPPED_IN))); + SWIG_Python_SetConstant(d, "S_SWAPPED_OUT",SWIG_From_int(static_cast< int >(S_SWAPPED_OUT))); } diff --git a/src/switch_core_file.c b/src/switch_core_file.c index b17b5e4ff3..683e58c042 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -95,6 +95,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_open(switch_file_handle_t *fh, SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, void *data, switch_size_t *len) { assert(fh != NULL); + assert(fh->file_interface != NULL); return fh->file_interface->file_read(fh, data, len); } @@ -102,6 +103,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh, void *data, switch_size_t *len) { assert(fh != NULL); + assert(fh->file_interface != NULL); return fh->file_interface->file_write(fh, data, len); } @@ -109,6 +111,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh, SWITCH_DECLARE(switch_status_t) switch_core_file_seek(switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence) { assert(fh != NULL); + assert(fh->file_interface != NULL); switch_set_flag(fh, SWITCH_FILE_SEEK); return fh->file_interface->file_seek(fh, cur_pos, samples, whence); @@ -117,6 +120,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_seek(switch_file_handle_t *fh, SWITCH_DECLARE(switch_status_t) switch_core_file_set_string(switch_file_handle_t *fh, switch_audio_col_t col, const char *string) { assert(fh != NULL); + assert(fh->file_interface != NULL); return fh->file_interface->file_set_string(fh, col, string); } @@ -124,6 +128,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_set_string(switch_file_handle_t SWITCH_DECLARE(switch_status_t) switch_core_file_get_string(switch_file_handle_t *fh, switch_audio_col_t col, const char **string) { assert(fh != NULL); + assert(fh->file_interface != NULL); return fh->file_interface->file_get_string(fh, col, string); @@ -132,6 +137,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_get_string(switch_file_handle_t SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh) { + assert(fh != NULL); + assert(fh->file_interface != NULL); + switch_clear_flag(fh, SWITCH_FILE_OPEN); return fh->file_interface->file_close(fh); diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 3ee9d72fe4..058dc0712d 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -7,7 +7,7 @@ #define sanity_check(x) do { if (!session) { switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "session is not initalized\n"); return x;}} while(0) #define sanity_check_noreturn do { if (!session) { switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "session is not initalized\n"); return;}} while(0) -#define init_vars() do { session = NULL; channel = NULL; uuid = NULL; tts_name = NULL; voice_name = NULL; memset(&args, 0, sizeof(args)); ap = NULL; caller_profile.source = "mod_unknown"; caller_profile.dialplan = ""; caller_profile.context = ""; caller_profile.caller_id_name = ""; caller_profile.caller_id_number = ""; caller_profile.network_addr = ""; caller_profile.ani = ""; caller_profile.aniii = ""; caller_profile.rdnis = ""; caller_profile.username = ""; } while(0) +#define init_vars() do { session = NULL; channel = NULL; uuid = NULL; tts_name = NULL; voice_name = NULL; memset(&args, 0, sizeof(args)); ap = NULL; caller_profile.source = "mod_unknown"; caller_profile.dialplan = ""; caller_profile.context = ""; caller_profile.caller_id_name = ""; caller_profile.caller_id_number = ""; caller_profile.network_addr = ""; caller_profile.ani = ""; caller_profile.aniii = ""; caller_profile.rdnis = ""; caller_profile.username = ""; on_hangup = NULL; cb_state.function = NULL; } while(0) @@ -36,8 +36,13 @@ CoreSession::CoreSession(switch_core_session_t *new_session) CoreSession::~CoreSession() { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::~CoreSession desctructor"); + switch_channel_t *channel = NULL; if (session) { + channel = switch_core_session_get_channel(session); + if (channel && switch_test_flag(this, S_HUP)) { + switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); + } switch_core_session_rwunlock(session); } @@ -103,30 +108,35 @@ int CoreSession::playFile(char *file, char *timer_name) timer_name = NULL; } store_file_handle(&fh); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "playFile begin_allow_threads\n"); begin_allow_threads(); status = switch_ivr_play_file(session, &fh, file, ap); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "playFile end_allow_threads\n"); end_allow_threads(); return status == SWITCH_STATUS_SUCCESS ? 1 : 0; } -void CoreSession::setDTMFCallback(switch_input_callback_function_t cb, - void *buf, - uint32_t buflen) -{ - sanity_check_noreturn; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::setDTMFCallback."); - if (cb) { - args.buf = buf; - args.buflen = buflen; - args.input_callback = cb; - ap = &args; - } else { - memset(&args, 0, sizeof(args)); - ap = NULL; - } -} +void CoreSession::setDTMFCallback(void *cbfunc, char *funcargs) { + + cb_state.funcargs = funcargs; + cb_state.function = cbfunc; + + args.buf = &cb_state; + args.buflen = sizeof(cb_state); // not sure what this is used for, copy mod_spidermonkey + + switch_channel_set_private(channel, "CoreSession", this); + + // we cannot set the actual callback to a python function, because + // the callback is a function pointer with a specific signature. + // so, set it to the following c function which will act as a proxy, + // finding the python callback in the args callback args structure + args.input_callback = dtmf_callback; + ap = &args; + + +} int CoreSession::speak(char *text) { @@ -134,6 +144,12 @@ int CoreSession::speak(char *text) switch_codec_t *codec; sanity_check(-1); + + // create and store an empty filehandle in callback args + // to workaround a bug in the presumptuous process_callback_result() + switch_file_handle_t fh = { 0 }; + store_file_handle(&fh); + if (!tts_name) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No TTS engine specified"); return SWITCH_STATUS_FALSE; @@ -161,7 +177,8 @@ void CoreSession::set_tts_parms(char *tts_name_p, char *voice_name_p) } int CoreSession::getDigits(char *dtmf_buf, - int len, + int buflen, + int maxdigits, char *terminators, char *terminator, int timeout) @@ -169,13 +186,16 @@ int CoreSession::getDigits(char *dtmf_buf, switch_status_t status; sanity_check(-1); begin_allow_threads(); + status = switch_ivr_collect_digits_count(session, dtmf_buf, - (uint32_t) len, - (uint32_t) len, + (uint32_t) buflen, + (uint32_t) maxdigits, terminators, terminator, (uint32_t) timeout); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "getDigits dtmf_buf: %s\n", dtmf_buf); end_allow_threads(); return status == SWITCH_STATUS_SUCCESS ? 1 : 0; } @@ -213,6 +233,9 @@ int CoreSession::playAndGetDigits(int min_digits, bad_input_audio_files, dtmf_buf, 128, digits_regex); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "playAndGetDigits dtmf_buf: %s\n", dtmf_buf); + end_allow_threads(); return status == SWITCH_STATUS_SUCCESS ? 1 : 0; } @@ -318,6 +341,52 @@ int CoreSession::recordFile(char *file_name, int max_len, int silence_threshold, } +int CoreSession::flushEvents() +{ + switch_event_t *event; + switch_channel_t *channel; + + if (!session) { + return SWITCH_STATUS_FALSE; + } + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + while (switch_core_session_dequeue_event(session, &event) == SWITCH_STATUS_SUCCESS) { + switch_event_destroy(&event); + } + return SWITCH_STATUS_SUCCESS; +} + +int CoreSession::flushDigits() +{ + char buf[256]; + switch_size_t has; + switch_channel_t *channel; + + + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + while ((has = switch_channel_has_dtmf(channel))) { + switch_channel_dequeue_dtmf(channel, buf, sizeof(buf)); + } + return SWITCH_STATUS_SUCCESS; +} + +int CoreSession::setAutoHangup(bool val) +{ + if (!session) { + return SWITCH_STATUS_FALSE; + } + if (val) { + switch_set_flag(this, S_HUP); + } else { + switch_clear_flag(this, S_HUP); + } + return SWITCH_STATUS_SUCCESS; +} + void CoreSession::setCallerData(char *var, char *val) { if (strcmp(var, "dialplan") == 0) { @@ -350,12 +419,17 @@ void CoreSession::setCallerData(char *var, char *val) { } -void CoreSession::begin_allow_threads() { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::begin_allow_threads() called and does nothing\n"); -} +void CoreSession::setHangupHook(void *hangup_func) { + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::seHangupHook, hangup_func: %p\n", hangup_func); + on_hangup = hangup_func; + switch_channel_t *channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + hook_state = switch_channel_get_state(channel); + switch_channel_set_private(channel, "CoreSession", this); + switch_core_event_hook_add_state_change(session, hanguphook); -void CoreSession::end_allow_threads() { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::end_allow_threads() called and does nothing\n"); } /** \brief Store a file handle in the callback args @@ -424,6 +498,64 @@ void bridge(CoreSession &session_a, CoreSession &session_b) } +switch_status_t hanguphook(switch_core_session_t *session_hungup) +{ + switch_channel_t *channel; + CoreSession *coresession = NULL; + switch_channel_state_t state; + + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangup_hook called\n"); + fflush(stdout); + + channel = switch_core_session_get_channel(session_hungup); + assert(channel != NULL); + + state = switch_channel_get_state(channel); + + if ((coresession = (CoreSession *) switch_channel_get_private(channel, "CoreSession"))) { + if (coresession->hook_state != state) { + coresession->hook_state = state; + coresession->check_hangup_hook(); + } + } + + return SWITCH_STATUS_SUCCESS; +} + + +switch_status_t dtmf_callback(switch_core_session_t *session_cb, + void *input, + switch_input_type_t itype, + void *buf, + unsigned int buflen) { + + switch_channel_t *channel; + CoreSession *coresession = NULL; + switch_status_t result; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmf_callback called\n"); + fflush(stdout); + + channel = switch_core_session_get_channel(session_cb); + assert(channel != NULL); + + coresession = (CoreSession *) switch_channel_get_private(channel, "CoreSession"); + if (!coresession) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid CoreSession\n"); + return SWITCH_STATUS_FALSE; + } + + result = coresession->run_dtmf_callback(input, itype); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "process_callback_result returned\n"); + if (result) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "process_callback_result returned: %d\n", result); + } + return result; + +} + + switch_status_t process_callback_result(char *ret, struct input_callback_state *cb_state, @@ -431,16 +563,40 @@ switch_status_t process_callback_result(char *ret, { switch_file_handle_t *fh = NULL; + + if (!cb_state) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Process callback result aborted because cb_state is null\n"); + return SWITCH_STATUS_FALSE; + } + + if (!cb_state->extra) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Process callback result aborted because cb_state->extra is null\n"); + return SWITCH_STATUS_FALSE; + } + fh = (switch_file_handle_t *) cb_state->extra; if (!fh) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Process callback result aborted because fh is null\n"); + return SWITCH_STATUS_FALSE; + } + + if (!fh->file_interface) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Process callback result aborted because fh->file_interface is null\n"); return SWITCH_STATUS_FALSE; } if (!ret) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Process callback result aborted because ret is null\n"); return SWITCH_STATUS_FALSE; } + if (!session) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Process callback result aborted because session is null\n"); + return SWITCH_STATUS_FALSE; + } + + if (!strncasecmp(ret, "speed", 4)) { char *p; @@ -481,7 +637,7 @@ switch_status_t process_callback_result(char *ret, unsigned int pos = 0; char *p; codec = switch_core_session_get_read_codec(session); - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "got codec\n"); if ((p = strchr(ret, ':'))) { p++; if (*p == '+' || *p == '-') { @@ -491,14 +647,20 @@ switch_status_t process_callback_result(char *ret, } if (step > 0) { samps = step * (codec->implementation->samples_per_second / 1000); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "going to seek\n"); switch_core_file_seek(fh, &pos, samps, SEEK_CUR); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "done seek\n"); } else { samps = step * (codec->implementation->samples_per_second / 1000); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "going to seek\n"); switch_core_file_seek(fh, &pos, fh->pos - samps, SEEK_SET); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "done seek\n"); } } else { samps = atoi(p) * (codec->implementation->samples_per_second / 1000); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "going to seek\n"); switch_core_file_seek(fh, &pos, samps, SEEK_SET); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "done seek\n"); } } @@ -506,9 +668,11 @@ switch_status_t process_callback_result(char *ret, } if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "return success\n"); return SWITCH_STATUS_SUCCESS; } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no match, return false\n"); return SWITCH_STATUS_FALSE;