From 700aa0df5667f7294d0616e10e2ad4b52620201e Mon Sep 17 00:00:00 2001 From: Traun Leyden Date: Sun, 24 Jun 2007 17:38:17 +0000 Subject: [PATCH] streamFiles 2nd argument is now optional. fix segfault that was happening with originate/bridge due to no valid session in b leg. rename streamfile to streamFile. remove playFile since streamFile does the same thing git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5454 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_cpp.h | 22 ++---- src/mod/languages/mod_python/freeswitch.py | 3 +- .../mod_python/freeswitch_python.cpp | 12 ++- src/mod/languages/mod_python/mod_python.c | 7 +- .../languages/mod_python/mod_python_wrap.cpp | 73 ++++--------------- src/switch_cpp.cpp | 39 ++++------ 6 files changed, 47 insertions(+), 109 deletions(-) diff --git a/src/include/switch_cpp.h b/src/include/switch_cpp.h index 86bb200038..13e2c19b3b 100644 --- a/src/include/switch_cpp.h +++ b/src/include/switch_cpp.h @@ -142,29 +142,17 @@ class CoreSession { /** \brief Originate a call to a destination * - * \param old_session - the session where the call is originating from - * and also the session in which _this_ session was - * created + * \param a_leg_sessoin - the session where the call is originating from + * and also the session in which _this_ session was + * created * \param dest - a string representing destination, eg, sofia/mydomain.com/foo@bar.com * \return an int status code indicating success or failure * */ - int originate(CoreSession *aleg_session, + int originate(CoreSession *a_leg_session, char *dest, int timeout=60); - /** \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 * @@ -215,7 +203,7 @@ class CoreSession { * \return an int status code indicating success or failure * */ - int streamfile(char *file, int starting_sample_count); + int streamFile(char *file, int starting_sample_count=0); /** \brief flush any pending events */ diff --git a/src/mod/languages/mod_python/freeswitch.py b/src/mod/languages/mod_python/freeswitch.py index 10721b4b17..422ae14afb 100644 --- a/src/mod/languages/mod_python/freeswitch.py +++ b/src/mod/languages/mod_python/freeswitch.py @@ -115,14 +115,13 @@ class CoreSession(_object): def recordFile(*args): return _freeswitch.CoreSession_recordFile(*args) def setCallerData(*args): return _freeswitch.CoreSession_setCallerData(*args) def originate(*args): return _freeswitch.CoreSession_originate(*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 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) diff --git a/src/mod/languages/mod_python/freeswitch_python.cpp b/src/mod/languages/mod_python/freeswitch_python.cpp index 89c3727ec3..254497c8cd 100644 --- a/src/mod/languages/mod_python/freeswitch_python.cpp +++ b/src/mod/languages/mod_python/freeswitch_python.cpp @@ -175,6 +175,11 @@ switch_status_t PySession::run_dtmf_callback(void *input, bool PySession::begin_allow_threads(void) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::begin_allow_threads() called\n"); + if (!session) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No valid session\n"); + return false; + } + // 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"); @@ -196,7 +201,6 @@ bool PySession::begin_allow_threads(void) { } else { // currently swapped out - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Threadstate already swapd-out! Skipping\n"); return false; } @@ -205,11 +209,15 @@ bool PySession::begin_allow_threads(void) { 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 + if (!session) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No valid session\n"); + return false; + } + 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 { diff --git a/src/mod/languages/mod_python/mod_python.c b/src/mod/languages/mod_python/mod_python.c index 07e477d31c..89cc05d98e 100644 --- a/src/mod/languages/mod_python/mod_python.c +++ b/src/mod/languages/mod_python/mod_python.c @@ -177,18 +177,19 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess // 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"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "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"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "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"); + // they ran python script from cmd line, behave a bit differently (untested) + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Threadstate mod_python.c swap-out! \n"); PyEval_ReleaseThread(tstate); } diff --git a/src/mod/languages/mod_python/mod_python_wrap.cpp b/src/mod/languages/mod_python/mod_python_wrap.cpp index beeb43a5a4..ab07cf73ee 100644 --- a/src/mod/languages/mod_python/mod_python_wrap.cpp +++ b/src/mod/languages/mod_python/mod_python_wrap.cpp @@ -3961,52 +3961,6 @@ fail: } -SWIGINTERN PyObject *_wrap_CoreSession_playFile(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - CoreSession *arg1 = (CoreSession *) 0 ; - char *arg2 = (char *) 0 ; - char *arg3 = (char *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - int res3 ; - char *buf3 = 0 ; - int alloc3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OOO:CoreSession_playFile",&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_playFile" "', 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_playFile" "', argument " "2"" of type '" "char *""'"); - } - arg2 = reinterpret_cast< char * >(buf2); - res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "CoreSession_playFile" "', argument " "3"" of type '" "char *""'"); - } - arg3 = reinterpret_cast< char * >(buf3); - result = (int)(arg1)->playFile(arg2,arg3); - resultobj = SWIG_From_int(static_cast< int >(result)); - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - if (alloc3 == SWIG_NEWOBJ) delete[] buf3; - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) delete[] buf2; - if (alloc3 == SWIG_NEWOBJ) delete[] buf3; - return NULL; -} - - SWIGINTERN PyObject *_wrap_CoreSession_setDTMFCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; @@ -4405,11 +4359,11 @@ fail: } -SWIGINTERN PyObject *_wrap_CoreSession_streamfile(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { +SWIGINTERN PyObject *_wrap_CoreSession_streamFile(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CoreSession *arg1 = (CoreSession *) 0 ; char *arg2 = (char *) 0 ; - int arg3 ; + int arg3 = (int) 0 ; int result; void *argp1 = 0 ; int res1 = 0 ; @@ -4422,23 +4376,25 @@ SWIGINTERN PyObject *_wrap_CoreSession_streamfile(PyObject *SWIGUNUSEDPARM(self) PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OOO:CoreSession_streamfile",&obj0,&obj1,&obj2)) SWIG_fail; + if (!PyArg_ParseTuple(args,(char *)"OO|O: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 *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_streamFile" "', 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_streamfile" "', argument " "2"" of type '" "char *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_streamFile" "', argument " "2"" of type '" "char *""'"); } arg2 = reinterpret_cast< char * >(buf2); - 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""'"); - } - arg3 = static_cast< int >(val3); - result = (int)(arg1)->streamfile(arg2,arg3); + if (obj2) { + 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""'"); + } + 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; return resultobj; @@ -5269,14 +5225,13 @@ static PyMethodDef SwigMethods[] = { { (char *)"CoreSession_recordFile", _wrap_CoreSession_recordFile, METH_VARARGS, NULL}, { (char *)"CoreSession_setCallerData", _wrap_CoreSession_setCallerData, METH_VARARGS, NULL}, { (char *)"CoreSession_originate", _wrap_CoreSession_originate, 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_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}, diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 058dc0712d..3863a51502 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -92,6 +92,7 @@ void CoreSession::execute(char *app, char *data) const switch_application_interface_t *application_interface; sanity_check_noreturn; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::execute. data:%s\n", data); if ((application_interface = switch_loadable_module_get_application_interface(app))) { begin_allow_threads(); switch_core_session_exec(session, application_interface, data); @@ -99,25 +100,6 @@ 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); - 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(void *cbfunc, char *funcargs) { cb_state.funcargs = funcargs; @@ -206,6 +188,7 @@ int CoreSession::transfer(char *extension, char *dialplan, char *context) sanity_check(-1); begin_allow_threads(); status = switch_ivr_session_transfer(session, extension, dialplan, context); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "transfer result: %d\n", status); end_allow_threads(); return status == SWITCH_STATUS_SUCCESS ? 1 : 0; } @@ -240,7 +223,7 @@ int CoreSession::playAndGetDigits(int min_digits, return status == SWITCH_STATUS_SUCCESS ? 1 : 0; } -int CoreSession::streamfile(char *file, int starting_sample_count) { +int CoreSession::streamFile(char *file, int starting_sample_count) { switch_status_t status; switch_file_handle_t fh = { 0 }; @@ -282,7 +265,7 @@ bool CoreSession::ready() { } -int CoreSession::originate(CoreSession *aleg_session, +int CoreSession::originate(CoreSession *a_leg_session, char *dest, int timeout) { @@ -293,11 +276,15 @@ int CoreSession::originate(CoreSession *aleg_session, cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - if (aleg_session != NULL) { - aleg_core_session = aleg_session->session; + if (a_leg_session != NULL) { + aleg_core_session = a_leg_session->session; } - begin_allow_threads(); + // this session has no valid switch_core_session_t at this point, and therefore + // no valid channel. since the threadstate is stored in the channel, and there + // is none, if we try to call begin_alllow_threads it will fail miserably. + // use the 'a leg session' to do the thread swapping stuff. + a_leg_session->begin_allow_threads(); if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n"); @@ -318,11 +305,11 @@ int CoreSession::originate(CoreSession *aleg_session, } - end_allow_threads(); + a_leg_session->end_allow_threads(); return SWITCH_STATUS_SUCCESS; failed: - end_allow_threads(); + a_leg_session->end_allow_threads(); return SWITCH_STATUS_FALSE; }