snake charming

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8998 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale
2008-07-11 19:42:52 +00:00
parent 0f873e692b
commit a3ccefa7e1
23 changed files with 2318 additions and 4906 deletions
+8 -7
View File
@@ -11,19 +11,20 @@ include ../../../../build/modmake.rules
LINK=$(CXXLINK)
PYMOD=freeswitch
PYTHON_SITE_DIR=@PYTHON_SITE_DIR@
PYTHON_SITE_DIR=/usr/lib/python2.4/site-packages
SWIGCFILE=../../../switch_swig.c
SWIGIFILE=../../../switch_swig.i
reswig:
swig -python -shadow -c++ -I../../../../src/include -o mod_python_wrap.cpp mod_python.i
reswig: swigclean mod_python_wrap.cpp
switch_swig_wrap.o: switch_swig_wrap.c Makefile
$(CC) -w $(CFLAGS) -c $< -o $@
swigclean: clean
rm -f mod_python_wrap.* freeswitch.py
switch_swig.o: $(SWIGCFILE) Makefile
$(CC) -w $(CFLAGS) -c $< -o $@
mod_python_wrap.cpp: mod_python_extra.c
swig -python -c++ -I../../../../src/include -oh mod_python_wrap.h -o mod_python_wrap.cpp mod_python.i
echo "#include \"mod_python_extra.c\"" >> mod_python_wrap.cpp
patch -s -p0 -i hack.diff
local_install:
mkdir -m755 -p $(DESTDIR)$(PYTHON_SITE_DIR)
+49 -16
View File
@@ -114,6 +114,27 @@ input_callback_state_t_swigregister(input_callback_state_t)
S_HUP = _freeswitch.S_HUP
S_FREE = _freeswitch.S_FREE
S_RDLOCK = _freeswitch.S_RDLOCK
class DTMF(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, DTMF, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, DTMF, name)
__repr__ = _swig_repr
__swig_setmethods__["digit"] = _freeswitch.DTMF_digit_set
__swig_getmethods__["digit"] = _freeswitch.DTMF_digit_get
if _newclass:digit = _swig_property(_freeswitch.DTMF_digit_get, _freeswitch.DTMF_digit_set)
__swig_setmethods__["duration"] = _freeswitch.DTMF_duration_set
__swig_getmethods__["duration"] = _freeswitch.DTMF_duration_get
if _newclass:duration = _swig_property(_freeswitch.DTMF_duration_get, _freeswitch.DTMF_duration_set)
def __init__(self, *args):
this = _freeswitch.new_DTMF(*args)
try: self.this.append(this)
except: self.this = this
__swig_destroy__ = _freeswitch.delete_DTMF
__del__ = lambda self : None;
DTMF_swigregister = _freeswitch.DTMF_swigregister
DTMF_swigregister(DTMF)
class Stream(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, Stream, name, value)
@@ -274,31 +295,43 @@ console_clean_log = _freeswitch.console_clean_log
bridge = _freeswitch.bridge
hanguphook = _freeswitch.hanguphook
dtmf_callback = _freeswitch.dtmf_callback
S_SWAPPED_IN = _freeswitch.S_SWAPPED_IN
S_SWAPPED_OUT = _freeswitch.S_SWAPPED_OUT
class PySession(CoreSession):
class Session(CoreSession):
__swig_setmethods__ = {}
for _s in [CoreSession]: __swig_setmethods__.update(getattr(_s,'__swig_setmethods__',{}))
__setattr__ = lambda self, name, value: _swig_setattr(self, PySession, name, value)
__setattr__ = lambda self, name, value: _swig_setattr(self, Session, name, value)
__swig_getmethods__ = {}
for _s in [CoreSession]: __swig_getmethods__.update(getattr(_s,'__swig_getmethods__',{}))
__getattr__ = lambda self, name: _swig_getattr(self, PySession, name)
__getattr__ = lambda self, name: _swig_getattr(self, Session, name)
__repr__ = _swig_repr
def __init__(self, *args):
this = _freeswitch.new_PySession(*args)
this = _freeswitch.new_Session(*args)
try: self.this.append(this)
except: self.this = this
__swig_destroy__ = _freeswitch.delete_PySession
__swig_destroy__ = _freeswitch.delete_Session
__del__ = lambda self : None;
def setDTMFCallback(*args): return _freeswitch.PySession_setDTMFCallback(*args)
def setHangupHook(*args): return _freeswitch.PySession_setHangupHook(*args)
def check_hangup_hook(*args): return _freeswitch.PySession_check_hangup_hook(*args)
def hangup(*args): return _freeswitch.PySession_hangup(*args)
def begin_allow_threads(*args): return _freeswitch.PySession_begin_allow_threads(*args)
def end_allow_threads(*args): return _freeswitch.PySession_end_allow_threads(*args)
def run_dtmf_callback(*args): return _freeswitch.PySession_run_dtmf_callback(*args)
PySession_swigregister = _freeswitch.PySession_swigregister
PySession_swigregister(PySession)
def begin_allow_threads(*args): return _freeswitch.Session_begin_allow_threads(*args)
def end_allow_threads(*args): return _freeswitch.Session_end_allow_threads(*args)
def check_hangup_hook(*args): return _freeswitch.Session_check_hangup_hook(*args)
def run_dtmf_callback(*args): return _freeswitch.Session_run_dtmf_callback(*args)
def setInputCallback(*args): return _freeswitch.Session_setInputCallback(*args)
def setHangupHook(*args): return _freeswitch.Session_setHangupHook(*args)
def ready(*args): return _freeswitch.Session_ready(*args)
__swig_setmethods__["cb_function"] = _freeswitch.Session_cb_function_set
__swig_getmethods__["cb_function"] = _freeswitch.Session_cb_function_get
if _newclass:cb_function = _swig_property(_freeswitch.Session_cb_function_get, _freeswitch.Session_cb_function_set)
__swig_setmethods__["cb_arg"] = _freeswitch.Session_cb_arg_set
__swig_getmethods__["cb_arg"] = _freeswitch.Session_cb_arg_get
if _newclass:cb_arg = _swig_property(_freeswitch.Session_cb_arg_get, _freeswitch.Session_cb_arg_set)
__swig_setmethods__["hangup_func"] = _freeswitch.Session_hangup_func_set
__swig_getmethods__["hangup_func"] = _freeswitch.Session_hangup_func_get
if _newclass:hangup_func = _swig_property(_freeswitch.Session_hangup_func_get, _freeswitch.Session_hangup_func_set)
__swig_setmethods__["hangup_func_arg"] = _freeswitch.Session_hangup_func_arg_set
__swig_getmethods__["hangup_func_arg"] = _freeswitch.Session_hangup_func_arg_get
if _newclass:hangup_func_arg = _swig_property(_freeswitch.Session_hangup_func_arg_get, _freeswitch.Session_hangup_func_arg_set)
def setPython(*args): return _freeswitch.Session_setPython(*args)
def setSelf(*args): return _freeswitch.Session_setSelf(*args)
Session_swigregister = _freeswitch.Session_swigregister
Session_swigregister(Session)
+234 -253
View File
@@ -1,320 +1,301 @@
#include <switch.h>
#include "freeswitch_python.h"
using namespace PYTHON;
#define py_sanity_check(x) do { if (!session) { switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "session is not initalized\n"); return x;}} while(0)
#define py_init_vars() do { caller_profile.source = "mod_python"; swapstate = S_SWAPPED_IN; } while(0)
#define py_init_vars() cb_function = cb_arg = hangup_func = hangup_func_arg = NULL; hh = mark = 0; TS = NULL
PySession::PySession():CoreSession()
Session::Session():CoreSession()
{
py_init_vars();
}
PySession::PySession(char *uuid):CoreSession(uuid)
Session::Session(char *uuid):CoreSession(uuid)
{
py_init_vars();
}
PySession::PySession(switch_core_session_t *new_session):CoreSession(new_session)
Session::Session(switch_core_session_t *new_session):CoreSession(new_session)
{
py_init_vars();
}
static switch_status_t python_hanguphook(switch_core_session_t *session_hungup);
void PySession::setDTMFCallback(PyObject * pyfunc, char *funcargs)
Session::~Session()
{
py_sanity_check();
if (!PyCallable_Check(pyfunc)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF function is not a python function.\n");
return;
if (hangup_func) {
if (session) {
switch_core_event_hook_remove_state_change(session, python_hanguphook);
}
Py_XDECREF(hangup_func);
hangup_func = NULL;
}
if (hangup_func_arg) {
Py_XDECREF(hangup_func_arg);
hangup_func_arg = NULL;
}
Py_XINCREF(pyfunc);
CoreSession::setDTMFCallback((void *) pyfunc, funcargs);
if (cb_function) {
Py_XDECREF(cb_function);
cb_function = NULL;
}
if (cb_arg) {
Py_XDECREF(cb_arg);
cb_arg = NULL;
}
if (Self) {
Py_XDECREF(Self);
}
}
bool Session::begin_allow_threads()
{
do_hangup_hook();
if (!TS) {
TS = PyEval_SaveThread();
return true;
}
return false;
}
bool Session::end_allow_threads()
{
if (!TS) {
return false;
}
PyEval_RestoreThread(TS);
TS = NULL;
do_hangup_hook();
return true;
}
void Session::setPython(PyObject *state)
{
Py = state;
}
void Session::setSelf(PyObject *state)
{
Self = state;
}
PyObject *Session::getPython()
{
return Py;
}
bool Session::ready()
{
bool r;
sanity_check(false);
r = switch_channel_ready(channel) != 0;
do_hangup_hook();
return r;
}
void Session::check_hangup_hook()
{
if (hangup_func && (hook_state == CS_HANGUP || hook_state == CS_ROUTING)) {
hh++;
}
}
void Session::do_hangup_hook()
{
PyObject *result, *arglist;
const char *what = hook_state == CS_HANGUP ? "hangup" : "transfer";
if (hh && !mark) {
mark++;
if (hangup_func) {
if (!PyCallable_Check(hangup_func)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "function not callable\n");
return;
}
if (!Self) {
mod_python_conjure_session(NULL, session, NULL);
}
if (hangup_func_arg) {
arglist = Py_BuildValue("(OsO)", Self, what, hangup_func_arg);
} else {
arglist = Py_BuildValue("(Os)", Self, what);
}
if (!(result = PyEval_CallObject(hangup_func, arglist))) {
PyErr_Print();
}
Py_XDECREF(arglist);
Py_XDECREF(hangup_func_arg);
}
}
}
void PySession::setHangupHook(PyObject * pyfunc)
static switch_status_t python_hanguphook(switch_core_session_t *session_hungup)
{
switch_channel_t *channel = switch_core_session_get_channel(session_hungup);
CoreSession *coresession = NULL;
switch_channel_state_t state = switch_channel_get_state(channel);
if ((coresession = (CoreSession *) switch_channel_get_private(channel, "CoreSession"))) {
if (coresession->hook_state != state) {
coresession->hook_state = state;
coresession->check_hangup_hook();
}
}
return SWITCH_STATUS_SUCCESS;
}
void Session::setHangupHook(PyObject *pyfunc, PyObject *arg)
{
if (!PyCallable_Check(pyfunc)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Hangup hook is not a python function.\n");
return;
}
// without this Py_XINCREF, there will be segfaults. basically the python
// interpreter will not know that it should not GC this object.
// callback example: http://docs.python.org/ext/callingPython.html
Py_XINCREF(pyfunc);
CoreSession::setHangupHook((void *) pyfunc);
if (hangup_func) {
if (session) {
switch_core_event_hook_remove_state_change(session, python_hanguphook);
}
Py_XDECREF(hangup_func);
hangup_func = NULL;
}
if (hangup_func_arg) {
Py_XDECREF(hangup_func_arg);
hangup_func_arg = NULL;
}
hangup_func = pyfunc;
hangup_func_arg = arg;
Py_XINCREF(hangup_func);
if (hangup_func_arg) {
Py_XINCREF(hangup_func_arg);
}
switch_channel_set_private(channel, "CoreSession", this);
hook_state = switch_channel_get_state(channel);
switch_core_event_hook_add_state_change(session, python_hanguphook);
}
void PySession::check_hangup_hook()
void Session::setInputCallback(PyObject *cbfunc, PyObject *funcargs)
{
#if 0
PyObject *func;
PyObject *result;
char *resultStr;
bool did_swap_in = false;
#endif
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"check_hangup_hook has been DISABLED, please do not use hangup hooks in python code until further notice!\n");
if (!session) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No valid session\n");
if (!PyCallable_Check(cbfunc)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Hangup hook is not a python function.\n");
return;
}
return;
if (cb_function) {
Py_XDECREF(cb_function);
cb_function = NULL;
}
/*! NEEDS TO BE FIXED:
if (cb_arg) {
Py_XDECREF(cb_arg);
cb_arg = NULL;
}
// The did_swap_in boolean was added to fix the following problem:
// Design flaw - we swap in threadstate based on the assumption that thread state
// is currently _swapped out_ when this hangup hook is called. However, nothing known to
// guarantee that, and if thread state is already swapped in when this is invoked,
// bad things will happen.
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "check hangup hook end_allow_threads\n");
did_swap_in = end_allow_threads();
cb_function = cbfunc;
cb_arg = funcargs;
args.buf = this;
switch_channel_set_private(channel, "CoreSession", this);
if (on_hangup == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "on_hangup is null\n");
return;
}
Py_XINCREF(cb_function);
func = (PyObject *) on_hangup;
if (cb_arg) {
Py_XINCREF(cb_arg);
}
// TODO: to match js implementation, should pass the _python_ PySession
// object instance wrapping this C++ PySession instance. but how do we do that?
// for now, pass the uuid since its better than nothing
PyObject* func_arg = Py_BuildValue("(s)", uuid);
args.input_callback = dtmf_callback;
ap = &args;
result = PyEval_CallObject(func, func_arg);
Py_XDECREF(func_arg);
if (result) {
resultStr = (char *) PyString_AsString(result);
// currently just ignore the result
}
else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to call python hangup callback\n");
PyErr_Print();
PyErr_Clear();
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "check hangup hook begin_allow_threads\n");
if (did_swap_in) {
begin_allow_threads();
}
Py_XDECREF(result);
*/
}
switch_status_t PySession::run_dtmf_callback(void *input, switch_input_type_t itype)
switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t itype)
{
PyObject *func, *arglist;
PyObject *pyresult;
PyObject *headerdict;
PyObject *pyresult, *arglist, *io = NULL;
int ts = 0;
char *str = NULL, *what = "";
char *resultStr;
char *funcargs;
bool did_swap_in = false;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "run_dtmf_callback\n");
if (!cb_state.function) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "cb_state->function is null\n");
return SWITCH_STATUS_FALSE;
if (TS) {
ts++;
end_allow_threads();
}
func = (PyObject *) cb_state.function;
if (!func) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "cb_state->function is null\n");
return SWITCH_STATUS_FALSE;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "cb_state->function is NOT null\n");
}
if (!PyCallable_Check(func)) {
if (!PyCallable_Check(cb_function)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "function not callable\n");
return SWITCH_STATUS_FALSE;
}
funcargs = (char *) cb_state.funcargs;
if (itype == SWITCH_INPUT_TYPE_DTMF) {
arglist = Py_BuildValue("(sis)", input, itype, funcargs);
} else if (itype == SWITCH_INPUT_TYPE_EVENT) {
// DUNNO if this is correct in the case we have an event
// will be of type switch_event_t *event;
// http://www.freeswitch.org/docs/structswitch__event.html
switch_event_t *event = (switch_event_t *) input;
arglist = Py_BuildValue("({s:s}is)", "body", event->body, itype, funcargs);
// build a dictionary with all the headers
switch_event_header_t *hp;
headerdict = PyDict_New();
for (hp = event->headers; hp; hp = hp->next) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding event header to result");
// TODO: create PyObject pointers for name and value
// and explicitly decref them. all ref counting stuff is
// a mess and needs to be tested and looked at closer.
PyDict_SetItem(headerdict, Py_BuildValue("s", hp->name), Py_BuildValue("s", hp->value));
}
// add it to the main event dictionary (first arg in list)
// under key 'headers'
PyObject *dict = PyTuple_GetItem(arglist, 0);
PyDict_SetItemString(dict, "headers", headerdict);
Py_XDECREF(headerdict);
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
io = mod_python_conjure_DTMF(dtmf->digit, dtmf->duration);
what = "dtmf";
} else if (itype == SWITCH_INPUT_TYPE_EVENT){
what = "event";
io = mod_python_conjure_event(NULL, (switch_event_t *) input, NULL);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown input type: %d\n", itype);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unsupported type!\n");
return SWITCH_STATUS_FALSE;
}
if (!arglist) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error building arglist");
return SWITCH_STATUS_FALSE;
if (!Self) {
mod_python_conjure_session(NULL, session, NULL);
}
if (cb_arg) {
arglist = Py_BuildValue("(OsOO)", Self, what, io, cb_arg);
} else {
arglist = Py_BuildValue("(OsO)", Self, what, io);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "run_dtmf_callback end_allow_threads\n");
did_swap_in = end_allow_threads();
pyresult = PyEval_CallObject(func, arglist);
Py_XDECREF(arglist); // Trash arglist
if (pyresult && pyresult != Py_None) {
resultStr = (char *) PyString_AsString(pyresult);
switch_status_t cbresult = process_callback_result(resultStr);
return cbresult;
if ((pyresult = PyEval_CallObject(cb_function, arglist))) {
str = (char *) PyString_AsString(pyresult);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Python callback\n returned None");
PyErr_Print();
PyErr_Clear();
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "run_dtmf_callback begin_allow_threads\n");
if (did_swap_in) {
Py_XDECREF(arglist);
Py_XDECREF(io);
if (cb_arg) {
Py_XDECREF(cb_arg);
}
if (ts) {
begin_allow_threads();
}
Py_XDECREF(pyresult);
return SWITCH_STATUS_SUCCESS;
}
bool PySession::begin_allow_threads(void)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::begin_allow_threads() called\n");
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");
// so lets assume the thread state was swapped in when the python script was started,
// therefore swapin_tstate will be NULL (because there is nothing to swap in, since its
// _already_ swapped in.)
if (swapin_tstate == NULL) {
// currently swapped in
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Threadstate swap-out!\n");
swapin_tstate = PyEval_SaveThread();
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "swapin_tstate: %p\n", swapin_tstate);
// give future swapper-inners something to actually swap in
switch_channel_set_private(channel, "SwapInThreadState", (void *) swapin_tstate);
cb_state.threadState = threadState; // TODO: get rid of this
args.buf = &cb_state;
ap = &args;
return true;
} else {
// currently swapped out
return false;
}
}
bool PySession::end_allow_threads(void)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::end_allow_threads() called\n");
// swap in threadstate from instance variable saved earlier
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
return false;
} else {
// currently swapped out
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Threadstate swap-in!\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "swapin_tstate: %p\n", swapin_tstate);
PyEval_RestoreThread(swapin_tstate);
// dont give any swapper-inners the opportunity to do a double swap
switch_channel_set_private(channel, "SwapInThreadState", NULL);
return true;
}
}
void PySession::hangup(char *cause)
{
// since we INCREF'd this function pointer earlier (so the py gc didnt reclaim it)
// we have to DECREF it, or else the PySession dtor will never get called and
// a zombie channel will be left over using up resources
if (cb_state.function != NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "xdecref on cb_state_function\n");
PyObject *func = (PyObject *) cb_state.function;
Py_XDECREF(func);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "cb_state.function is null\n");
}
CoreSession::hangup(cause);
}
PySession::~PySession()
{
// Should we do any cleanup here?
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::~PySession started\n");
if (on_hangup) {
PyObject *func = (PyObject *) on_hangup;
Py_XDECREF(func);
}
if (cb_state.function != NULL) {
PyObject *func = (PyObject *) cb_state.function;
Py_XDECREF(func);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::~PySession finished\n");
if (str) {
return process_callback_result(str);
}
return SWITCH_STATUS_FALSE;
}
@@ -1,61 +1,45 @@
#ifndef FREESWITCH_PYTHON_H
#define FREESWITCH_PYTHON_H
#include <Python.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DOH
#include <Python.h>
#include "mod_python_extra.h"
}
#endif
#include <switch_cpp.h>
typedef enum {
S_SWAPPED_IN = (1 << 0),
S_SWAPPED_OUT = (1 << 1)
} swap_state_t;
void console_log(char *level_str, char *msg);
void console_clean_log(char *msg);
class PySession : public CoreSession {
namespace PYTHON {
class Session : public CoreSession {
private:
void *threadState;
int swapstate;
virtual void do_hangup_hook();
PyObject *getPython();
PyObject *Py;
PyObject *Self;
int hh;
int mark;
PyThreadState *TS;
public:
PySession();
PySession(char *uuid);
PySession(switch_core_session_t *session);
~PySession();
void setDTMFCallback(PyObject *pyfunc, char *funcargs);
void setHangupHook(PyObject *pyfunc);
void check_hangup_hook();
void hangup(char *cause);
bool begin_allow_threads();
bool end_allow_threads();
Session();
Session(char *uuid);
Session(switch_core_session_t *session);
virtual ~Session();
virtual bool begin_allow_threads();
virtual bool end_allow_threads();
virtual void check_hangup_hook();
/**
* Run DTMF callback
*
* A static method in CoreSession is the first thing called
* upon receving a dtmf/event callback from fs engine, and then
* it gets the PySession instance and calls this method with
* dtmf/event object.
*
* @param input - a dtmf char buffer, or an event 'object' (not sure..)
* @param itype - a SWITCH_INPUT_TYPE_DTMF or a SWITCH_INPUT_TYPE_EVENT
*/
switch_status_t run_dtmf_callback(void *input,
switch_input_type_t itype);
virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype);
void setInputCallback(PyObject *cbfunc, PyObject *funcargs = NULL);
void setHangupHook(PyObject *pyfunc, PyObject *arg = NULL);
bool ready();
PyObject *cb_function;
PyObject *cb_arg;
PyObject *hangup_func;
PyObject *hangup_func_arg;
void setPython(PyObject *state);
void setSelf(PyObject *state);
};
#ifdef __cplusplus
}
#endif
#endif
+53
View File
@@ -0,0 +1,53 @@
--- mod_python_wrap.cpp 2008-07-10 13:14:21.000000000 -0500
+++ old.cpp 2008-07-10 13:13:57.000000000 -0500
@@ -8150,20 +8150,20 @@
}
-SWIGINTERN PyObject *_wrap_new_Session__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_Session__SWIG_0(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
PYTHON::Session *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)":new_Session")) SWIG_fail;
result = (PYTHON::Session *)new PYTHON::Session();
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 );
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 ); result->setPython(self);
return resultobj;
fail:
return NULL;
}
-SWIGINTERN PyObject *_wrap_new_Session__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_Session__SWIG_1(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
char *arg1 = (char *) 0 ;
PYTHON::Session *result = 0 ;
@@ -8179,7 +8179,7 @@
}
arg1 = reinterpret_cast< char * >(buf1);
result = (PYTHON::Session *)new PYTHON::Session(arg1);
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 );
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 ); result->setPython(self);
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
return resultobj;
fail:
@@ -8188,7 +8188,7 @@
}
-SWIGINTERN PyObject *_wrap_new_Session__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_Session__SWIG_2(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
PYTHON::Session *result = 0 ;
@@ -8203,7 +8203,7 @@
}
arg1 = reinterpret_cast< switch_core_session_t * >(argp1);
result = (PYTHON::Session *)new PYTHON::Session(arg1);
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 );
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 ); result->setPython(self);
return resultobj;
fail:
return NULL;
+16 -7
View File
@@ -42,7 +42,7 @@
#endif
#include <switch.h>
#include "mod_python_extra.h"
PyThreadState *mainThreadState = NULL;
@@ -62,7 +62,7 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess
int argc;
int lead = 0;
char *script = NULL;
PyObject *module = NULL;
PyObject *module = NULL, *sp = NULL;
PyObject *function = NULL;
PyObject *arg = NULL;
PyObject *result = NULL;
@@ -139,6 +139,10 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess
PyTuple_SetItem(arg, 0, nada);
}
if (session) {
sp = mod_python_conjure_session(module, session, "session");
}
// invoke the handler
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call python script \n");
result = PyEval_CallObjectWithKeywords(function, arg, (PyObject *) NULL);
@@ -150,21 +154,26 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess
PyErr_Print();
PyErr_Clear();
}
goto done_swap_out;
done:
switch_safe_free(dupargs);
if (sp) {
Py_XDECREF(sp);
}
done_swap_out:
// decrement ref counts
Py_XDECREF(module);
Py_XDECREF(function);
Py_XDECREF(arg);
Py_XDECREF(result);
// swap out thread state
if (session) {
//switch_core_session_rwunlock(session);
// record the fact that thread state is swapped in
switch_channel_t *channel = switch_core_session_get_channel(session);
PyThreadState *swapin_tstate = (PyThreadState *) switch_channel_get_private(channel, "SwapInThreadState");
@@ -189,7 +198,7 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No session: Threadstate mod_python.c swap-out! \n");
PyEval_ReleaseThread(tstate);
}
switch_safe_free(dupargs);
@@ -26,5 +26,3 @@
%include switch_swigable_cpp.h
%include freeswitch_python.h
@@ -0,0 +1,65 @@
SWITCH_BEGIN_EXTERN_C
PyObject *mod_python_conjure_event(PyObject *module, switch_event_t *event, const char *name)
{
PyObject *obj;
Event *result = new Event(event, 0);
obj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Event, SWIG_POINTER_OWN );
if (module && name) {
PyDict_SetItem(PyModule_GetDict(module), Py_BuildValue("s", name), obj);
Py_DECREF(obj);
}
return obj;
}
PyObject *mod_python_conjure_stream(PyObject *module, switch_stream_handle_t *stream, const char *name)
{
PyObject *obj;
Stream *result = new Stream(stream);
obj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Stream, SWIG_POINTER_OWN );
if (module && name) {
PyDict_SetItem(PyModule_GetDict(module), Py_BuildValue("s", name), obj);
Py_DECREF(obj);
}
return obj;
}
PyObject *mod_python_conjure_session(PyObject *module, switch_core_session_t *session, const char *name)
{
PyObject *obj;
PYTHON::Session *result = new PYTHON::Session(session);
obj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_OWN);
result->setPython(module);
result->setSelf(obj);
if (module && name) {
PyDict_SetItem(PyModule_GetDict(module), Py_BuildValue("s", name), obj);
Py_DECREF(obj);
}
return obj;
}
PyObject *mod_python_conjure_DTMF(char digit, int32_t duration)
{
PyObject *obj;
DTMF *result = new DTMF(digit, duration);
obj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DTMF, SWIG_POINTER_OWN);
return obj;
}
SWITCH_END_EXTERN_C
@@ -0,0 +1,11 @@
#ifndef MOD_PYTHON_EXTRA
#define MOD_PYTHON_EXTRA
SWITCH_BEGIN_EXTERN_C
PyObject *mod_python_conjure_event(PyObject *module, switch_event_t *event, const char *name);
PyObject *mod_python_conjure_stream(PyObject *module, switch_stream_handle_t *stream, const char *name);
PyObject *mod_python_conjure_session(PyObject *module, switch_core_session_t *session, const char *name);
PyObject *mod_python_conjure_DTMF(char digit, int32_t duration);
SWITCH_END_EXTERN_C
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff