From f45d0601721d58ab134a3e742192322996b60d84 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 15 Jun 2007 17:25:41 +0000 Subject: [PATCH] merge fix for MODLANG-33 and MODLANG-34. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5374 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- scripts/mytest.py | 63 +- src/include/switch_cpp.h | 111 ++- src/mod/languages/mod_python/freeswitch.py | 82 +- .../mod_python/freeswitch_python.cpp | 59 +- .../languages/mod_python/freeswitch_python.h | 23 +- src/mod/languages/mod_python/mod_python.c | 151 ++-- src/mod/languages/mod_python/mod_python.i | 22 +- .../languages/mod_python/mod_python_wrap.cpp | 801 ++++++++++-------- src/switch_cpp.cpp | 109 ++- 9 files changed, 847 insertions(+), 574 deletions(-) diff --git a/scripts/mytest.py b/scripts/mytest.py index be105cea09..42112f8e76 100644 --- a/scripts/mytest.py +++ b/scripts/mytest.py @@ -1,26 +1,39 @@ +# Please see latest version of this script at +# http://wiki.freeswitch.org/wiki/Mod_python +# before reporting errors + import sys, time -def onDTMF(input, itype, buf, buflen): - print "input=",input - print "itype=",itype - print "buf=",buf - print "buflen",buflen - if input == "#": - return 1 - else: - return 0 -console_log("1","test from my python program\n") -session.answer() -session.setDTMFCallback(onDTMF) -session.set_tts_parms("cepstral", "david") -session.playFile("/root/test.gsm", "") -session.speakText("Please enter telephone number with area code and press pound sign. ") -input = session.getDigits("", 11, "*#", 10000) -console_log("1","result from get digits is "+ input +"\n") -phone_number = session.playAndGetDigits(5, 11, 3, 10000, "*#", - "/sounds/test.gsm", - "/sounds/invalid.gsm", - "", - "^17771112222$"); -console_log("1","result from play_and_get_digits is "+ phone_number +"\n") -session.transfer("1000", "XML", "default") -session.hangup("1") +from freeswitch import * + +def onDTMF(input, itype, funcargs): + console_log("1","\n\nonDTMF input: %s\n" % input) + if input == "5": + return "pause" + if input == "3": + return "seek:+60000" + if input == "1": + return "seek:-60000" + if input == "0": + return "stop" + return None # will make the streamfile audio stop + +def handler(uuid): + + console_log("1","... test from my python program\n") + session = PySession(uuid) + session.answer() + session.setDTMFCallback(onDTMF, "") + session.set_tts_parms("cepstral", "david") + session.playFile("/path/to/your.mp3", "") + session.speak("Please enter telephone number with area code and press pound sign. ") + input = session.getDigits("", 11, "*#", "#", 10000) + console_log("1","result from get digits is %s\n" % input) + phone_number = session.playAndGetDigits(5, 11, 3, 10000, "*#", + "/sounds/test.gsm", + "/sounds/invalid.gsm", + "", + "^17771112222$"); + console_log("1","result from play_and_get_digits is %s\n" % phone_number) + session.transfer("1000", "XML", "default") + session.hangup("1") + diff --git a/src/include/switch_cpp.h b/src/include/switch_cpp.h index 57a5e7d6c8..32ae002327 100644 --- a/src/include/switch_cpp.h +++ b/src/include/switch_cpp.h @@ -20,39 +20,112 @@ switch_status_t process_callback_result(char *raw_result, struct input_callback_state *cb_state, switch_core_session_t *session); + +typedef struct input_callback_state { + void *function; // pointer to the language specific callback function + // eg, PyObject *pyfunc + void *threadState; // pointer to the language specific thread state + // eg, PyThreadState *threadState + void *extra; // currently used to store a switch_file_handle_t + char *funcargs; // extra string that will be passed to callback function +}; + + class CoreSession { - private: + protected: switch_input_args_t args; switch_input_args_t *ap; + char *uuid; + char *tts_name; + char *voice_name; + void store_file_handle(switch_file_handle_t *fh); public: CoreSession(char *uuid); CoreSession(switch_core_session_t *new_session); - ~CoreSession(); + virtual ~CoreSession(); switch_core_session_t *session; switch_channel_t *channel; + input_callback_state cb_state; int answer(); int preAnswer(); void hangup(char *cause); void setVariable(char *var, char *val); char *getVariable(char *var); - int playFile(char *file, char *timer_name); - void setDTMFCallback(switch_input_callback_function_t cb, void *buf, uint32_t buflen); - int speakText(char *text); - void set_tts_parms(char *tts_name, char *voice_name); - int getDigits(char *dtmf_buf, int len, char *terminators, char *terminator, int timeout); - int transfer(char *extensions, char *dialplan, char *context); - int playAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, char *terminators, - char *audio_files, char *bad_input_audio_files, char *dtmf_buf, - char *digits_regex); - int streamfile(char *file, void *cb_func, char *funcargs, int starting_sample_count); - void execute(char *app, char *data); - void begin_allow_threads(); - void end_allow_threads(); - protected: - char *uuid; - char *tts_name; - char *voice_name; + /** \brief Play a file that resides on disk into the channel + * + * \param file - the path to the .wav/.mp3 to be played + * \param timer_name - ?? does not seem to be used, what is this? + * \return an int status code indicating success or failure + * + * NOTE: if a dtmf callback is installed before calling this + * function, that callback will be called upon receiving any + * dtmfs + */ + int playFile(char *file, char *timer_name); + + + /** \brief set a DTMF callback function + * + * The DTMF callback function will be set and persist + * for the life of the session, and be called when a dtmf + * 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); + + int speak(char *text); + void set_tts_parms(char *tts_name, char *voice_name); + + int getDigits(char *dtmf_buf, + int len, + char *terminators, + char *terminator, + int timeout); + + int transfer(char *extensions, char *dialplan, char *context); + + /** \brief Play a file into channel and collect dtmfs + * + * See API docs in switch_ivr.h: switch_play_and_get_digits(..) + * + * NOTE: this does not call any dtmf callbacks set by + * setDTMFCallback(..) as it uses its own internal callback + * handler. + */ + int playAndGetDigits(int min_digits, + int max_digits, + int max_tries, + int timeout, + char *terminators, + char *audio_files, + char *bad_input_audio_files, + char *dtmf_buf, + char *digits_regex); + + /** \brief Play a file that resides on disk into the channel + * + * \param file - the path to the .wav/.mp3 to be played + * \param starting_sample_count - the index of the sample to + * start playing from + * \return an int status code indicating success or failure + * + */ + int streamfile(char *file, int starting_sample_count); + + bool ready(); + + void execute(char *app, char *data); + virtual void begin_allow_threads(); + virtual void end_allow_threads(); + + }; diff --git a/src/mod/languages/mod_python/freeswitch.py b/src/mod/languages/mod_python/freeswitch.py index 49b0d2e4a6..c8a5e3cb3d 100644 --- a/src/mod/languages/mod_python/freeswitch.py +++ b/src/mod/languages/mod_python/freeswitch.py @@ -47,44 +47,6 @@ console_clean_log = _freeswitch.console_clean_log api_execute = _freeswitch.api_execute api_reply_delete = _freeswitch.api_reply_delete process_callback_result = _freeswitch.process_callback_result -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) - __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 - __swig_getmethods__["session"] = _freeswitch.CoreSession_session_get - if _newclass:session = property(_freeswitch.CoreSession_session_get, _freeswitch.CoreSession_session_set) - __swig_setmethods__["channel"] = _freeswitch.CoreSession_channel_set - __swig_getmethods__["channel"] = _freeswitch.CoreSession_channel_get - if _newclass:channel = property(_freeswitch.CoreSession_channel_get, _freeswitch.CoreSession_channel_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) - def setVariable(*args): return _freeswitch.CoreSession_setVariable(*args) - def getVariable(*args): return _freeswitch.CoreSession_getVariable(*args) - def playFile(*args): return _freeswitch.CoreSession_playFile(*args) - def setDTMFCallback(*args): return _freeswitch.CoreSession_setDTMFCallback(*args) - def speakText(*args): return _freeswitch.CoreSession_speakText(*args) - def set_tts_parms(*args): return _freeswitch.CoreSession_set_tts_parms(*args) - def getDigits(*args): return _freeswitch.CoreSession_getDigits(*args) - 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 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) -CoreSession_swigregister = _freeswitch.CoreSession_swigregister -CoreSession_swigregister(CoreSession) - -PythonDTMFCallback = _freeswitch.PythonDTMFCallback class input_callback_state(_object): __swig_setmethods__ = {} __setattr__ = lambda self, name, value: _swig_setattr(self, input_callback_state, name, value) @@ -112,6 +74,48 @@ class input_callback_state(_object): input_callback_state_swigregister = _freeswitch.input_callback_state_swigregister input_callback_state_swigregister(input_callback_state) +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) + __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 + __swig_getmethods__["session"] = _freeswitch.CoreSession_session_get + if _newclass:session = property(_freeswitch.CoreSession_session_get, _freeswitch.CoreSession_session_set) + __swig_setmethods__["channel"] = _freeswitch.CoreSession_channel_set + __swig_getmethods__["channel"] = _freeswitch.CoreSession_channel_get + if _newclass:channel = property(_freeswitch.CoreSession_channel_get, _freeswitch.CoreSession_channel_set) + __swig_setmethods__["cb_state"] = _freeswitch.CoreSession_cb_state_set + __swig_getmethods__["cb_state"] = _freeswitch.CoreSession_cb_state_get + if _newclass:cb_state = property(_freeswitch.CoreSession_cb_state_get, _freeswitch.CoreSession_cb_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) + def setVariable(*args): return _freeswitch.CoreSession_setVariable(*args) + def getVariable(*args): return _freeswitch.CoreSession_getVariable(*args) + def playFile(*args): return _freeswitch.CoreSession_playFile(*args) + def setDTMFCallback(*args): return _freeswitch.CoreSession_setDTMFCallback(*args) + def speak(*args): return _freeswitch.CoreSession_speak(*args) + def set_tts_parms(*args): return _freeswitch.CoreSession_set_tts_parms(*args) + def getDigits(*args): return _freeswitch.CoreSession_getDigits(*args) + 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 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) +CoreSession_swigregister = _freeswitch.CoreSession_swigregister +CoreSession_swigregister(CoreSession) + +PythonDTMFCallback = _freeswitch.PythonDTMFCallback class PySession(CoreSession): __swig_setmethods__ = {} for _s in [CoreSession]: __swig_setmethods__.update(_s.__swig_setmethods__) @@ -126,7 +130,7 @@ class PySession(CoreSession): except: self.this = this __swig_destroy__ = _freeswitch.delete_PySession __del__ = lambda self : None; - def streamfile(*args): return _freeswitch.PySession_streamfile(*args) + def setDTMFCallback(*args): return _freeswitch.PySession_setDTMFCallback(*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) PySession_swigregister = _freeswitch.PySession_swigregister diff --git a/src/mod/languages/mod_python/freeswitch_python.cpp b/src/mod/languages/mod_python/freeswitch_python.cpp index 324842bd5a..d8cd4ab65f 100644 --- a/src/mod/languages/mod_python/freeswitch_python.cpp +++ b/src/mod/languages/mod_python/freeswitch_python.cpp @@ -3,62 +3,53 @@ #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) -int PySession::streamfile(char *file, PyObject *pyfunc, char *funcargs, int starting_sample_count) +void PySession::setDTMFCallback(PyObject *pyfunc, char *funcargs) { - switch_status_t status; - switch_input_args_t args = { 0 }, *ap = NULL; - struct input_callback_state cb_state = { 0 }; - switch_file_handle_t fh = { 0 }; - char *prebuf; - - sanity_check(-1); - cb_state.funcargs = funcargs; - fh.samples = starting_sample_count; + sanity_check(); if (!PyCallable_Check(pyfunc)) { - dtmfCallbackFunction = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF function is not a python function."); - } - else { - dtmfCallbackFunction = pyfunc; } + else { + cb_state.funcargs = funcargs; + cb_state.function = (void *) pyfunc; - if (dtmfCallbackFunction) { - cb_state.function = dtmfCallbackFunction; - cb_state.extra = &fh; args.buf = &cb_state; args.buflen = sizeof(cb_state); // not sure what this is used for, copy mod_spidermonkey - args.input_callback = PythonDTMFCallback; // defined in mod_python.i, will use ptrs in cb_state + + // 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; + } - if ((prebuf = switch_channel_get_variable(this->channel, "stream_prebuffer"))) { - int maybe = atoi(prebuf); - if (maybe > 0) { - fh.prebuf = maybe; - } - } - - - this->begin_allow_threads(); - cb_state.threadState = threadState; // pass threadState so the dtmfhandler can pick it up - status = switch_ivr_play_file(session, &fh, file, ap); - this->end_allow_threads(); - - return status == SWITCH_STATUS_SUCCESS ? 1 : 0; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmf callback was set, pyfunc: %p. cb_state: %p\n", pyfunc, &cb_state); } void PySession::begin_allow_threads(void) { - threadState = PyEval_SaveThread(); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::begin_allow_threads() called\n"); + + threadState = (void *) PyEval_SaveThread(); + cb_state.threadState = threadState; + // cb_state.extra = &fh; + args.buf = &cb_state; + ap = &args; } void PySession::end_allow_threads(void) { - PyEval_RestoreThread(threadState); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::end_allow_threads() called\n"); + 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"); } + + diff --git a/src/mod/languages/mod_python/freeswitch_python.h b/src/mod/languages/mod_python/freeswitch_python.h index b8dbc4632f..f23c078d1a 100644 --- a/src/mod/languages/mod_python/freeswitch_python.h +++ b/src/mod/languages/mod_python/freeswitch_python.h @@ -26,26 +26,17 @@ void console_clean_log(char *msg); char *api_execute(char *cmd, char *arg); void api_reply_delete(char *reply); -struct input_callback_state { - PyObject *function; - PyThreadState *threadState; - void *extra; - char *funcargs; -}; - class PySession : public CoreSession { private: - PyObject *dtmfCallbackFunction; - PyThreadState *threadState; + void *threadState; public: - PySession(char *uuid) : CoreSession(uuid) {}; - PySession(switch_core_session_t *session) : CoreSession(session) {}; - ~PySession(); - int streamfile(char *file, PyObject *pyfunc, char *funcargs, int starting_sample_count); - void begin_allow_threads(); - void end_allow_threads(); + PySession(char *uuid) : CoreSession(uuid) {} + PySession(switch_core_session_t *session) : CoreSession(session) {} + ~PySession(); + void setDTMFCallback(PyObject *pyfunc, char *funcargs); + void begin_allow_threads(); + void end_allow_threads(); - protected: }; #ifdef __cplusplus diff --git a/src/mod/languages/mod_python/mod_python.c b/src/mod/languages/mod_python/mod_python.c index b5ed4d6e10..9707e8259f 100644 --- a/src/mod/languages/mod_python/mod_python.c +++ b/src/mod/languages/mod_python/mod_python.c @@ -56,87 +56,115 @@ SWITCH_MODULE_DEFINITION(mod_python, mod_python_load, mod_python_shutdown, NULL) static void eval_some_python(char *uuid, char *args) { PyThreadState *tstate = NULL; - FILE *pythonfile = NULL; char *dupargs = NULL; char *argv[128] = {0}; int argc; int lead = 0; - char *script = NULL, *script_path = NULL, *path = NULL; + char *script = NULL; + PyObject *module = NULL; + PyObject *function = NULL; + PyObject *arg = NULL; + PyObject *result = NULL; if (args) { - dupargs = strdup(args); + dupargs = strdup(args); } else { - return; + return; } assert(dupargs != NULL); if (!(argc = switch_separate_string(dupargs, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No script name specified!\n"); - goto done; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No module name specified!\n"); + goto done; } script = argv[0]; lead = 1; - if (switch_is_file_path(script)) { - script_path = script; - if ((script = strrchr(script_path, *SWITCH_PATH_SEPARATOR))) { - script++; - } else { - script = script_path; - } - } else if ((path = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.script_dir, SWITCH_PATH_SEPARATOR, script))) { - script_path = path; - } - if (script_path) { - if (!switch_file_exists(script_path, NULL) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Open File: %s\n", script_path); - goto done; - } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Invoking py module: %s\n", script); + + tstate = PyThreadState_New(mainThreadState->interp); + if (!tstate) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error acquiring tstate\n"); + goto done; } + // swap in thread state + PyEval_AcquireThread(tstate); + init_freeswitch(); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "running %s\n", script_path); + // import the module + module = PyImport_ImportModule( (char *) script); + if (!module) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error importing module\n"); + PyErr_Print(); + PyErr_Clear(); + goto done_swap_out; + } + // reload the module + module = PyImport_ReloadModule(module); + if (!module) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error reloading module\n"); + PyErr_Print(); + PyErr_Clear(); + goto done_swap_out; + } - if ((pythonfile = fopen(script_path, "r"))) { + // get the handler function to be called + function = PyObject_GetAttrString(module, "handler"); + if (!function) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Module does not define handler(uuid)\n"); + PyErr_Print(); + PyErr_Clear(); + goto done_swap_out; + } - PyEval_AcquireLock(); - tstate = PyThreadState_New(mainThreadState->interp); - if (!tstate) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error acquiring tstate\n"); - goto done; - } - PyThreadState_Swap(tstate); - init_freeswitch(); - PyRun_SimpleString("from freeswitch import *"); - if (uuid) { - char code[128]; - snprintf(code, sizeof(code), "session = PySession(\"%s\");", uuid); - PyRun_SimpleString(code); - } - PySys_SetArgv(argc - lead, &argv[lead]); - PyRun_SimpleFile(pythonfile, script); - PyThreadState_Swap(NULL); - PyThreadState_Clear(tstate); - PyThreadState_Delete(tstate); - PyEval_ReleaseLock(); - - - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error running %s\n", script_path); + if (uuid) { + // build a tuple to pass the args, the uuid of session + arg = Py_BuildValue("(s)", uuid); + if (!arg) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error building args\n"); + PyErr_Print(); + PyErr_Clear(); + goto done_swap_out; + } + } + else { + arg = PyTuple_New(1); + PyObject *nada = Py_BuildValue(""); + PyTuple_SetItem(arg, 0, nada); } + // invoke the handler + result = PyEval_CallObjectWithKeywords(function, arg, (PyObject *)NULL); + + // check the result and print out any errors + if (!result) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error calling python script\n"); + PyErr_Print(); + PyErr_Clear(); + } + + goto done_swap_out; done: + switch_safe_free(dupargs); - if (pythonfile) { - fclose(pythonfile); - } + done_swap_out: + // decrement ref counts + Py_XDECREF(module); + Py_XDECREF(function); + Py_XDECREF(arg); + Py_XDECREF(result); + + // swap out thread state + PyEval_ReleaseThread(tstate); switch_safe_free(dupargs); - switch_safe_free(path); + + } static void python_function(switch_core_session_t *session, char *data) @@ -229,14 +257,25 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_python_load) *module_interface = &python_module_interface; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Python Framework Loading...\n"); - Py_Initialize(); - PyEval_InitThreads(); + if (!Py_IsInitialized()) { - mainThreadState = PyThreadState_Get(); + // initialize python system + Py_Initialize(); - PyThreadState_Swap(NULL); + // create GIL and a threadstate + PyEval_InitThreads(); - PyEval_ReleaseLock(); + // save threadstate since it's interp field will be needed + // to create new threadstates, and will be needed for shutdown + mainThreadState = PyThreadState_Get(); + + // swap out threadstate since the call threads will create + // their own and swap in their threadstate + PyThreadState_Swap(NULL); + + // release GIL + PyEval_ReleaseLock(); + } /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; diff --git a/src/mod/languages/mod_python/mod_python.i b/src/mod/languages/mod_python/mod_python.i index abf5d2fd22..78e8f0b407 100644 --- a/src/mod/languages/mod_python/mod_python.i +++ b/src/mod/languages/mod_python/mod_python.i @@ -30,6 +30,8 @@ switch_status_t PythonDTMFCallback(switch_core_session_t *session, switch_file_handle_t *fh = NULL; PyThreadState *threadState = NULL; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "PythonDTMFCallback\n"); + if (!buf) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buf pointer is null"); return SWITCH_STATUS_FALSE; @@ -39,11 +41,14 @@ switch_status_t PythonDTMFCallback(switch_core_session_t *session, func = (PyObject *) cb_state->function; if (!func) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cb_state->function is null"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cb_state->function is null\n"); return SWITCH_STATUS_FALSE; } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "cb_state->function is NOT null\n"); + } if (!PyCallable_Check(func)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "function not callable"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "function not callable\n"); return SWITCH_STATUS_FALSE; } @@ -57,14 +62,22 @@ switch_status_t PythonDTMFCallback(switch_core_session_t *session, threadState = (PyThreadState *) cb_state->threadState; if (!threadState) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error, invalid 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_INFO, "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_INFO, "restored threadstate, calling python function: %p\n", func); + result = PyEval_CallObject(func, arglist); + threadState = PyEval_SaveThread(); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "called python function\n"); Py_DECREF(arglist); // Trash arglist if (result && result != Py_None) { @@ -88,6 +101,9 @@ switch_status_t process_callback_result(char *ret, switch_file_handle_t *fh = NULL; fh = (switch_file_handle_t *) cb_state->extra; + if (!fh) { + return SWITCH_STATUS_FALSE; + } if (!ret) { return SWITCH_STATUS_FALSE; diff --git a/src/mod/languages/mod_python/mod_python_wrap.cpp b/src/mod/languages/mod_python/mod_python_wrap.cpp index f96354e082..371c2e93d6 100644 --- a/src/mod/languages/mod_python/mod_python_wrap.cpp +++ b/src/mod/languages/mod_python/mod_python_wrap.cpp @@ -2461,19 +2461,18 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_CoreSession swig_types[0] #define SWIGTYPE_p_PySession swig_types[1] -#define SWIGTYPE_p_PyThreadState swig_types[2] -#define SWIGTYPE_p_char swig_types[3] -#define SWIGTYPE_p_input_callback_state swig_types[4] -#define SWIGTYPE_p_switch_channel_t swig_types[5] -#define SWIGTYPE_p_switch_core_session swig_types[6] -#define SWIGTYPE_p_switch_core_session_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_void swig_types[12] -static swig_type_info *swig_types[14]; -static swig_module_info swig_module = {swig_types, 13, 0, 0, 0, 0}; +#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_callback_function_t swig_types[7] +#define SWIGTYPE_p_switch_input_type_t swig_types[8] +#define SWIGTYPE_p_switch_status_t swig_types[9] +#define SWIGTYPE_p_uint32_t swig_types[10] +#define SWIGTYPE_p_void swig_types[11] +static swig_type_info *swig_types[13]; +static swig_module_info swig_module = {swig_types, 12, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2815,6 +2814,13 @@ SWIG_AsVal_int (PyObject * obj, int *val) } +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) { @@ -2892,6 +2898,8 @@ switch_status_t PythonDTMFCallback(switch_core_session_t *session, switch_file_handle_t *fh = NULL; PyThreadState *threadState = NULL; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "PythonDTMFCallback\n"); + if (!buf) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buf pointer is null"); return SWITCH_STATUS_FALSE; @@ -2901,11 +2909,14 @@ switch_status_t PythonDTMFCallback(switch_core_session_t *session, func = (PyObject *) cb_state->function; if (!func) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cb_state->function is null"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cb_state->function is null\n"); return SWITCH_STATUS_FALSE; } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "cb_state->function is NOT null\n"); + } if (!PyCallable_Check(func)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "function not callable"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "function not callable\n"); return SWITCH_STATUS_FALSE; } @@ -2919,14 +2930,22 @@ switch_status_t PythonDTMFCallback(switch_core_session_t *session, threadState = (PyThreadState *) cb_state->threadState; if (!threadState) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error, invalid 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_INFO, "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_INFO, "restored threadstate, calling python function: %p\n", func); + result = PyEval_CallObject(func, arglist); + threadState = PyEval_SaveThread(); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "called python function\n"); Py_DECREF(arglist); // Trash arglist if (result && result != Py_None) { @@ -2950,6 +2969,9 @@ switch_status_t process_callback_result(char *ret, switch_file_handle_t *fh = NULL; fh = (switch_file_handle_t *) cb_state->extra; + if (!fh) { + return SWITCH_STATUS_FALSE; + } if (!ret) { return SWITCH_STATUS_FALSE; @@ -2984,8 +3006,6 @@ switch_status_t process_callback_result(char *ret, return SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(ret, "stop")) { return SWITCH_STATUS_FALSE; - } else if (!strcasecmp(ret, "hangup")) { - return SWITCH_STATUS_BREAK; } else if (!strcasecmp(ret, "restart")) { unsigned int pos = 0; fh->speed = 0; @@ -3230,6 +3250,262 @@ fail: } +SWIGINTERN PyObject *_wrap_input_callback_state_function_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + input_callback_state *arg1 = (input_callback_state *) 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:input_callback_state_function_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_function_set" "', argument " "1"" of type '" "input_callback_state *""'"); + } + arg1 = reinterpret_cast< input_callback_state * >(argp1); + res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, SWIG_POINTER_DISOWN); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "input_callback_state_function_set" "', argument " "2"" of type '" "void *""'"); + } + if (arg1) (arg1)->function = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_input_callback_state_function_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + input_callback_state *arg1 = (input_callback_state *) 0 ; + void *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:input_callback_state_function_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_function_get" "', argument " "1"" of type '" "input_callback_state *""'"); + } + arg1 = reinterpret_cast< input_callback_state * >(argp1); + result = (void *) ((arg1)->function); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_input_callback_state_threadState_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + input_callback_state *arg1 = (input_callback_state *) 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:input_callback_state_threadState_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_threadState_set" "', argument " "1"" of type '" "input_callback_state *""'"); + } + arg1 = reinterpret_cast< input_callback_state * >(argp1); + res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, SWIG_POINTER_DISOWN); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "input_callback_state_threadState_set" "', argument " "2"" of type '" "void *""'"); + } + if (arg1) (arg1)->threadState = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_input_callback_state_threadState_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + input_callback_state *arg1 = (input_callback_state *) 0 ; + void *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:input_callback_state_threadState_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_threadState_get" "', argument " "1"" of type '" "input_callback_state *""'"); + } + arg1 = reinterpret_cast< input_callback_state * >(argp1); + result = (void *) ((arg1)->threadState); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_input_callback_state_extra_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + input_callback_state *arg1 = (input_callback_state *) 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:input_callback_state_extra_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_extra_set" "', argument " "1"" of type '" "input_callback_state *""'"); + } + arg1 = reinterpret_cast< input_callback_state * >(argp1); + res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, SWIG_POINTER_DISOWN); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "input_callback_state_extra_set" "', argument " "2"" of type '" "void *""'"); + } + if (arg1) (arg1)->extra = arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_input_callback_state_extra_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + input_callback_state *arg1 = (input_callback_state *) 0 ; + void *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:input_callback_state_extra_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_extra_get" "', argument " "1"" of type '" "input_callback_state *""'"); + } + arg1 = reinterpret_cast< input_callback_state * >(argp1); + result = (void *) ((arg1)->extra); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_input_callback_state_funcargs_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + input_callback_state *arg1 = (input_callback_state *) 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:input_callback_state_funcargs_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_funcargs_set" "', argument " "1"" of type '" "input_callback_state *""'"); + } + arg1 = reinterpret_cast< input_callback_state * >(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "input_callback_state_funcargs_set" "', argument " "2"" of type '" "char *""'"); + } + arg2 = buf2; + if (arg1->funcargs) delete[] arg1->funcargs; + if (arg2) { + size_t size = strlen(arg2) + 1; + arg1->funcargs = reinterpret_cast< char* >(memcpy((new char[size]), arg2, sizeof(char)*(size))); + } else { + arg1->funcargs = 0; + } + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_input_callback_state_funcargs_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + input_callback_state *arg1 = (input_callback_state *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:input_callback_state_funcargs_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_funcargs_get" "', argument " "1"" of type '" "input_callback_state *""'"); + } + arg1 = reinterpret_cast< input_callback_state * >(argp1); + result = (char *) ((arg1)->funcargs); + resultobj = SWIG_FromCharPtr(result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_input_callback_state(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + input_callback_state *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)":new_input_callback_state")) SWIG_fail; + result = (input_callback_state *)new input_callback_state(); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_input_callback_state, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_input_callback_state(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + input_callback_state *arg1 = (input_callback_state *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:delete_input_callback_state",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_input_callback_state" "', argument " "1"" of type '" "input_callback_state *""'"); + } + arg1 = reinterpret_cast< input_callback_state * >(argp1); + delete arg1; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *input_callback_state_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_input_callback_state, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + SWIGINTERN PyObject *_wrap_new_CoreSession__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; char *arg1 = (char *) 0 ; @@ -3439,6 +3715,59 @@ fail: } +SWIGINTERN PyObject *_wrap_CoreSession_cb_state_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + input_callback_state *arg2 = (input_callback_state *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:CoreSession_cb_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_cb_state_set" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_input_callback_state, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_cb_state_set" "', argument " "2"" of type '" "input_callback_state *""'"); + } + arg2 = reinterpret_cast< input_callback_state * >(argp2); + if (arg1) (arg1)->cb_state = *arg2; + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_CoreSession_cb_state_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + input_callback_state *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:CoreSession_cb_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_cb_state_get" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + result = (input_callback_state *)& ((arg1)->cb_state); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_input_callback_state, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_CoreSession_answer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; @@ -3703,7 +4032,7 @@ fail: } -SWIGINTERN PyObject *_wrap_CoreSession_speakText(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { +SWIGINTERN PyObject *_wrap_CoreSession_speak(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; char *arg2 = (char *) 0 ; @@ -3716,18 +4045,18 @@ SWIGINTERN PyObject *_wrap_CoreSession_speakText(PyObject *SWIGUNUSEDPARM(self), PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OO:CoreSession_speakText",&obj0,&obj1)) SWIG_fail; + if (!PyArg_ParseTuple(args,(char *)"OO:CoreSession_speak",&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_speakText" "', argument " "1"" of type '" "CoreSession *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_speak" "', argument " "1"" of type '" "CoreSession *""'"); } arg1 = reinterpret_cast< CoreSession * >(argp1); res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_speakText" "', argument " "2"" of type '" "char *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_speak" "', argument " "2"" of type '" "char *""'"); } arg2 = buf2; - result = (int)(arg1)->speakText(arg2); + result = (int)(arg1)->speak(arg2); resultobj = SWIG_From_int(static_cast< int >(result)); if (alloc2 == SWIG_NEWOBJ) delete[] buf2; return resultobj; @@ -4056,28 +4385,20 @@ SWIGINTERN PyObject *_wrap_CoreSession_streamfile(PyObject *SWIGUNUSEDPARM(self) PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; char *arg2 = (char *) 0 ; - void *arg3 = (void *) 0 ; - char *arg4 = (char *) 0 ; - int arg5 ; + int arg3 ; int result; void *argp1 = 0 ; int res1 = 0 ; int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; - int res3 ; - int res4 ; - char *buf4 = 0 ; - int alloc4 = 0 ; - int val5 ; - int ecode5 = 0 ; + int val3 ; + int ecode3 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OOOOO:CoreSession_streamfile",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; + if (!PyArg_ParseTuple(args,(char *)"OOO:CoreSession_streamfile",&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_streamfile" "', argument " "1"" of type '" "CoreSession *""'"); @@ -4088,28 +4409,39 @@ SWIGINTERN PyObject *_wrap_CoreSession_streamfile(PyObject *SWIGUNUSEDPARM(self) SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_streamfile" "', argument " "2"" of type '" "char *""'"); } arg2 = buf2; - res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3), 0, 0); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "CoreSession_streamfile" "', argument " "3"" of type '" "void *""'"); - } - res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "CoreSession_streamfile" "', argument " "4"" of type '" "char *""'"); - } - arg4 = buf4; - ecode5 = SWIG_AsVal_int(obj4, &val5); - if (!SWIG_IsOK(ecode5)) { - SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "CoreSession_streamfile" "', argument " "5"" of type '" "int""'"); + ecode3 = SWIG_AsVal_int(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "CoreSession_streamfile" "', argument " "3"" of type '" "int""'"); } - arg5 = static_cast< int >(val5); - result = (int)(arg1)->streamfile(arg2,arg3,arg4,arg5); + arg3 = static_cast< int >(val3); + result = (int)(arg1)->streamfile(arg2,arg3); resultobj = SWIG_From_int(static_cast< int >(result)); if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - if (alloc4 == SWIG_NEWOBJ) delete[] buf4; return resultobj; fail: if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - if (alloc4 == SWIG_NEWOBJ) delete[] buf4; + return NULL; +} + + +SWIGINTERN PyObject *_wrap_CoreSession_ready(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + CoreSession *arg1 = (CoreSession *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:CoreSession_ready",&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_ready" "', argument " "1"" of type '" "CoreSession *""'"); + } + arg1 = reinterpret_cast< CoreSession * >(argp1); + result = (bool)(arg1)->ready(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: return NULL; } @@ -4270,260 +4602,6 @@ fail: } -SWIGINTERN PyObject *_wrap_input_callback_state_function_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - input_callback_state *arg1 = (input_callback_state *) 0 ; - PyObject *arg2 = (PyObject *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OO:input_callback_state_function_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_function_set" "', argument " "1"" of type '" "input_callback_state *""'"); - } - arg1 = reinterpret_cast< input_callback_state * >(argp1); - arg2 = obj1; - if (arg1) (arg1)->function = arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_input_callback_state_function_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - input_callback_state *arg1 = (input_callback_state *) 0 ; - PyObject *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:input_callback_state_function_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_function_get" "', argument " "1"" of type '" "input_callback_state *""'"); - } - arg1 = reinterpret_cast< input_callback_state * >(argp1); - result = (PyObject *) ((arg1)->function); - resultobj = result; - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_input_callback_state_threadState_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - input_callback_state *arg1 = (input_callback_state *) 0 ; - PyThreadState *arg2 = (PyThreadState *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OO:input_callback_state_threadState_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_threadState_set" "', argument " "1"" of type '" "input_callback_state *""'"); - } - arg1 = reinterpret_cast< input_callback_state * >(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_PyThreadState, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "input_callback_state_threadState_set" "', argument " "2"" of type '" "PyThreadState *""'"); - } - arg2 = reinterpret_cast< PyThreadState * >(argp2); - if (arg1) (arg1)->threadState = arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_input_callback_state_threadState_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - input_callback_state *arg1 = (input_callback_state *) 0 ; - PyThreadState *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:input_callback_state_threadState_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_threadState_get" "', argument " "1"" of type '" "input_callback_state *""'"); - } - arg1 = reinterpret_cast< input_callback_state * >(argp1); - result = (PyThreadState *) ((arg1)->threadState); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PyThreadState, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_input_callback_state_extra_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - input_callback_state *arg1 = (input_callback_state *) 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:input_callback_state_extra_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_extra_set" "', argument " "1"" of type '" "input_callback_state *""'"); - } - arg1 = reinterpret_cast< input_callback_state * >(argp1); - res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, SWIG_POINTER_DISOWN); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "input_callback_state_extra_set" "', argument " "2"" of type '" "void *""'"); - } - if (arg1) (arg1)->extra = arg2; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_input_callback_state_extra_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - input_callback_state *arg1 = (input_callback_state *) 0 ; - void *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:input_callback_state_extra_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_extra_get" "', argument " "1"" of type '" "input_callback_state *""'"); - } - arg1 = reinterpret_cast< input_callback_state * >(argp1); - result = (void *) ((arg1)->extra); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_input_callback_state_funcargs_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - input_callback_state *arg1 = (input_callback_state *) 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:input_callback_state_funcargs_set",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_funcargs_set" "', argument " "1"" of type '" "input_callback_state *""'"); - } - arg1 = reinterpret_cast< input_callback_state * >(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "input_callback_state_funcargs_set" "', argument " "2"" of type '" "char *""'"); - } - arg2 = buf2; - if (arg1->funcargs) delete[] arg1->funcargs; - if (arg2) { - size_t size = strlen(arg2) + 1; - arg1->funcargs = reinterpret_cast< char* >(memcpy((new char[size]), arg2, sizeof(char)*(size))); - } else { - arg1->funcargs = 0; - } - resultobj = SWIG_Py_Void(); - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - return NULL; -} - - -SWIGINTERN PyObject *_wrap_input_callback_state_funcargs_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - input_callback_state *arg1 = (input_callback_state *) 0 ; - char *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:input_callback_state_funcargs_get",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "input_callback_state_funcargs_get" "', argument " "1"" of type '" "input_callback_state *""'"); - } - arg1 = reinterpret_cast< input_callback_state * >(argp1); - result = (char *) ((arg1)->funcargs); - resultobj = SWIG_FromCharPtr(result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_input_callback_state(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - input_callback_state *result = 0 ; - - if (!PyArg_ParseTuple(args,(char *)":new_input_callback_state")) SWIG_fail; - result = (input_callback_state *)new input_callback_state(); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_input_callback_state, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_input_callback_state(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - input_callback_state *arg1 = (input_callback_state *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:delete_input_callback_state",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_input_callback_state, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_input_callback_state" "', argument " "1"" of type '" "input_callback_state *""'"); - } - arg1 = reinterpret_cast< input_callback_state * >(argp1); - delete arg1; - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *input_callback_state_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_input_callback_state, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - SWIGINTERN PyObject *_wrap_new_PySession__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; char *arg1 = (char *) 0 ; @@ -4627,60 +4705,38 @@ fail: } -SWIGINTERN PyObject *_wrap_PySession_streamfile(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { +SWIGINTERN PyObject *_wrap_PySession_setDTMFCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; PySession *arg1 = (PySession *) 0 ; - char *arg2 = (char *) 0 ; - PyObject *arg3 = (PyObject *) 0 ; - char *arg4 = (char *) 0 ; - int arg5 ; - int result; + PyObject *arg2 = (PyObject *) 0 ; + char *arg3 = (char *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - int res4 ; - char *buf4 = 0 ; - int alloc4 = 0 ; - int val5 ; - int ecode5 = 0 ; + int res3 ; + char *buf3 = 0 ; + int alloc3 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OOOOO:PySession_streamfile",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; + if (!PyArg_ParseTuple(args,(char *)"OOO:PySession_setDTMFCallback",&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_streamfile" "', argument " "1"" of type '" "PySession *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySession_setDTMFCallback" "', 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_streamfile" "', argument " "2"" of type '" "char *""'"); + arg2 = obj1; + res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "PySession_setDTMFCallback" "', argument " "3"" of type '" "char *""'"); } - arg2 = buf2; - arg3 = obj2; - res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "PySession_streamfile" "', argument " "4"" of type '" "char *""'"); - } - arg4 = buf4; - ecode5 = SWIG_AsVal_int(obj4, &val5); - if (!SWIG_IsOK(ecode5)) { - SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "PySession_streamfile" "', argument " "5"" of type '" "int""'"); - } - arg5 = static_cast< int >(val5); - result = (int)(arg1)->streamfile(arg2,arg3,arg4,arg5); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - if (alloc4 == SWIG_NEWOBJ) delete[] buf4; + arg3 = buf3; + (arg1)->setDTMFCallback(arg2,arg3); + resultobj = SWIG_Py_Void(); + if (alloc3 == SWIG_NEWOBJ) delete[] buf3; return resultobj; fail: - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - if (alloc4 == SWIG_NEWOBJ) delete[] buf4; + if (alloc3 == SWIG_NEWOBJ) delete[] buf3; return NULL; } @@ -4740,30 +4796,6 @@ static PyMethodDef SwigMethods[] = { { (char *)"api_execute", _wrap_api_execute, METH_VARARGS, NULL}, { (char *)"api_reply_delete", _wrap_api_reply_delete, METH_VARARGS, NULL}, { (char *)"process_callback_result", _wrap_process_callback_result, 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_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}, - { (char *)"CoreSession_setVariable", _wrap_CoreSession_setVariable, METH_VARARGS, NULL}, - { (char *)"CoreSession_getVariable", _wrap_CoreSession_getVariable, METH_VARARGS, NULL}, - { (char *)"CoreSession_playFile", _wrap_CoreSession_playFile, METH_VARARGS, NULL}, - { (char *)"CoreSession_setDTMFCallback", _wrap_CoreSession_setDTMFCallback, METH_VARARGS, NULL}, - { (char *)"CoreSession_speakText", _wrap_CoreSession_speakText, METH_VARARGS, NULL}, - { (char *)"CoreSession_set_tts_parms", _wrap_CoreSession_set_tts_parms, METH_VARARGS, NULL}, - { (char *)"CoreSession_getDigits", _wrap_CoreSession_getDigits, METH_VARARGS, NULL}, - { (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_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_swigregister", CoreSession_swigregister, METH_VARARGS, NULL}, - { (char *)"PythonDTMFCallback", _wrap_PythonDTMFCallback, METH_VARARGS, NULL}, { (char *)"input_callback_state_function_set", _wrap_input_callback_state_function_set, METH_VARARGS, NULL}, { (char *)"input_callback_state_function_get", _wrap_input_callback_state_function_get, METH_VARARGS, NULL}, { (char *)"input_callback_state_threadState_set", _wrap_input_callback_state_threadState_set, METH_VARARGS, NULL}, @@ -4775,9 +4807,36 @@ static PyMethodDef SwigMethods[] = { { (char *)"new_input_callback_state", _wrap_new_input_callback_state, METH_VARARGS, NULL}, { (char *)"delete_input_callback_state", _wrap_delete_input_callback_state, METH_VARARGS, NULL}, { (char *)"input_callback_state_swigregister", input_callback_state_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_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_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}, + { (char *)"CoreSession_setVariable", _wrap_CoreSession_setVariable, METH_VARARGS, NULL}, + { (char *)"CoreSession_getVariable", _wrap_CoreSession_getVariable, METH_VARARGS, NULL}, + { (char *)"CoreSession_playFile", _wrap_CoreSession_playFile, METH_VARARGS, NULL}, + { (char *)"CoreSession_setDTMFCallback", _wrap_CoreSession_setDTMFCallback, METH_VARARGS, NULL}, + { (char *)"CoreSession_speak", _wrap_CoreSession_speak, METH_VARARGS, NULL}, + { (char *)"CoreSession_set_tts_parms", _wrap_CoreSession_set_tts_parms, METH_VARARGS, NULL}, + { (char *)"CoreSession_getDigits", _wrap_CoreSession_getDigits, METH_VARARGS, NULL}, + { (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_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_swigregister", CoreSession_swigregister, METH_VARARGS, NULL}, + { (char *)"PythonDTMFCallback", _wrap_PythonDTMFCallback, METH_VARARGS, NULL}, { (char *)"new_PySession", _wrap_new_PySession, METH_VARARGS, NULL}, { (char *)"delete_PySession", _wrap_delete_PySession, METH_VARARGS, NULL}, - { (char *)"PySession_streamfile", _wrap_PySession_streamfile, METH_VARARGS, NULL}, + { (char *)"PySession_setDTMFCallback", _wrap_PySession_setDTMFCallback, 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_swigregister", PySession_swigregister, METH_VARARGS, NULL}, @@ -4792,7 +4851,6 @@ static void *_p_PySessionTo_p_CoreSession(void *x) { } static swig_type_info _swigt__p_CoreSession = {"_p_CoreSession", "CoreSession *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_PySession = {"_p_PySession", "PySession *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_PyThreadState = {"_p_PyThreadState", "PyThreadState *", 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_switch_channel_t = {"_p_switch_channel_t", "switch_channel_t *", 0, 0, (void*)0, 0}; @@ -4807,7 +4865,6 @@ static swig_type_info _swigt__p_void = {"_p_void", "void *", 0, 0, (void*)0, 0}; static swig_type_info *swig_type_initial[] = { &_swigt__p_CoreSession, &_swigt__p_PySession, - &_swigt__p_PyThreadState, &_swigt__p_char, &_swigt__p_input_callback_state, &_swigt__p_switch_channel_t, @@ -4822,7 +4879,6 @@ static swig_type_info *swig_type_initial[] = { static swig_cast_info _swigc__p_CoreSession[] = { {&_swigt__p_CoreSession, 0, 0, 0}, {&_swigt__p_PySession, _p_PySessionTo_p_CoreSession, 0, 0},{0, 0, 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_PyThreadState[] = { {&_swigt__p_PyThreadState, 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_switch_channel_t[] = { {&_swigt__p_switch_channel_t, 0, 0, 0},{0, 0, 0, 0}}; @@ -4837,7 +4893,6 @@ static swig_cast_info _swigc__p_void[] = { {&_swigt__p_void, 0, 0, 0},{0, 0, 0, static swig_cast_info *swig_cast_initial[] = { _swigc__p_CoreSession, _swigc__p_PySession, - _swigc__p_PyThreadState, _swigc__p_char, _swigc__p_input_callback_state, _swigc__p_switch_channel_t, diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 4a24bc91f6..4c30b4c939 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -28,6 +28,7 @@ CoreSession::CoreSession(switch_core_session_t *new_session) CoreSession::~CoreSession() { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::~CoreSession desctructor"); if (session) { switch_core_session_rwunlock(session); @@ -57,6 +58,7 @@ int CoreSession::preAnswer() void CoreSession::hangup(char *cause) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::hangup\n"); sanity_check_noreturn; switch_channel_hangup(channel, switch_channel_str2cause(cause)); } @@ -88,20 +90,25 @@ void CoreSession::execute(char *app, char *data) int CoreSession::playFile(char *file, char *timer_name) { switch_status_t status; + switch_file_handle_t fh = { 0 }; sanity_check(-1); if (switch_strlen_zero(timer_name)) { timer_name = NULL; } + store_file_handle(&fh); begin_allow_threads(); - status = switch_ivr_play_file(session, NULL, file, ap); + status = switch_ivr_play_file(session, &fh, file, ap); end_allow_threads(); return status == SWITCH_STATUS_SUCCESS ? 1 : 0; } -void CoreSession::setDTMFCallback(switch_input_callback_function_t cb, void *buf, uint32_t buflen) +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; @@ -113,12 +120,23 @@ void CoreSession::setDTMFCallback(switch_input_callback_function_t cb, void *buf } } -int CoreSession::speakText(char *text) + +int CoreSession::speak(char *text) { switch_status_t status; switch_codec_t *codec; sanity_check(-1); + if (!tts_name) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No TTS engine specified"); + return SWITCH_STATUS_FALSE; + } + + if (!voice_name) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No TTS voice specified"); + return SWITCH_STATUS_FALSE; + } + codec = switch_core_session_get_read_codec(session); begin_allow_threads(); status = switch_ivr_speak_text(session, tts_name, voice_name, codec->implementation->samples_per_second, text, ap); @@ -135,12 +153,22 @@ void CoreSession::set_tts_parms(char *tts_name_p, char *voice_name_p) voice_name = strdup(voice_name_p); } -int CoreSession::getDigits(char *dtmf_buf, int len, char *terminators, char *terminator, int timeout) +int CoreSession::getDigits(char *dtmf_buf, + int len, + char *terminators, + char *terminator, + int timeout) { 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, terminators, terminator, (uint32_t) timeout); + status = switch_ivr_collect_digits_count(session, + dtmf_buf, + (uint32_t) len, + (uint32_t) len, + terminators, + terminator, + (uint32_t) timeout); end_allow_threads(); return status == SWITCH_STATUS_SUCCESS ? 1 : 0; } @@ -153,8 +181,15 @@ int CoreSession::transfer(char *extension, char *dialplan, char *context) return status == SWITCH_STATUS_SUCCESS ? 1 : 0; } -int CoreSession::playAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, char *terminators, - char *audio_files, char *bad_input_audio_files, char *dtmf_buf, char *digits_regex) +int CoreSession::playAndGetDigits(int min_digits, + int max_digits, + int max_tries, + int timeout, + char *terminators, + char *audio_files, + char *bad_input_audio_files, + char *dtmf_buf, + char *digits_regex) { switch_status_t status; sanity_check(-1); @@ -173,16 +208,72 @@ int CoreSession::playAndGetDigits(int min_digits, int max_digits, int max_tries, return status == SWITCH_STATUS_SUCCESS ? 1 : 0; } -int CoreSession::streamfile(char *file, void *cb_func, char *funcargs, int starting_sample_count) { - return 0; +int CoreSession::streamfile(char *file, int starting_sample_count) { + + switch_status_t status; + switch_file_handle_t fh = { 0 }; + unsigned int samps; + unsigned int pos = 0; + char *prebuf; + + sanity_check(-1); + fh.samples = starting_sample_count; + store_file_handle(&fh); + + begin_allow_threads(); + status = switch_ivr_play_file(session, &fh, file, ap); + end_allow_threads(); + + if ((prebuf = switch_channel_get_variable(this->channel, "stream_prebuffer"))) { + int maybe = atoi(prebuf); + if (maybe > 0) { + fh.prebuf = maybe; + } + } + + return status == SWITCH_STATUS_SUCCESS ? 1 : 0; + +} + +bool CoreSession::ready() { + + switch_channel_t *channel; + + if (!session) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "You must call the session.originate method before calling this method!\n"); + return false; + } + + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + return switch_channel_ready(channel) != 0; + + } 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::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 + * + * In a few of the methods like playFile and streamfile, + * an empty switch_file_handle_t is created and passed + * to core, and stored in callback args so that the callback + * handler can retrieve it for pausing, ff, rewinding file ptr. + * + * \param fh - a switch_file_handle_t + */ +void CoreSession::store_file_handle(switch_file_handle_t *fh) { + cb_state.extra = fh; // set a file handle so callback handler can pause + args.buf = &cb_state; + ap = &args; +} /* For Emacs: