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:
@@ -5,32 +5,165 @@
|
||||
%cstring_bounded_mutable(char *terminator, 8);
|
||||
|
||||
%{
|
||||
#include "switch_cpp.h"
|
||||
#include "freeswitch_python.h"
|
||||
%}
|
||||
|
||||
%include switch_cpp.h
|
||||
%include freeswitch_python.h
|
||||
|
||||
%{
|
||||
|
||||
|
||||
|
||||
switch_status_t PythonDTMFCallback(switch_core_session_t *session,
|
||||
void *input,
|
||||
switch_input_type_t itype,
|
||||
void *buf,
|
||||
void *buf,
|
||||
unsigned int buflen)
|
||||
{
|
||||
PyObject *func, *arglist;
|
||||
PyObject *result;
|
||||
switch_status_t dres = SWITCH_STATUS_FALSE;
|
||||
char *resultStr;
|
||||
char *funcargs;
|
||||
struct input_callback_state *cb_state;
|
||||
switch_file_handle_t *fh = NULL;
|
||||
PyThreadState *threadState = NULL;
|
||||
|
||||
if (!buf) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buf pointer is null");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
func = (PyObject *) buf; // Get Python function
|
||||
arglist = Py_BuildValue("(si)", input, itype); // Build argument list
|
||||
result = PyEval_CallObject(func, arglist); // Call Python
|
||||
Py_DECREF(arglist); // Trash arglist
|
||||
if (result) { // If no errors, return double
|
||||
dres = (switch_status_t) PyInt_AsLong(result);
|
||||
cb_state = (input_callback_state *) buf;
|
||||
|
||||
func = (PyObject *) cb_state->function;
|
||||
if (!func) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cb_state->function is null");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
Py_XDECREF(result);
|
||||
return dres;
|
||||
if (!PyCallable_Check(func)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "function not callable");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
funcargs = (char *) cb_state->funcargs;
|
||||
|
||||
arglist = Py_BuildValue("(sis)", input, itype, funcargs);
|
||||
if (!arglist) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error building arglist");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
threadState = (PyThreadState *) cb_state->threadState;
|
||||
if (!threadState) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error, invalid threadstate");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
PyEval_RestoreThread(threadState); // nasty stuff happens when py interp has no thread state
|
||||
result = PyEval_CallObject(func, arglist);
|
||||
threadState = PyEval_SaveThread();
|
||||
|
||||
|
||||
Py_DECREF(arglist); // Trash arglist
|
||||
if (result && result != Py_None) {
|
||||
resultStr = (char *) PyString_AsString(result);
|
||||
Py_XDECREF(result);
|
||||
return process_callback_result(resultStr, cb_state, session);
|
||||
}
|
||||
else {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
switch_status_t process_callback_result(char *ret,
|
||||
struct input_callback_state *cb_state,
|
||||
switch_core_session_t *session)
|
||||
{
|
||||
|
||||
switch_file_handle_t *fh = NULL;
|
||||
fh = (switch_file_handle_t *) cb_state->extra;
|
||||
|
||||
|
||||
if (!ret) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (!strncasecmp(ret, "speed", 4)) {
|
||||
char *p;
|
||||
|
||||
if ((p = strchr(ret, ':'))) {
|
||||
p++;
|
||||
if (*p == '+' || *p == '-') {
|
||||
int step;
|
||||
if (!(step = atoi(p))) {
|
||||
step = 1;
|
||||
}
|
||||
fh->speed += step;
|
||||
} else {
|
||||
int speed = atoi(p);
|
||||
fh->speed = speed;
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
|
||||
} else if (!strcasecmp(ret, "pause")) {
|
||||
if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
|
||||
switch_clear_flag(fh, SWITCH_FILE_PAUSE);
|
||||
} else {
|
||||
switch_set_flag(fh, SWITCH_FILE_PAUSE);
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
} else if (!strcasecmp(ret, "stop")) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
} else if (!strcasecmp(ret, "restart")) {
|
||||
unsigned int pos = 0;
|
||||
fh->speed = 0;
|
||||
switch_core_file_seek(fh, &pos, 0, SEEK_SET);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
} else if (!strncasecmp(ret, "seek", 4)) {
|
||||
switch_codec_t *codec;
|
||||
unsigned int samps = 0;
|
||||
unsigned int pos = 0;
|
||||
char *p;
|
||||
codec = switch_core_session_get_read_codec(session);
|
||||
|
||||
if ((p = strchr(ret, ':'))) {
|
||||
p++;
|
||||
if (*p == '+' || *p == '-') {
|
||||
int step;
|
||||
if (!(step = atoi(p))) {
|
||||
step = 1000;
|
||||
}
|
||||
if (step > 0) {
|
||||
samps = step * (codec->implementation->samples_per_second / 1000);
|
||||
switch_core_file_seek(fh, &pos, samps, SEEK_CUR);
|
||||
} else {
|
||||
samps = step * (codec->implementation->samples_per_second / 1000);
|
||||
switch_core_file_seek(fh, &pos, fh->pos - samps, SEEK_SET);
|
||||
}
|
||||
} else {
|
||||
samps = atoi(p) * (codec->implementation->samples_per_second / 1000);
|
||||
switch_core_file_seek(fh, &pos, samps, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user