mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-06 04:11:52 +00:00
merge changes from branch http://svn.freeswitch.org/svn/freeswitch/branches/greenlizard/ that changes the session container implementation to use the one in the core, and an inherited class in python. Please note that this changes the python script api to more closely match (it is still a subset) the one already in place and documented for spidermonkey, and will break all your scripts that are currently working.. Fix a fatal bug causing segfaults in mod_python when using the callbacks.
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5242 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
@@ -2,172 +2,55 @@
|
||||
|
||||
#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)
|
||||
|
||||
SessionContainer::SessionContainer(char *nuuid)
|
||||
{
|
||||
uuid = nuuid;
|
||||
dtmfCallbackFunction = NULL;
|
||||
tts_name = NULL;
|
||||
voice_name = NULL;
|
||||
|
||||
if (session = switch_core_session_locate(uuid)) {
|
||||
channel = switch_core_session_get_channel(session);
|
||||
}
|
||||
}
|
||||
|
||||
SessionContainer::~SessionContainer()
|
||||
{
|
||||
|
||||
if (session) {
|
||||
switch_core_session_rwunlock(session);
|
||||
}
|
||||
}
|
||||
|
||||
int SessionContainer::answer()
|
||||
{
|
||||
switch_status_t status;
|
||||
|
||||
sanity_check(-1);
|
||||
status = switch_channel_answer(channel);
|
||||
return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
|
||||
}
|
||||
|
||||
int SessionContainer::pre_answer()
|
||||
{
|
||||
switch_status_t status;
|
||||
sanity_check(-1);
|
||||
switch_channel_pre_answer(channel);
|
||||
return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
|
||||
}
|
||||
|
||||
void SessionContainer::hangup(char *cause)
|
||||
{
|
||||
sanity_check();
|
||||
switch_channel_hangup(channel, switch_channel_str2cause(cause));
|
||||
}
|
||||
|
||||
void SessionContainer::set_variable(char *var, char *val)
|
||||
{
|
||||
sanity_check();
|
||||
switch_channel_set_variable(channel, var, val);
|
||||
}
|
||||
|
||||
char *SessionContainer::get_variable(char *var)
|
||||
{
|
||||
sanity_check(NULL);
|
||||
return switch_channel_get_variable(channel, var);
|
||||
}
|
||||
|
||||
void SessionContainer::execute(char *app, char *data)
|
||||
{
|
||||
const switch_application_interface_t *application_interface;
|
||||
sanity_check();
|
||||
|
||||
if ((application_interface = switch_loadable_module_get_application_interface(app))) {
|
||||
switch_core_session_exec(session, application_interface, data);
|
||||
}
|
||||
}
|
||||
|
||||
int SessionContainer::play_file(char *file, char *timer_name)
|
||||
int PySession::streamfile(char *file, PyObject *pyfunc, char *funcargs, int starting_sample_count)
|
||||
{
|
||||
switch_status_t status;
|
||||
switch_input_args_t args = { 0 }, *ap = NULL;
|
||||
sanity_check(-1);
|
||||
struct input_callback_state cb_state = { 0 };
|
||||
switch_file_handle_t fh = { 0 };
|
||||
|
||||
if (switch_strlen_zero(timer_name)) {
|
||||
timer_name = NULL;
|
||||
}
|
||||
sanity_check(-1);
|
||||
cb_state.funcargs = funcargs;
|
||||
fh.samples = starting_sample_count;
|
||||
|
||||
if (dtmfCallbackFunction) {
|
||||
args.buf = dtmfCallbackFunction;
|
||||
args.input_callback = PythonDTMFCallback;
|
||||
ap = &args;
|
||||
}
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
status = switch_ivr_play_file(session, NULL, file, ap);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
|
||||
}
|
||||
|
||||
void SessionContainer::set_dtmf_callback(PyObject *pyfunc)
|
||||
{
|
||||
sanity_check();
|
||||
if (!PyCallable_Check(pyfunc)) {
|
||||
dtmfCallbackFunction = NULL;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "DTMF function is not a python function.");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF function is not a python function.");
|
||||
}
|
||||
else {
|
||||
dtmfCallbackFunction = pyfunc;
|
||||
}
|
||||
}
|
||||
|
||||
int SessionContainer::speak_text(char *text)
|
||||
{
|
||||
switch_status_t status;
|
||||
switch_codec_t *codec;
|
||||
switch_input_args_t args = { 0 }, *ap = NULL;
|
||||
|
||||
sanity_check(-1);
|
||||
|
||||
codec = switch_core_session_get_read_codec(session);
|
||||
if (dtmfCallbackFunction) {
|
||||
args.buf = dtmfCallbackFunction;
|
||||
args.input_callback = PythonDTMFCallback;
|
||||
ap = &args;
|
||||
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
|
||||
ap = &args;
|
||||
}
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
status = switch_ivr_speak_text(session, tts_name, voice_name, codec->implementation->samples_per_second, text, ap);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void SessionContainer::set_tts_parms(char *tts_name_p, char *voice_name_p)
|
||||
{
|
||||
sanity_check();
|
||||
tts_name = tts_name_p;
|
||||
voice_name = voice_name_p;
|
||||
}
|
||||
|
||||
int SessionContainer::get_digits(char *dtmf_buf, int len, char *terminators, char *terminator, int timeout)
|
||||
{
|
||||
switch_status_t status;
|
||||
sanity_check(-1);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
status = switch_ivr_collect_digits_count(session, dtmf_buf,(uint32_t) len,(uint32_t) len, terminators, terminator, (uint32_t) timeout);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
|
||||
}
|
||||
|
||||
int SessionContainer::transfer(char *extension, char *dialplan, char *context)
|
||||
{
|
||||
switch_status_t status;
|
||||
sanity_check(-1);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
status = switch_ivr_session_transfer(session, extension, dialplan, context);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
|
||||
}
|
||||
|
||||
int SessionContainer::play_and_get_digits(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);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
status = switch_play_and_get_digits( session, (uint32_t) min_digits,(uint32_t) max_digits,
|
||||
(uint32_t) max_tries, (uint32_t) timeout,
|
||||
terminators, audio_files, bad_input_audio_files, dtmf_buf, 128, digits_regex);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
void PySession::begin_allow_threads(void) {
|
||||
threadState = PyEval_SaveThread();
|
||||
}
|
||||
|
||||
void PySession::end_allow_threads(void) {
|
||||
PyEval_RestoreThread(threadState);
|
||||
}
|
||||
|
||||
PySession::~PySession() {
|
||||
// Should we do any cleanup here?
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user