* implement originate() and bridge() methods in CoreSession. * api changes for originate() : no longer passes 11 arguments git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5410 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
b7910ac8f9
commit
e028f2691c
|
@ -16,6 +16,16 @@ void console_log(char *level_str, char *msg);
|
|||
void console_clean_log(char *msg);
|
||||
char *api_execute(char *cmd, char *arg);
|
||||
void api_reply_delete(char *reply);
|
||||
|
||||
|
||||
/**
|
||||
* \brief - process language specific callback results
|
||||
*
|
||||
* First the actual callback is called, (in the case of python,
|
||||
* PythonDTMFCallback), it then calls the language specific callback defined
|
||||
* by the user (eg, some python method), and then _this_ function is called
|
||||
* with the results of the language specific callback.
|
||||
*/
|
||||
switch_status_t process_callback_result(char *raw_result,
|
||||
struct input_callback_state *cb_state,
|
||||
switch_core_session_t *session);
|
||||
|
@ -28,30 +38,55 @@ typedef struct input_callback_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
|
||||
} input_callback_state;
|
||||
} input_callback_state_t;
|
||||
|
||||
|
||||
class CoreSession {
|
||||
protected:
|
||||
switch_input_args_t args;
|
||||
switch_input_args_t *ap;
|
||||
switch_input_args_t args; // holds ptr to cb function and input_callback_state struct
|
||||
// which has a language specific callback function
|
||||
switch_input_args_t *ap; // ptr to args .. (is this really needed?)
|
||||
switch_caller_profile_t caller_profile; // avoid passing so many args to originate,
|
||||
// instead set them here first
|
||||
char *uuid;
|
||||
char *tts_name;
|
||||
char *voice_name;
|
||||
void store_file_handle(switch_file_handle_t *fh);
|
||||
public:
|
||||
CoreSession();
|
||||
CoreSession(char *uuid);
|
||||
CoreSession(switch_core_session_t *new_session);
|
||||
virtual ~CoreSession();
|
||||
switch_core_session_t *session;
|
||||
switch_channel_t *channel;
|
||||
input_callback_state cb_state;
|
||||
input_callback_state cb_state; // callback state, always pointed to by the buf
|
||||
// field in this->args
|
||||
|
||||
int answer();
|
||||
int preAnswer();
|
||||
void hangup(char *cause);
|
||||
void setVariable(char *var, char *val);
|
||||
char *getVariable(char *var);
|
||||
|
||||
/** \brief Set attributes of caller data for purposes of outgoing calls
|
||||
* \param var - the variable name, eg, "caller_id_name"
|
||||
* \param val - the data to set, eg, "bob"
|
||||
*/
|
||||
void setCallerData(char *var, char *val);
|
||||
|
||||
/** \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 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,
|
||||
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
|
||||
|
@ -125,10 +160,35 @@ class CoreSession {
|
|||
virtual void begin_allow_threads();
|
||||
virtual void end_allow_threads();
|
||||
|
||||
/** \brief Get the uuid of this session
|
||||
* \return the uuid of this session
|
||||
*/
|
||||
char* get_uuid() const { return uuid; };
|
||||
|
||||
/** \brief Get the callback function arguments associated with this session
|
||||
* \return a const reference to the callback function arguments
|
||||
*/
|
||||
const switch_input_args_t& get_cb_args() const { return args; };
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* ---- functions not bound to CoreSession instance ----- */
|
||||
|
||||
void console_log(char *level_str, char *msg);
|
||||
void console_clean_log(char *msg);
|
||||
char *api_execute(char *cmd, char *arg);
|
||||
void api_reply_delete(char *reply);
|
||||
|
||||
/** \brief bridge the audio of session_b into session_a
|
||||
*
|
||||
* NOTE: the stuff regarding the dtmf callback might be completely
|
||||
* wrong and has not been reviewed or tested
|
||||
*/
|
||||
void bridge(CoreSession &session_a, CoreSession &session_b);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -53,32 +53,32 @@ 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 input_callback_state(_object):
|
||||
class input_callback_state_t(_object):
|
||||
__swig_setmethods__ = {}
|
||||
__setattr__ = lambda self, name, value: _swig_setattr(self, input_callback_state, name, value)
|
||||
__setattr__ = lambda self, name, value: _swig_setattr(self, input_callback_state_t, name, value)
|
||||
__swig_getmethods__ = {}
|
||||
__getattr__ = lambda self, name: _swig_getattr(self, input_callback_state, name)
|
||||
__getattr__ = lambda self, name: _swig_getattr(self, input_callback_state_t, name)
|
||||
__repr__ = _swig_repr
|
||||
__swig_setmethods__["function"] = _freeswitch.input_callback_state_function_set
|
||||
__swig_getmethods__["function"] = _freeswitch.input_callback_state_function_get
|
||||
if _newclass:function = _swig_property(_freeswitch.input_callback_state_function_get, _freeswitch.input_callback_state_function_set)
|
||||
__swig_setmethods__["threadState"] = _freeswitch.input_callback_state_threadState_set
|
||||
__swig_getmethods__["threadState"] = _freeswitch.input_callback_state_threadState_get
|
||||
if _newclass:threadState = _swig_property(_freeswitch.input_callback_state_threadState_get, _freeswitch.input_callback_state_threadState_set)
|
||||
__swig_setmethods__["extra"] = _freeswitch.input_callback_state_extra_set
|
||||
__swig_getmethods__["extra"] = _freeswitch.input_callback_state_extra_get
|
||||
if _newclass:extra = _swig_property(_freeswitch.input_callback_state_extra_get, _freeswitch.input_callback_state_extra_set)
|
||||
__swig_setmethods__["funcargs"] = _freeswitch.input_callback_state_funcargs_set
|
||||
__swig_getmethods__["funcargs"] = _freeswitch.input_callback_state_funcargs_get
|
||||
if _newclass:funcargs = _swig_property(_freeswitch.input_callback_state_funcargs_get, _freeswitch.input_callback_state_funcargs_set)
|
||||
__swig_setmethods__["function"] = _freeswitch.input_callback_state_t_function_set
|
||||
__swig_getmethods__["function"] = _freeswitch.input_callback_state_t_function_get
|
||||
if _newclass:function = _swig_property(_freeswitch.input_callback_state_t_function_get, _freeswitch.input_callback_state_t_function_set)
|
||||
__swig_setmethods__["threadState"] = _freeswitch.input_callback_state_t_threadState_set
|
||||
__swig_getmethods__["threadState"] = _freeswitch.input_callback_state_t_threadState_get
|
||||
if _newclass:threadState = _swig_property(_freeswitch.input_callback_state_t_threadState_get, _freeswitch.input_callback_state_t_threadState_set)
|
||||
__swig_setmethods__["extra"] = _freeswitch.input_callback_state_t_extra_set
|
||||
__swig_getmethods__["extra"] = _freeswitch.input_callback_state_t_extra_get
|
||||
if _newclass:extra = _swig_property(_freeswitch.input_callback_state_t_extra_get, _freeswitch.input_callback_state_t_extra_set)
|
||||
__swig_setmethods__["funcargs"] = _freeswitch.input_callback_state_t_funcargs_set
|
||||
__swig_getmethods__["funcargs"] = _freeswitch.input_callback_state_t_funcargs_get
|
||||
if _newclass:funcargs = _swig_property(_freeswitch.input_callback_state_t_funcargs_get, _freeswitch.input_callback_state_t_funcargs_set)
|
||||
def __init__(self, *args):
|
||||
this = _freeswitch.new_input_callback_state(*args)
|
||||
this = _freeswitch.new_input_callback_state_t(*args)
|
||||
try: self.this.append(this)
|
||||
except: self.this = this
|
||||
__swig_destroy__ = _freeswitch.delete_input_callback_state
|
||||
__swig_destroy__ = _freeswitch.delete_input_callback_state_t
|
||||
__del__ = lambda self : None;
|
||||
input_callback_state_swigregister = _freeswitch.input_callback_state_swigregister
|
||||
input_callback_state_swigregister(input_callback_state)
|
||||
input_callback_state_t_swigregister = _freeswitch.input_callback_state_t_swigregister
|
||||
input_callback_state_t_swigregister(input_callback_state_t)
|
||||
|
||||
class CoreSession(_object):
|
||||
__swig_setmethods__ = {}
|
||||
|
@ -106,6 +106,8 @@ class CoreSession(_object):
|
|||
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 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)
|
||||
|
@ -118,9 +120,12 @@ class CoreSession(_object):
|
|||
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)
|
||||
def get_uuid(*args): return _freeswitch.CoreSession_get_uuid(*args)
|
||||
def get_cb_args(*args): return _freeswitch.CoreSession_get_cb_args(*args)
|
||||
CoreSession_swigregister = _freeswitch.CoreSession_swigregister
|
||||
CoreSession_swigregister(CoreSession)
|
||||
|
||||
bridge = _freeswitch.bridge
|
||||
PythonDTMFCallback = _freeswitch.PythonDTMFCallback
|
||||
class PySession(CoreSession):
|
||||
__swig_setmethods__ = {}
|
||||
|
|
|
@ -1,6 +1,22 @@
|
|||
#include "freeswitch_python.h"
|
||||
|
||||
#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)
|
||||
#define init_vars() do { caller_profile.source = "mod_python"; } while(0)
|
||||
|
||||
PySession::PySession() : CoreSession()
|
||||
{
|
||||
init_vars();
|
||||
}
|
||||
|
||||
PySession::PySession(char *uuid) : CoreSession(uuid)
|
||||
{
|
||||
init_vars();
|
||||
}
|
||||
|
||||
PySession::PySession(switch_core_session_t *new_session) : CoreSession(new_session)
|
||||
{
|
||||
init_vars();
|
||||
}
|
||||
|
||||
|
||||
void PySession::setDTMFCallback(PyObject *pyfunc, char *funcargs)
|
||||
|
@ -34,15 +50,16 @@ void PySession::setDTMFCallback(PyObject *pyfunc, char *funcargs)
|
|||
void PySession::begin_allow_threads(void) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::begin_allow_threads() called\n");
|
||||
|
||||
// swap out threadstate and store in instance variable
|
||||
threadState = (void *) PyEval_SaveThread();
|
||||
cb_state.threadState = threadState;
|
||||
// cb_state.extra = &fh;
|
||||
args.buf = &cb_state;
|
||||
ap = &args;
|
||||
}
|
||||
|
||||
void 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
|
||||
PyEval_RestoreThread(((PyThreadState *)threadState));
|
||||
}
|
||||
|
||||
|
@ -52,4 +69,88 @@ PySession::~PySession() {
|
|||
}
|
||||
|
||||
|
||||
/* ----- functions not bound to PySession instance ------ */
|
||||
|
||||
|
||||
switch_status_t PythonDTMFCallback(switch_core_session_t *session,
|
||||
void *input,
|
||||
switch_input_type_t itype,
|
||||
void *buf,
|
||||
unsigned int buflen)
|
||||
{
|
||||
PyObject *func, *arglist;
|
||||
PyObject *result;
|
||||
char *resultStr;
|
||||
char *funcargs;
|
||||
input_callback_state_t *cb_state;
|
||||
switch_file_handle_t *fh = NULL;
|
||||
PyThreadState *threadState = NULL;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PythonDTMFCallback\n");
|
||||
|
||||
if (!buf) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buf pointer is null");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
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\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)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "function not callable\n");
|
||||
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\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "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_DEBUG, "restored threadstate, calling python function: %p\n", func);
|
||||
|
||||
result = PyEval_CallObject(func, arglist);
|
||||
|
||||
threadState = PyEval_SaveThread();
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "called python function\n");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@ extern "C" {
|
|||
|
||||
|
||||
|
||||
// declaration for function that is defined in mod_python.i
|
||||
extern switch_status_t PythonDTMFCallback(switch_core_session *session,
|
||||
void *input,
|
||||
switch_input_type_t itype,
|
||||
void *buf,
|
||||
unsigned int buflen);
|
||||
switch_status_t PythonDTMFCallback(switch_core_session *session,
|
||||
void *input,
|
||||
switch_input_type_t itype,
|
||||
void *buf,
|
||||
unsigned int buflen);
|
||||
|
||||
|
||||
void console_log(char *level_str, char *msg);
|
||||
void console_clean_log(char *msg);
|
||||
|
@ -30,8 +30,9 @@ class PySession : public CoreSession {
|
|||
private:
|
||||
void *threadState;
|
||||
public:
|
||||
PySession(char *uuid) : CoreSession(uuid) {}
|
||||
PySession(switch_core_session_t *session) : CoreSession(session) {}
|
||||
PySession();
|
||||
PySession(char *uuid);
|
||||
PySession(switch_core_session_t *session);
|
||||
~PySession();
|
||||
void setDTMFCallback(PyObject *pyfunc, char *funcargs);
|
||||
void begin_allow_threads();
|
||||
|
@ -39,6 +40,7 @@ class PySession : public CoreSession {
|
|||
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,218 +1,21 @@
|
|||
%module freeswitch
|
||||
%include "cstring.i"
|
||||
|
||||
%cstring_bounded_mutable(char *dtmf_buf, 128);
|
||||
%cstring_bounded_mutable(char *terminator, 8);
|
||||
|
||||
/** insert the following includes into generated code so it compiles */
|
||||
%{
|
||||
#include "switch_cpp.h"
|
||||
#include "freeswitch_python.h"
|
||||
%}
|
||||
|
||||
/**
|
||||
* tell swig to grok everything defined in these header files and
|
||||
* build all sorts of c wrappers and python shadows of the c wrappers.
|
||||
*/
|
||||
%include switch_cpp.h
|
||||
%include freeswitch_python.h
|
||||
|
||||
%{
|
||||
/** hmm .. dunno why this is here */
|
||||
%cstring_bounded_mutable(char *dtmf_buf, 128);
|
||||
%cstring_bounded_mutable(char *terminator, 8);
|
||||
|
||||
|
||||
|
||||
switch_status_t PythonDTMFCallback(switch_core_session_t *session,
|
||||
void *input,
|
||||
switch_input_type_t itype,
|
||||
void *buf,
|
||||
unsigned int buflen)
|
||||
{
|
||||
PyObject *func, *arglist;
|
||||
PyObject *result;
|
||||
char *resultStr;
|
||||
char *funcargs;
|
||||
struct input_callback_state *cb_state;
|
||||
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;
|
||||
}
|
||||
|
||||
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\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\n");
|
||||
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\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) {
|
||||
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 (!fh) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void console_log(char *level_str, char *msg)
|
||||
{
|
||||
switch_log_level_t level = SWITCH_LOG_DEBUG;
|
||||
if (level_str) {
|
||||
level = switch_log_str2level(level_str);
|
||||
}
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, level, msg);
|
||||
}
|
||||
|
||||
void console_clean_log(char *msg)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN,SWITCH_LOG_DEBUG, msg);
|
||||
}
|
||||
|
||||
|
||||
char *api_execute(char *cmd, char *arg)
|
||||
{
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
switch_api_execute(cmd, arg, NULL, &stream);
|
||||
return (char *) stream.data;
|
||||
}
|
||||
|
||||
void api_reply_delete(char *reply)
|
||||
{
|
||||
if (!switch_strlen_zero(reply)) {
|
||||
free(reply);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
%}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,14 @@
|
|||
|
||||
#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)
|
||||
#define sanity_check_noreturn do { if (!session) { switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "session is not initalized\n"); return;}} while(0)
|
||||
#define init_vars() do { session = NULL; channel = NULL; uuid = NULL; tts_name = NULL; voice_name = NULL; memset(&args, 0, sizeof(args)); ap = NULL;} while(0)
|
||||
#define init_vars() do { session = NULL; channel = NULL; uuid = NULL; tts_name = NULL; voice_name = NULL; memset(&args, 0, sizeof(args)); ap = NULL; caller_profile.source = "mod_unknown"; caller_profile.dialplan = ""; caller_profile.context = ""; caller_profile.caller_id_name = ""; caller_profile.caller_id_number = ""; caller_profile.network_addr = ""; caller_profile.ani = ""; caller_profile.aniii = ""; caller_profile.rdnis = ""; caller_profile.username = ""; } while(0)
|
||||
|
||||
|
||||
|
||||
CoreSession::CoreSession()
|
||||
{
|
||||
init_vars();
|
||||
}
|
||||
|
||||
CoreSession::CoreSession(char *nuuid)
|
||||
{
|
||||
|
@ -177,7 +184,9 @@ int CoreSession::transfer(char *extension, char *dialplan, char *context)
|
|||
{
|
||||
switch_status_t status;
|
||||
sanity_check(-1);
|
||||
begin_allow_threads();
|
||||
status = switch_ivr_session_transfer(session, extension, dialplan, context);
|
||||
end_allow_threads();
|
||||
return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
|
||||
}
|
||||
|
||||
|
@ -250,6 +259,83 @@ bool CoreSession::ready() {
|
|||
|
||||
}
|
||||
|
||||
int CoreSession::originate(CoreSession *aleg_session,
|
||||
char *dest,
|
||||
int timeout)
|
||||
{
|
||||
|
||||
switch_memory_pool_t *pool = NULL;
|
||||
switch_core_session_t *aleg_core_session = NULL;
|
||||
switch_call_cause_t cause;
|
||||
|
||||
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
|
||||
if (aleg_session != NULL) {
|
||||
aleg_core_session = aleg_session->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");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (switch_ivr_originate(aleg_core_session,
|
||||
&session,
|
||||
&cause,
|
||||
dest,
|
||||
timeout,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&caller_profile) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error Creating Outgoing Channel! [%s]\n", dest);
|
||||
goto failed;
|
||||
|
||||
}
|
||||
|
||||
end_allow_threads();
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
failed:
|
||||
end_allow_threads();
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
void CoreSession::setCallerData(char *var, char *val) {
|
||||
|
||||
if (strcmp(var, "dialplan") == 0) {
|
||||
caller_profile.dialplan = val;
|
||||
}
|
||||
if (strcmp(var, "context") == 0) {
|
||||
caller_profile.context = val;
|
||||
}
|
||||
if (strcmp(var, "caller_id_name") == 0) {
|
||||
caller_profile.caller_id_name = val;
|
||||
}
|
||||
if (strcmp(var, "caller_id_number") == 0) {
|
||||
caller_profile.caller_id_number = val;
|
||||
}
|
||||
if (strcmp(var, "network_addr") == 0) {
|
||||
caller_profile.network_addr = val;
|
||||
}
|
||||
if (strcmp(var, "ani") == 0) {
|
||||
caller_profile.ani = val;
|
||||
}
|
||||
if (strcmp(var, "aniii") == 0) {
|
||||
caller_profile.aniii = val;
|
||||
}
|
||||
if (strcmp(var, "rdnis") == 0) {
|
||||
caller_profile.rdnis = val;
|
||||
}
|
||||
if (strcmp(var, "username") == 0) {
|
||||
caller_profile.username = val;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CoreSession::begin_allow_threads() {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CoreSession::begin_allow_threads() called and does nothing\n");
|
||||
}
|
||||
|
@ -274,6 +360,147 @@ void CoreSession::store_file_handle(switch_file_handle_t *fh) {
|
|||
}
|
||||
|
||||
|
||||
/* ---- methods not bound to CoreSession instance ---- */
|
||||
|
||||
|
||||
void console_log(char *level_str, char *msg)
|
||||
{
|
||||
switch_log_level_t level = SWITCH_LOG_DEBUG;
|
||||
if (level_str) {
|
||||
level = switch_log_str2level(level_str);
|
||||
}
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, level, msg);
|
||||
fflush(stdout); // TEMP ONLY!! SHOULD NOT BE CHECKED IN!!
|
||||
}
|
||||
|
||||
void console_clean_log(char *msg)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN,SWITCH_LOG_DEBUG, msg);
|
||||
}
|
||||
|
||||
|
||||
char *api_execute(char *cmd, char *arg)
|
||||
{
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
switch_api_execute(cmd, arg, NULL, &stream);
|
||||
return (char *) stream.data;
|
||||
}
|
||||
|
||||
void api_reply_delete(char *reply)
|
||||
{
|
||||
if (!switch_strlen_zero(reply)) {
|
||||
free(reply);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void bridge(CoreSession &session_a, CoreSession &session_b)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "bridge called, session_a uuid: %s\n", session_a.get_uuid());
|
||||
switch_input_callback_function_t dtmf_func = NULL;
|
||||
switch_input_args_t args;
|
||||
|
||||
session_a.begin_allow_threads();
|
||||
args = session_a.get_cb_args(); // get the cb_args data structure for session a
|
||||
dtmf_func = args.input_callback; // get the call back function
|
||||
switch_ivr_multi_threaded_bridge(session_a.session, session_b.session, dtmf_func, args.buf, args.buf);
|
||||
session_a.end_allow_threads();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 (!fh) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
|
Loading…
Reference in New Issue