indent pass 2

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8689 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale committed 2008-05-27 04:54:52 +00:00
1 parent 9bbcabbbdd
commit f930eaeec7
101 files changed
+31644 -31458

No files matched your search

+41 -38
View File
@@ -3,19 +3,19 @@
#include "freeswitch_lua.h"
using namespace LUA;
Session::Session() : CoreSession()
Session::Session():CoreSession()
{
cb_function = cb_arg = hangup_func_str = hangup_func_arg = NULL;
hh = mark = 0;
}
Session::Session(char *uuid) : CoreSession(uuid)
Session::Session(char *uuid):CoreSession(uuid)
{
cb_function = cb_arg = hangup_func_str = hangup_func_arg = NULL;
hh = mark = 0;
}
Session::Session(switch_core_session_t *new_session) : CoreSession(new_session)
Session::Session(switch_core_session_t *new_session):CoreSession(new_session)
{
cb_function = cb_arg = hangup_func_str = hangup_func_arg = NULL;
hh = mark = 0;
@@ -30,25 +30,25 @@ Session::~Session()
}
free(hangup_func_str);
}
switch_safe_free(hangup_func_arg);
switch_safe_free(cb_function);
switch_safe_free(cb_arg);
}
bool Session::begin_allow_threads()
bool Session::begin_allow_threads()
{
do_hangup_hook();
return true;
}
bool Session::end_allow_threads()
bool Session::end_allow_threads()
{
do_hangup_hook();
return true;
}
void Session::setLUA(lua_State *state)
void Session::setLUA(lua_State * state)
{
L = state;
}
@@ -56,30 +56,31 @@ void Session::setLUA(lua_State *state)
lua_State *Session::getLUA()
{
if (!L) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh!\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh!\n");
}
return L;
}
bool Session::ready() {
bool Session::ready()
{
bool r;
sanity_check(false);
sanity_check(false);
r = switch_channel_ready(channel) != 0;
do_hangup_hook();
return r;
}
void Session::check_hangup_hook()
void Session::check_hangup_hook()
{
if (hangup_func_str && (hook_state == CS_HANGUP || hook_state == CS_ROUTING)) {
hh++;
}
}
void Session::do_hangup_hook()
void Session::do_hangup_hook()
{
if (hh && !mark) {
const char *err = NULL;
@@ -90,25 +91,25 @@ void Session::do_hangup_hook()
return;
}
lua_getfield(L, LUA_GLOBALSINDEX, (char *)hangup_func_str);
lua_getfield(L, LUA_GLOBALSINDEX, (char *) hangup_func_str);
lua_pushstring(L, hook_state == CS_HANGUP ? "hangup" : "transfer");
if (hangup_func_arg) {
lua_getfield(L, LUA_GLOBALSINDEX, (char *)hangup_func_arg);
lua_getfield(L, LUA_GLOBALSINDEX, (char *) hangup_func_arg);
arg_count++;
}
lua_call(L, arg_count, 1);
err = lua_tostring(L, -1);
if (!switch_strlen_zero(err)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err);
}
}
}
static switch_status_t lua_hanguphook(switch_core_session_t *session_hungup)
static switch_status_t lua_hanguphook(switch_core_session_t *session_hungup)
{
switch_channel_t *channel = switch_core_session_get_channel(session_hungup);
CoreSession *coresession = NULL;
@@ -125,13 +126,14 @@ static switch_status_t lua_hanguphook(switch_core_session_t *session_hungup)
}
void Session::setHangupHook(char *func, char *arg) {
void Session::setHangupHook(char *func, char *arg)
{
sanity_check_noreturn;
switch_safe_free(hangup_func_str);
switch_safe_free(hangup_func_arg);
if (func) {
hangup_func_str = strdup(func);
if (!switch_strlen_zero(arg)) {
@@ -143,7 +145,8 @@ void Session::setHangupHook(char *func, char *arg) {
}
}
void Session::setInputCallback(char *cbfunc, char *funcargs) {
void Session::setInputCallback(char *cbfunc, char *funcargs)
{
sanity_check_noreturn;
@@ -156,15 +159,15 @@ void Session::setInputCallback(char *cbfunc, char *funcargs) {
if (funcargs) {
cb_arg = strdup(funcargs);
}
args.buf = this;
switch_channel_set_private(channel, "CoreSession", this);
args.input_callback = dtmf_callback;
args.input_callback = dtmf_callback;
ap = &args;
}
switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t itype)
switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t itype)
{
const char *ret;
@@ -173,27 +176,27 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp
}
switch (itype) {
case SWITCH_INPUT_TYPE_DTMF:
case SWITCH_INPUT_TYPE_DTMF:
{
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
char str[2] = "";
int arg_count = 2;
lua_getfield(L, LUA_GLOBALSINDEX, (char *)cb_function);
lua_pushstring(L, "dtmf");
lua_newtable(L);
lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_function);
lua_pushstring(L, "dtmf");
lua_newtable(L);
lua_pushstring(L, "digit");
str[0] = dtmf->digit;
lua_pushstring(L, str);
lua_rawset(L, -3);
lua_pushstring(L, "duration");
lua_pushnumber(L, dtmf->duration);
lua_rawset(L, -3);
if (cb_arg) {
lua_getfield(L, LUA_GLOBALSINDEX, (char *)cb_arg);
lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_arg);
arg_count++;
}
@@ -201,30 +204,30 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp
ret = lua_tostring(L, -1);
lua_pop(L, 1);
return process_callback_result((char *)ret);
return process_callback_result((char *) ret);
}
break;
case SWITCH_INPUT_TYPE_EVENT:
case SWITCH_INPUT_TYPE_EVENT:
{
switch_event_t *event = (switch_event_t *) input;
int arg_count = 2;
lua_getfield(L, LUA_GLOBALSINDEX, (char *)cb_function);
lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_function);
lua_pushstring(L, "event");
mod_lua_conjure_event(L, event, "__Input_Event__", 1);
lua_getfield(L, LUA_GLOBALSINDEX, "__Input_Event__");
if (cb_arg) {
lua_getfield(L, LUA_GLOBALSINDEX, (char *)cb_arg);
lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_arg);
arg_count++;
}
lua_call(L, 2, 1);
ret = lua_tostring(L, -1);
ret = lua_tostring(L, -1);
lua_pop(L, 1);
return process_callback_result((char *)ret);
return process_callback_result((char *) ret);
}
break;
}
+43 -44
View File
@@ -45,23 +45,23 @@ static struct {
char *xml_handler;
} globals;
int luaopen_freeswitch(lua_State* L);
int luaopen_freeswitch(lua_State * L);
static int panic (lua_State *L)
static int panic(lua_State * L)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1));
return 0;
}
static void lua_uninit(lua_State *L)
static void lua_uninit(lua_State * L)
{
lua_gc(L, LUA_GCCOLLECT, 0);
lua_close(L);
}
static int traceback (lua_State *L) {
static int traceback(lua_State * L)
{
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
@@ -72,30 +72,32 @@ static int traceback (lua_State *L) {
lua_pop(L, 2);
return 1;
}
lua_pushvalue(L, 1); /* pass error message */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback */
lua_pushvalue(L, 1); /* pass error message */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback */
return 1;
}
static int docall (lua_State *L, int narg, int clear) {
static int docall(lua_State * L, int narg, int clear)
{
int status;
int base = lua_gettop(L) - narg; /* function index */
lua_pushcfunction(L, traceback); /* push traceback function */
lua_insert(L, base); /* put it under chunk and args */
int base = lua_gettop(L) - narg; /* function index */
lua_pushcfunction(L, traceback); /* push traceback function */
lua_insert(L, base); /* put it under chunk and args */
status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
lua_remove(L, base); /* remove traceback function */
lua_remove(L, base); /* remove traceback function */
/* force a complete garbage collection in case of errors */
if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
if (status != 0)
lua_gc(L, LUA_GCCOLLECT, 0);
return status;
}
static lua_State *lua_init(void)
static lua_State *lua_init(void)
{
lua_State *L = lua_open();
int error = 0;
@@ -108,12 +110,12 @@ static lua_State *lua_init(void)
lua_gc(L, LUA_GCRESTART, 0);
lua_atpanic(L, panic);
error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 1);
}
}
return L;
}
static int lua_parse_and_execute(lua_State *L, char *input_code)
static int lua_parse_and_execute(lua_State * L, char *input_code)
{
int error = 0;
@@ -124,7 +126,7 @@ static int lua_parse_and_execute(lua_State *L, char *input_code)
if (*input_code == '~') {
char *buff = input_code + 1;
error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 1); //lua_pcall(L, 0, 0, 0);
error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 1); //lua_pcall(L, 0, 0, 0);
} else {
char *args = strchr(input_code, ' ');
if (args) {
@@ -136,13 +138,13 @@ static int lua_parse_and_execute(lua_State *L, char *input_code)
if ((argc = switch_separate_string(args, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
switch_stream_handle_t stream = { 0 };
SWITCH_STANDARD_STREAM(stream);
stream.write_function(&stream, " argv = { ");
for (x = 0; x < argc; x++) {
stream.write_function(&stream, "'%s'%s", argv[x], x == argc-1 ? "" : ", ");
stream.write_function(&stream, "'%s'%s", argv[x], x == argc - 1 ? "" : ", ");
}
stream.write_function(&stream, " };");
code = (char *)stream.data;
code = (char *) stream.data;
} else {
code = switch_mprintf("argv = {};");
}
@@ -154,7 +156,7 @@ static int lua_parse_and_execute(lua_State *L, char *input_code)
}
if (!error) {
char *file = input_code, *fdup = NULL;
if (!switch_is_file_path(file)) {
fdup = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.script_dir, file);
switch_assert(fdup);
@@ -170,7 +172,7 @@ static int lua_parse_and_execute(lua_State *L, char *input_code)
if (!switch_strlen_zero(err)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err);
}
lua_pop(L, 1); /* pop error message from the stack */
lua_pop(L, 1); /* pop error message from the stack */
}
return error;
@@ -179,10 +181,10 @@ static int lua_parse_and_execute(lua_State *L, char *input_code)
static void *SWITCH_THREAD_FUNC lua_thread_run(switch_thread_t *thread, void *obj)
{
char *input_code = (char *) obj;
lua_State *L = lua_init(); /* opens Lua */
lua_State *L = lua_init(); /* opens Lua */
lua_parse_and_execute(L, input_code);
if (input_code) {
free(input_code);
}
@@ -193,12 +195,8 @@ static void *SWITCH_THREAD_FUNC lua_thread_run(switch_thread_t *thread, void *ob
}
static switch_xml_t lua_fetch(const char *section,
const char *tag_name,
const char *key_name,
const char *key_value,
switch_event_t *params,
void *user_data)
static switch_xml_t lua_fetch(const char *section,
const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data)
{
switch_xml_t xml = NULL;
@@ -238,11 +236,11 @@ static switch_xml_t lua_fetch(const char *section,
if (str) {
if (switch_strlen_zero(str)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Result\n");
} else if (!(xml = switch_xml_parse_str((char *)str, strlen(str)))) {
} else if (!(xml = switch_xml_parse_str((char *) str, strlen(str)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing XML Result!\n");
}
}
lua_uninit(L);
free(mycmd);
}
@@ -304,13 +302,13 @@ SWITCH_STANDARD_APP(lua_function)
if (switch_strlen_zero(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no args specified!\n");
return;
}
return;
}
snprintf(code, sizeof(code), "~session = freeswitch.Session(\"%s\");", switch_core_session_get_uuid(session));
error = lua_parse_and_execute(L, code);
mycmd = strdup((char *)data);
mycmd = strdup((char *) data);
switch_assert(mycmd);
lua_parse_and_execute(L, mycmd);
@@ -319,8 +317,9 @@ SWITCH_STANDARD_APP(lua_function)
}
SWITCH_STANDARD_API(luarun_api_function) {
SWITCH_STANDARD_API(luarun_api_function)
{
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
} else {
@@ -332,7 +331,8 @@ SWITCH_STANDARD_API(luarun_api_function) {
}
SWITCH_STANDARD_API(lua_api_function) {
SWITCH_STANDARD_API(lua_api_function)
{
lua_State *L = lua_init();
char *mycmd;
@@ -370,13 +370,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_lua_load)
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_API(api_interface, "luarun", "run a script", luarun_api_function, "<script>");
SWITCH_ADD_API(api_interface, "lua", "run a script as an api function", lua_api_function, "<script>");
SWITCH_ADD_APP(app_interface, "lua", "Launch LUA ivr", "Run a lua ivr on a channel", lua_function, "<script>", SAF_SUPPORT_NOMEDIA);
globals.pool = pool;
do_config();
@@ -385,7 +385,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_lua_load)
}
SWITCH_END_EXTERN_C
/* For Emacs:
* Local Variables:
* mode:c
+4 -7
View File
@@ -1,18 +1,15 @@
SWITCH_BEGIN_EXTERN_C
void mod_lua_conjure_event(lua_State *L, switch_event_t *event, const char *name, int destroy_me)
SWITCH_BEGIN_EXTERN_C void mod_lua_conjure_event(lua_State * L, switch_event_t *event, const char *name, int destroy_me)
{
Event *result = new Event(event);
SWIG_NewPointerObj(L,result,SWIGTYPE_p_Event, destroy_me);
SWIG_NewPointerObj(L, result, SWIGTYPE_p_Event, destroy_me);
lua_setglobal(L, name);
}
void mod_lua_conjure_stream(lua_State *L, switch_stream_handle_t *stream, const char *name, int destroy_me)
void mod_lua_conjure_stream(lua_State * L, switch_stream_handle_t *stream, const char *name, int destroy_me)
{
Stream *result = new Stream(stream);
SWIG_NewPointerObj(L,result,SWIGTYPE_p_Stream, destroy_me);
SWIG_NewPointerObj(L, result, SWIGTYPE_p_Stream, destroy_me);
lua_setglobal(L, name);
}
File diff suppressed because it is too large. Load diff
+69 -75
View File
@@ -27,8 +27,8 @@
*
* freeswitch_mono.cpp -- Mono-specific CoreSession subclass
*
*/
*/
#include <switch.h>
#include <switch_cpp.h>
#include <glib.h>
@@ -38,77 +38,71 @@
#include <mono/metadata/threads.h>
#include <mono/metadata/metadata.h>
#include "freeswitch_mono.h"
MonoSession::MonoSession():CoreSession()
{
} MonoSession::MonoSession(char *uuid):CoreSession(uuid)
{
} MonoSession::MonoSession(switch_core_session_t *session):CoreSession(session)
{
} MonoSession::~MonoSession()
{
mono_thread_attach(globals.domain);
if (dtmfDelegateHandle)
mono_gchandle_free(dtmfDelegateHandle);
if (hangupDelegateHandle)
mono_gchandle_free(hangupDelegateHandle);
}
bool MonoSession::begin_allow_threads()
{
return true;
}
bool MonoSession::end_allow_threads()
{
return true;
}
void MonoSession::check_hangup_hook()
{
mono_thread_attach(globals.domain);
if (!hangupDelegateHandle) {
return;
}
MonoObject * hangupDelegate = mono_gchandle_get_target(hangupDelegateHandle);
if (!hangupDelegate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object.");
return;
}
MonoObject * ex = NULL;
mono_runtime_delegate_invoke(hangupDelegate, NULL, &ex);
if (ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegate threw an exception.");
}
}
switch_status_t MonoSession::run_dtmf_callback(void *input, switch_input_type_t itype)
{
mono_thread_attach(globals.domain);
if (!dtmfDelegateHandle) {
return SWITCH_STATUS_SUCCESS;
}
MonoObject * dtmfDelegate = mono_gchandle_get_target(dtmfDelegateHandle);
if (!dtmfDelegate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object.");
return SWITCH_STATUS_SUCCESS;
}
void *args[2];
args[0] = &input;
args[1] = &itype;
MonoObject * ex = NULL;
MonoObject * res = mono_runtime_delegate_invoke(dtmfDelegate, args, &ex);
if (ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegate threw an exception.");
return SWITCH_STATUS_FALSE;
}
char *resPtr = mono_string_to_utf8((MonoString *) res);
switch_status_t status = process_callback_result(resPtr);
g_free(resPtr);
return status;
}
MonoSession::MonoSession() : CoreSession()
{
}
MonoSession::MonoSession(char *uuid) : CoreSession(uuid)
{
}
MonoSession::MonoSession(switch_core_session_t *session) : CoreSession(session)
{
}
MonoSession::~MonoSession()
{
mono_thread_attach(globals.domain);
if (dtmfDelegateHandle) mono_gchandle_free(dtmfDelegateHandle);
if (hangupDelegateHandle) mono_gchandle_free(hangupDelegateHandle);
}
bool MonoSession::begin_allow_threads()
{
return true;
}
bool MonoSession::end_allow_threads()
{
return true;
}
void MonoSession::check_hangup_hook()
{
mono_thread_attach(globals.domain);
if (!hangupDelegateHandle) {
return;
}
MonoObject *hangupDelegate = mono_gchandle_get_target(hangupDelegateHandle);
if (!hangupDelegate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object.");
return;
}
MonoObject *ex = NULL;
mono_runtime_delegate_invoke(hangupDelegate, NULL, &ex);
if (ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegate threw an exception.");
}
}
switch_status_t MonoSession::run_dtmf_callback(void *input, switch_input_type_t itype)
{
mono_thread_attach(globals.domain);
if (!dtmfDelegateHandle) {
return SWITCH_STATUS_SUCCESS;
}
MonoObject *dtmfDelegate = mono_gchandle_get_target(dtmfDelegateHandle);
if (!dtmfDelegate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object.");
return SWITCH_STATUS_SUCCESS;
}
void *args[2];
args[0] = &input;
args[1] = &itype;
MonoObject *ex = NULL;
MonoObject *res = mono_runtime_delegate_invoke(dtmfDelegate, args, &ex);
if (ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegate threw an exception.");
return SWITCH_STATUS_FALSE;
}
char *resPtr = mono_string_to_utf8((MonoString*)res);
switch_status_t status = process_callback_result(resPtr);
g_free(resPtr);
return status;
}
+264 -273
View File
@@ -30,13 +30,10 @@
* Most of mod_mono is implmented in the mod_mono_managed Loader class.
* The native code just handles getting the Mono runtime up and down
* and passing pointers into managed code.
*/
*/
#include <switch.h>
SWITCH_BEGIN_EXTERN_C
SWITCH_BEGIN_EXTERN_C
#include "freeswitch_mono.h"
#include <glib.h>
#include <mono/jit/jit.h>
@@ -44,284 +41,278 @@ SWITCH_BEGIN_EXTERN_C
#include <mono/metadata/environment.h>
#include <mono/metadata/threads.h>
#include <mono/metadata/debug-helpers.h>
#ifdef WIN32
#include <shlobj.h>
#define EXPORT __declspec(dllexport)
#elif
#define EXPORT
#endif
#endif /* */
#define MOD_MONO_MANAGED_DLL "mod_mono_managed.dll"
mod_mono_globals globals = { 0 };
SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown);
SWITCH_MODULE_DEFINITION(mod_mono, mod_mono_load, mod_mono_shutdown, NULL);
SWITCH_STANDARD_API(monorun_api_function); /* ExecuteBackground */
SWITCH_STANDARD_API(mono_api_function); /* Execute */
SWITCH_STANDARD_APP(mono_app_function); /* Run */
mod_mono_globals globals = {
0};
SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown);
SWITCH_MODULE_DEFINITION(mod_mono, mod_mono_load, mod_mono_shutdown, NULL);
SWITCH_STANDARD_API(monorun_api_function); /* ExecuteBackground */
SWITCH_STANDARD_API(mono_api_function); /* Execute */
SWITCH_STANDARD_APP(mono_app_function); /* Run */
// Sets up delegates (and anything else needed) on the MonoSession object
// Called via internalcall
SWITCH_MOD_DECLARE(void) InitMonoSession(MonoSession *session, MonoObject *dtmfDelegate, MonoObject *hangupDelegate)
{
switch_assert(session);
if (!session) return;
session->setDTMFCallback(NULL, "");
session->setHangupHook(NULL);
session->dtmfDelegateHandle = mono_gchandle_new(dtmfDelegate, FALSE);
session->hangupDelegateHandle = mono_gchandle_new(hangupDelegate, FALSE);
}
switch_status_t setMonoDirs()
{
SWITCH_MOD_DECLARE(void) InitMonoSession(MonoSession * session, MonoObject * dtmfDelegate, MonoObject * hangupDelegate)
{
switch_assert(session);
if (!session)
return;
session->setDTMFCallback(NULL, "");
session->setHangupHook(NULL);
session->dtmfDelegateHandle = mono_gchandle_new(dtmfDelegate, FALSE);
session->hangupDelegateHandle = mono_gchandle_new(hangupDelegate, FALSE);
}
switch_status_t setMonoDirs()
{
#ifdef WIN32
/* Win32 Mono installs can't figure out their own path
// Guys in #mono say we should just deploy all the libs we need
// I think it's much nicer to let the user deal with installing Mono
// and we'll just look for it in program files. */
HANDLE hFind;
WIN32_FIND_DATA findData;
char progFilesPath[MAX_PATH];
char findPath[MAX_PATH];
SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, progFilesPath);
switch_snprintf(findPath, MAX_PATH, "%s\\Mono-*", progFilesPath);
hFind = FindFirstFile(findPath, &findData);
if (hFind == INVALID_HANDLE_VALUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error looking for Mono in Program Files.\n");
return SWITCH_STATUS_FALSE;
}
while((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
if (FindNextFile(hFind, &findData) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find Mono directory in Program Files.\n");
FindClose(hFind);
return SWITCH_STATUS_FALSE;
}
}
/* Got it */
{
char libPath[MAX_PATH];
char etcPath[MAX_PATH];
switch_snprintf(libPath, MAX_PATH, "%s\\%s\\lib", progFilesPath, findData.cFileName);
switch_snprintf(etcPath, MAX_PATH, "%s\\%s\\etc", progFilesPath, findData.cFileName);
FindClose(hFind);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Using Mono paths '%s' and '%s'.\n", libPath, etcPath);
mono_set_dirs(libPath, etcPath);
return SWITCH_STATUS_SUCCESS;
}
/* Win32 Mono installs can't figure out their own path
// Guys in #mono say we should just deploy all the libs we need
// I think it's much nicer to let the user deal with installing Mono
// and we'll just look for it in program files. */
HANDLE hFind;
WIN32_FIND_DATA findData;
char progFilesPath[MAX_PATH];
char findPath[MAX_PATH];
SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, progFilesPath);
switch_snprintf(findPath, MAX_PATH, "%s\\Mono-*", progFilesPath);
hFind = FindFirstFile(findPath, &findData);
if (hFind == INVALID_HANDLE_VALUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error looking for Mono in Program Files.\n");
return SWITCH_STATUS_FALSE;
}
while ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
if (FindNextFile(hFind, &findData) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find Mono directory in Program Files.\n");
FindClose(hFind);
return SWITCH_STATUS_FALSE;
}
}
/* Got it */
{
char libPath[MAX_PATH];
char etcPath[MAX_PATH];
switch_snprintf(libPath, MAX_PATH, "%s\\%s\\lib", progFilesPath, findData.cFileName);
switch_snprintf(etcPath, MAX_PATH, "%s\\%s\\etc", progFilesPath, findData.cFileName);
FindClose(hFind);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Using Mono paths '%s' and '%s'.\n", libPath, etcPath);
mono_set_dirs(libPath, etcPath);
return SWITCH_STATUS_SUCCESS;
}
#elif
// On other platforms, it should just work if it hasn't been relocated
mono_set_dirs(NULL, NULL);
return SWITCH_STATUS_SUCCESS;
#endif
}
switch_status_t loadModMonoManaged()
{
/* Find and load mod_mono_managed.exe */
char filename[256];
switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_MONO_MANAGED_DLL);
globals.domain = mono_jit_init(filename);
if (!globals.domain) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_jit_init failed.\n");
return SWITCH_STATUS_FALSE;
}
/* Open the assembly */
globals.mod_mono_asm = mono_domain_assembly_open(globals.domain, filename);
if (!globals.mod_mono_asm) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
MonoMethod *getMethod(const char *name, MonoClass *klass)
{
MonoMethodDesc *desc;
MonoMethod *method;
desc = mono_method_desc_new(name, TRUE);
method = mono_method_desc_search_in_class(desc, klass);
if (!method) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find %s method.\n", name);
return NULL;
}
return method;
}
switch_status_t findLoader()
{
/* Find loader class and methods*/
MonoImage* img;
MonoClass* loaderClass;
img = mono_assembly_get_image(globals.mod_mono_asm);
loaderClass = mono_class_from_name(img, "FreeSWITCH", "Loader");
if (!loaderClass) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find FreeSWITCH.Loader class.\n");
return SWITCH_STATUS_FALSE;
}
globals.loadMethod = getMethod("FreeSWITCH.Loader:Load()", loaderClass);
if (!globals.loadMethod) return SWITCH_STATUS_FALSE;
globals.unloadMethod = getMethod("FreeSWITCH.Loader:Unload()", loaderClass);
if (!globals.unloadMethod) return SWITCH_STATUS_FALSE;
globals.runMethod = getMethod("FreeSWITCH.Loader:Run(string,intptr)", loaderClass);
if (!globals.runMethod) return SWITCH_STATUS_FALSE;
globals.executeMethod = getMethod("FreeSWITCH.Loader:Execute(string,intptr,intptr)", loaderClass);
if (!globals.executeMethod) return SWITCH_STATUS_FALSE;
// On other platforms, it should just work if it hasn't been relocated
mono_set_dirs(NULL, NULL);
return SWITCH_STATUS_SUCCESS;
globals.executeBackgroundMethod = getMethod("FreeSWITCH.Loader:ExecuteBackground(string)", loaderClass);
if (!globals.executeBackgroundMethod) return SWITCH_STATUS_FALSE;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found all loader functions.\n");
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load)
{
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
globals.pool = pool;
if (setMonoDirs() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
if (loadModMonoManaged() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
if (findLoader() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
/* Not sure if this is necesary on the loading thread */
mono_thread_attach(globals.domain);
mono_add_internal_call("FreeSWITCH.Native.MonoSession::InitMonoSession", InitMonoSession);
/* Run loader */
MonoObject *objResult;
MonoObject *exception = NULL;
objResult = mono_runtime_invoke(globals.loadMethod, NULL, NULL, &exception);
if (exception) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load threw an exception.\n");
mono_print_unhandled_exception(exception);
return SWITCH_STATUS_FALSE;
}
if (*(int*)mono_object_unbox(objResult)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true.\n");
return SWITCH_STATUS_FALSE;
}
/* We're good to register */
switch_api_interface_t *api_interface;
switch_application_interface_t *app_interface;
SWITCH_ADD_API(api_interface, "monorun", "Run a module (ExecuteBackground)", monorun_api_function, "<module> [<args>]");
SWITCH_ADD_API(api_interface, "mono", "Run a module as an API function (Execute)", mono_api_function, "<module> [<args>]");
SWITCH_ADD_APP(app_interface, "mono", "Run Mono IVR", "Run a Mono IVR on a channel", mono_app_function, "<modulename> [<args>]", SAF_NONE);
#endif /* */
}
switch_status_t loadModMonoManaged()
{
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(monorun_api_function)
{
// TODO: Should we be detaching after all this?
mono_thread_attach(globals.domain);
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
// ExecuteBackground(string command)
void *args[1];
args[0] = mono_string_new(globals.domain, cmd);
MonoObject *exception = NULL;
MonoObject *objResult = mono_runtime_invoke(globals.executeBackgroundMethod, NULL, args, &exception);
if (exception) {
stream->write_function(stream, "-ERR FreeSWITCH.Loader.ExecuteBackground threw an exception.\n");
mono_print_unhandled_exception(exception);
return SWITCH_STATUS_SUCCESS;
}
if (*(int*)mono_object_unbox(objResult)) {
stream->write_function(stream, "+OK\n");
} else {
stream->write_function(stream, "-ERR ExecuteBackground returned false (unknown module?).\n");
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(mono_api_function)
{
mono_thread_attach(globals.domain);
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
/* Find and load mod_mono_managed.exe */
char filename[256];
switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_MONO_MANAGED_DLL);
globals.domain = mono_jit_init(filename);
if (!globals.domain) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_jit_init failed.\n");
return SWITCH_STATUS_FALSE;
}
/* Open the assembly */
globals.mod_mono_asm = mono_domain_assembly_open(globals.domain, filename);
if (!globals.mod_mono_asm) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
MonoMethod * getMethod(const char *name, MonoClass * klass)
{
MonoMethodDesc * desc;
MonoMethod * method;
desc = mono_method_desc_new(name, TRUE);
method = mono_method_desc_search_in_class(desc, klass);
if (!method) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find %s method.\n", name);
return NULL;
}
return method;
}
switch_status_t findLoader()
{
// Method is: Execute(string command, IntPtr streamPtr, IntPtr eventPtr)
void *args[3];
args[0] = mono_string_new(globals.domain, cmd);
args[1] = &stream; // Address of the arguments
args[2] = &(stream->param_event);
/* Find loader class and methods */
MonoImage * img;
MonoClass * loaderClass;
img = mono_assembly_get_image(globals.mod_mono_asm);
loaderClass = mono_class_from_name(img, "FreeSWITCH", "Loader");
if (!loaderClass) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find FreeSWITCH.Loader class.\n");
return SWITCH_STATUS_FALSE;
}
globals.loadMethod = getMethod("FreeSWITCH.Loader:Load()", loaderClass);
if (!globals.loadMethod)
return SWITCH_STATUS_FALSE;
globals.unloadMethod = getMethod("FreeSWITCH.Loader:Unload()", loaderClass);
if (!globals.unloadMethod)
return SWITCH_STATUS_FALSE;
globals.runMethod = getMethod("FreeSWITCH.Loader:Run(string,intptr)", loaderClass);
if (!globals.runMethod)
return SWITCH_STATUS_FALSE;
globals.executeMethod = getMethod("FreeSWITCH.Loader:Execute(string,intptr,intptr)", loaderClass);
if (!globals.executeMethod)
return SWITCH_STATUS_FALSE;
globals.executeBackgroundMethod = getMethod("FreeSWITCH.Loader:ExecuteBackground(string)", loaderClass);
if (!globals.executeBackgroundMethod)
return SWITCH_STATUS_FALSE;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found all loader functions.\n");
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load)
{
MonoObject *exception = NULL;
MonoObject *objResult = mono_runtime_invoke(globals.executeMethod, NULL, args, &exception);
if (exception) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute mono %s.\n", cmd);
mono_print_unhandled_exception(exception);
}
if (!(*(int*)mono_object_unbox(objResult))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Execute failed for %s (unknown module?).\n", cmd);
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_APP(mono_app_function)
{
mono_thread_attach(globals.domain);
if (switch_strlen_zero(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No args specified!\n");
}
// bool Run(string command, IntPtr sessionHandle)
void *args[2];
args[0] = mono_string_new(globals.domain, data);
args[1] = &session;
MonoObject *exception = NULL;
MonoObject *objResult = mono_runtime_invoke(globals.runMethod, NULL, args, &exception);
if (exception) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute application mono %s.\n", data);
mono_print_unhandled_exception(exception);
}
if (!(*(int*)mono_object_unbox(objResult))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application run failed for %s (unknown module?).\n", data);
}
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown)
{
mono_thread_attach(globals.domain);
MonoObject *ex;
mono_runtime_invoke(globals.unloadMethod, NULL, NULL, &ex);
if (ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception occurred in Loader::Unload.\n");
mono_print_unhandled_exception(ex);
}
mono_runtime_set_shutting_down();
mono_runtime_cleanup(globals.domain);
mono_runtime_quit();
return SWITCH_STATUS_SUCCESS;
}
SWITCH_END_EXTERN_C
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
globals.pool = pool;
if (setMonoDirs() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
if (loadModMonoManaged() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
if (findLoader() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
/* Not sure if this is necesary on the loading thread */
mono_thread_attach(globals.domain);
mono_add_internal_call("FreeSWITCH.Native.MonoSession::InitMonoSession", InitMonoSession);
/* Run loader */
MonoObject * objResult;
MonoObject * exception = NULL;
objResult = mono_runtime_invoke(globals.loadMethod, NULL, NULL, &exception);
if (exception) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load threw an exception.\n");
mono_print_unhandled_exception(exception);
return SWITCH_STATUS_FALSE;
}
if (*(int *) mono_object_unbox(objResult)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true.\n");
return SWITCH_STATUS_FALSE;
}
/* We're good to register */
switch_api_interface_t *api_interface;
switch_application_interface_t *app_interface;
SWITCH_ADD_API(api_interface, "monorun", "Run a module (ExecuteBackground)", monorun_api_function, "<module> [<args>]");
SWITCH_ADD_API(api_interface, "mono", "Run a module as an API function (Execute)", mono_api_function, "<module> [<args>]");
SWITCH_ADD_APP(app_interface, "mono", "Run Mono IVR", "Run a Mono IVR on a channel", mono_app_function, "<modulename> [<args>]", SAF_NONE);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(monorun_api_function)
{
// TODO: Should we be detaching after all this?
mono_thread_attach(globals.domain);
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
// ExecuteBackground(string command)
void *args[1];
args[0] = mono_string_new(globals.domain, cmd);
MonoObject * exception = NULL;
MonoObject * objResult = mono_runtime_invoke(globals.executeBackgroundMethod, NULL, args, &exception);
if (exception) {
stream->write_function(stream, "-ERR FreeSWITCH.Loader.ExecuteBackground threw an exception.\n");
mono_print_unhandled_exception(exception);
return SWITCH_STATUS_SUCCESS;
}
if (*(int *) mono_object_unbox(objResult)) {
stream->write_function(stream, "+OK\n");
} else {
stream->write_function(stream, "-ERR ExecuteBackground returned false (unknown module?).\n");
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(mono_api_function)
{
mono_thread_attach(globals.domain);
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
// Method is: Execute(string command, IntPtr streamPtr, IntPtr eventPtr)
void *args[3];
args[0] = mono_string_new(globals.domain, cmd);
args[1] = &stream; // Address of the arguments
args[2] = &(stream->param_event);
MonoObject * exception = NULL;
MonoObject * objResult = mono_runtime_invoke(globals.executeMethod, NULL, args, &exception);
if (exception) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute mono %s.\n", cmd);
mono_print_unhandled_exception(exception);
}
if (!(*(int *) mono_object_unbox(objResult))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Execute failed for %s (unknown module?).\n", cmd);
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_APP(mono_app_function)
{
mono_thread_attach(globals.domain);
if (switch_strlen_zero(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No args specified!\n");
}
// bool Run(string command, IntPtr sessionHandle)
void *args[2];
args[0] = mono_string_new(globals.domain, data);
args[1] = &session;
MonoObject * exception = NULL;
MonoObject * objResult = mono_runtime_invoke(globals.runMethod, NULL, args, &exception);
if (exception) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute application mono %s.\n", data);
mono_print_unhandled_exception(exception);
}
if (!(*(int *) mono_object_unbox(objResult))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application run failed for %s (unknown module?).\n", data);
}
} SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown)
{
mono_thread_attach(globals.domain);
MonoObject * ex;
mono_runtime_invoke(globals.unloadMethod, NULL, NULL, &ex);
if (ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception occurred in Loader::Unload.\n");
mono_print_unhandled_exception(ex);
}
mono_runtime_set_shutting_down();
mono_runtime_cleanup(globals.domain);
mono_runtime_quit();
return SWITCH_STATUS_SUCCESS;
}
SWITCH_END_EXTERN_C
+27 -24
View File
@@ -8,17 +8,17 @@ static STRLEN n_a;
using namespace PERL;
Session::Session() : CoreSession()
Session::Session():CoreSession()
{
init_me();
}
Session::Session(char *uuid) : CoreSession(uuid)
Session::Session(char *uuid):CoreSession(uuid)
{
init_me();
}
Session::Session(switch_core_session_t *new_session) : CoreSession(new_session)
Session::Session(switch_core_session_t *new_session):CoreSession(new_session)
{
init_me();
}
@@ -37,19 +37,19 @@ Session::~Session()
}
bool Session::begin_allow_threads()
bool Session::begin_allow_threads()
{
do_hangup_hook();
return true;
}
bool Session::end_allow_threads()
bool Session::end_allow_threads()
{
do_hangup_hook();
return true;
}
void Session::setPERL(PerlInterpreter *pi)
void Session::setPERL(PerlInterpreter * pi)
{
my_perl = pi;
}
@@ -57,30 +57,31 @@ void Session::setPERL(PerlInterpreter *pi)
PerlInterpreter *Session::getPERL()
{
if (!my_perl) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh!\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh!\n");
}
return my_perl;
}
bool Session::ready() {
bool Session::ready()
{
bool r;
sanity_check(false);
sanity_check(false);
r = switch_channel_ready(channel) != 0;
do_hangup_hook();
return r;
}
void Session::check_hangup_hook()
void Session::check_hangup_hook()
{
if (hangup_func_str && (hook_state == CS_HANGUP || hook_state == CS_ROUTING)) {
hh++;
}
}
void Session::do_hangup_hook()
void Session::do_hangup_hook()
{
if (hh && !mark) {
const char *err = NULL;
@@ -101,7 +102,7 @@ void Session::do_hangup_hook()
}
}
static switch_status_t perl_hanguphook(switch_core_session_t *session_hungup)
static switch_status_t perl_hanguphook(switch_core_session_t *session_hungup)
{
switch_channel_t *channel = switch_core_session_get_channel(session_hungup);
CoreSession *coresession = NULL;
@@ -118,7 +119,8 @@ static switch_status_t perl_hanguphook(switch_core_session_t *session_hungup)
}
void Session::setHangupHook(char *func, char *arg) {
void Session::setHangupHook(char *func, char *arg)
{
sanity_check_noreturn;
@@ -135,7 +137,8 @@ void Session::setHangupHook(char *func, char *arg) {
}
}
void Session::setInputCallback(char *cbfunc, char *funcargs) {
void Session::setInputCallback(char *cbfunc, char *funcargs)
{
sanity_check_noreturn;
@@ -148,22 +151,22 @@ void Session::setInputCallback(char *cbfunc, char *funcargs) {
if (funcargs) {
cb_arg = strdup(funcargs);
}
args.buf = this;
switch_channel_set_private(channel, "CoreSession", this);
args.input_callback = dtmf_callback;
args.input_callback = dtmf_callback;
ap = &args;
}
switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t itype)
switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t itype)
{
if (!getPERL()) {
return SWITCH_STATUS_FALSE;;
}
switch (itype) {
case SWITCH_INPUT_TYPE_DTMF:
case SWITCH_INPUT_TYPE_DTMF:
{
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
char str[32] = "";
@@ -177,14 +180,14 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp
}
str[0] = dtmf->digit;
this_sv = newSV(strlen(str)+1);
this_sv = newSV(strlen(str) + 1);
sv_setpv(this_sv, str);
hv_store(hash, "digit", 5, this_sv, 0);
switch_snprintf(str, sizeof(str), "%d", dtmf->duration);
this_sv = newSV(strlen(str)+1);
this_sv = newSV(strlen(str) + 1);
sv_setpv(this_sv, str);
hv_store(hash, "duration", 8, this_sv, 0);
hv_store(hash, "duration", 8, this_sv, 0);
code = switch_mprintf("$__RV = %s('dtmf', \\%%__dtmf, %s);", cb_function, switch_str_nil(cb_arg));
Perl_eval_pv(my_perl, code, FALSE);
@@ -193,18 +196,18 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp
return process_callback_result(SvPV(get_sv("__RV", TRUE), n_a));
}
break;
case SWITCH_INPUT_TYPE_EVENT:
case SWITCH_INPUT_TYPE_EVENT:
{
switch_event_t *event = (switch_event_t *) input;
int arg_count = 2;
char *code;
mod_perl_conjure_event(my_perl, event, "__Input_Event__");
code = switch_mprintf("$__RV = %s('event', $__Input_Event__, %s);", cb_function, switch_str_nil(cb_arg));
Perl_eval_pv(my_perl, code, TRUE);
free(code);
return process_callback_result(SvPV(get_sv("__RV", TRUE), n_a));
}
break;
+41 -58
View File
@@ -58,7 +58,7 @@ static struct {
static int Perl_safe_eval(PerlInterpreter *my_perl, const char *string)
static int Perl_safe_eval(PerlInterpreter * my_perl, const char *string)
{
char *err = NULL;
@@ -73,7 +73,7 @@ static int Perl_safe_eval(PerlInterpreter *my_perl, const char *string)
static int perl_parse_and_execute(PerlInterpreter *my_perl, char *input_code, char *setup_code)
static int perl_parse_and_execute(PerlInterpreter * my_perl, char *input_code, char *setup_code)
{
int error = 0;
@@ -103,10 +103,10 @@ static int perl_parse_and_execute(PerlInterpreter *my_perl, char *input_code, ch
if ((argc = switch_separate_string(args, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
switch_stream_handle_t stream = { 0 };
SWITCH_STANDARD_STREAM(stream);
stream.write_function(&stream, " @ARGV = ( ");
for (x = 0; x < argc; x++) {
stream.write_function(&stream, "'%s'%s", argv[x], x == argc-1 ? "" : ", ");
stream.write_function(&stream, "'%s'%s", argv[x], x == argc - 1 ? "" : ", ");
}
stream.write_function(&stream, " );");
code = stream.data;
@@ -130,7 +130,7 @@ static int perl_parse_and_execute(PerlInterpreter *my_perl, char *input_code, ch
file = switch_mprintf("require '%s';", file);
switch_assert(file);
}
error = Perl_safe_eval(my_perl, file);
switch_safe_free(file);
}
@@ -154,14 +154,15 @@ static PerlInterpreter *clone_perl(void)
}
#if 0
static perl_parse_and_execute (PerlInterpreter *my_perl, char *input_code, char *setup_code)
static perl_parse_and_execute(PerlInterpreter * my_perl, char *input_code, char *setup_code)
{
int error = 0;
if (*input_code == '~') {
char *buff = input_code + 1;
perl_parse(my_perl, xs_init, 3, embedding, NULL);
if (setup_code) Perl_safe_eval(my_perl, setup_code);
if (setup_code)
Perl_safe_eval(my_perl, setup_code);
Perl_safe_eval(my_perl, buff);
} else {
int argc = 0;
@@ -169,43 +170,38 @@ static perl_parse_and_execute (PerlInterpreter *my_perl, char *input_code, char
char *err;
argv[0] = "FreeSWITCH";
argc++;
argc += switch_separate_string(input_code, ' ', &argv[1], (sizeof(argv) / sizeof(argv[0])) - 1);
if (!perl_parse(my_perl, xs_init, argc, argv, (char **)NULL)) {
if (!perl_parse(my_perl, xs_init, argc, argv, (char **) NULL)) {
if (setup_code) {
if (!Perl_safe_eval(my_perl, setup_code)) {
perl_run(my_perl);
}
}
}
if ((err = SvPV(get_sv("@", TRUE), n_a)) && !switch_strlen_zero(err)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err);
}
}
}
#endif
#endif
static void perl_function(switch_core_session_t *session, char *data)
{
char *uuid = switch_core_session_get_uuid(session);
PerlInterpreter *my_perl = clone_perl();
char code[1024];
perl_parse(my_perl, xs_init, 3, embedding, NULL);
Perl_safe_eval(my_perl, code);
switch_snprintf(code, sizeof(code),
"use lib '%s/perl';\n"
"use freeswitch;\n"
"$SWITCH_ENV{UUID} = \"%s\";\n"
"$session = new freeswitch::Session(\"%s\")"
,
SWITCH_GLOBAL_dirs.base_dir,
uuid,
uuid);
switch_snprintf(code, sizeof(code),
"use lib '%s/perl';\n"
"use freeswitch;\n"
"$SWITCH_ENV{UUID} = \"%s\";\n" "$session = new freeswitch::Session(\"%s\")", SWITCH_GLOBAL_dirs.base_dir, uuid, uuid);
perl_parse_and_execute(my_perl, data, code);
Perl_safe_eval(my_perl, "undef $session;");
@@ -244,16 +240,10 @@ static void *SWITCH_THREAD_FUNC perl_thread_run(switch_thread_t *thread, void *o
if (session) {
uuid = switch_core_session_get_uuid(session);
}
switch_snprintf(code, sizeof(code),
"use lib '%s/perl';\n"
"use freeswitch;\n"
"$SWITCH_ENV{UUID} = \"%s\";\n"
,
SWITCH_GLOBAL_dirs.base_dir,
switch_str_nil(uuid)
);
switch_snprintf(code, sizeof(code),
"use lib '%s/perl';\n" "use freeswitch;\n" "$SWITCH_ENV{UUID} = \"%s\";\n", SWITCH_GLOBAL_dirs.base_dir, switch_str_nil(uuid)
);
perl_parse(my_perl, xs_init, 3, embedding, NULL);
Perl_safe_eval(my_perl, code);
@@ -273,7 +263,7 @@ static void *SWITCH_THREAD_FUNC perl_thread_run(switch_thread_t *thread, void *o
//Perl_safe_eval(my_perl, cmd);
perl_parse_and_execute(my_perl, cmd, NULL);
}
if (uuid) {
switch_snprintf(code, sizeof(code), "undef $session;", uuid);
Perl_safe_eval(my_perl, code);
@@ -301,7 +291,7 @@ int perl_thread(const char *text)
memset(po, 0, sizeof(*po));
po->cmd = strdup(text);
po->d = 1;
switch_threadattr_create(&thd_attr, globals.pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
@@ -310,7 +300,8 @@ int perl_thread(const char *text)
return 0;
}
SWITCH_STANDARD_API(perlrun_api_function) {
SWITCH_STANDARD_API(perlrun_api_function)
{
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR Missing args.\n");
@@ -322,7 +313,8 @@ SWITCH_STANDARD_API(perlrun_api_function) {
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(perl_api_function) {
SWITCH_STANDARD_API(perl_api_function)
{
struct perl_o po = { 0 };
@@ -337,12 +329,8 @@ SWITCH_STANDARD_API(perl_api_function) {
perl_thread_run(NULL, &po);
}
static switch_xml_t perl_fetch(const char *section,
const char *tag_name,
const char *key_name,
const char *key_value,
switch_event_t *params,
void *user_data)
static switch_xml_t perl_fetch(const char *section,
const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data)
{
char *argv[128] = { 0 };
@@ -359,10 +347,10 @@ static switch_xml_t perl_fetch(const char *section,
argv[argc++] = "FreeSWITCH";
argv[argc++] = globals.xml_handler;
PERL_SET_CONTEXT(my_perl);
if (perl_parse(my_perl, xs_init, argc, argv, (char **)NULL)) {
if (perl_parse(my_perl, xs_init, argc, argv, (char **) NULL)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result!\n");
return NULL;
}
@@ -375,15 +363,15 @@ static switch_xml_t perl_fetch(const char *section,
section = "";
}
this = newSV(strlen(section)+1);
this = newSV(strlen(section) + 1);
sv_setpv(this, section);
hv_store(hash, "section", 7, this, 0);
if (switch_strlen_zero(tag_name)) {
tag_name = "";
}
this = newSV(strlen(tag_name)+1);
this = newSV(strlen(tag_name) + 1);
sv_setpv(this, tag_name);
hv_store(hash, "tag_name", 8, this, 0);
@@ -391,7 +379,7 @@ static switch_xml_t perl_fetch(const char *section,
key_name = "";
}
this = newSV(strlen(key_name)+1);
this = newSV(strlen(key_name) + 1);
sv_setpv(this, key_name);
hv_store(hash, "key_name", 8, this, 0);
@@ -399,28 +387,23 @@ static switch_xml_t perl_fetch(const char *section,
key_value = "";
}
this = newSV(strlen(key_value)+1);
this = newSV(strlen(key_value) + 1);
sv_setpv(this, key_value);
hv_store(hash, "key_value", 9, this, 0);
if (!(hash = get_hv("XML_DATA", TRUE))) {
abort();
}
if (params) {
for (hp = params->headers; hp; hp = hp->next) {
this = newSV(strlen(hp->value)+1);
this = newSV(strlen(hp->value) + 1);
sv_setpv(this, hp->value);
hv_store(hash, hp->name, strlen(hp->name), this, 0);
}
}
switch_snprintf(code, sizeof(code),
"use lib '%s/perl';\n"
"use freeswitch;\n"
,
SWITCH_GLOBAL_dirs.base_dir
);
switch_snprintf(code, sizeof(code), "use lib '%s/perl';\n" "use freeswitch;\n", SWITCH_GLOBAL_dirs.base_dir);
Perl_safe_eval(my_perl, code);
if (params) {
@@ -437,7 +420,7 @@ static switch_xml_t perl_fetch(const char *section,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing XML Result!\n");
}
}
destroy_perl(&my_perl);
}
+8 -11
View File
@@ -1,24 +1,21 @@
SWITCH_BEGIN_EXTERN_C
void mod_perl_conjure_event(PerlInterpreter *my_perl, switch_event_t *event, const char *name)
SWITCH_BEGIN_EXTERN_C void mod_perl_conjure_event(PerlInterpreter * my_perl, switch_event_t *event, const char *name)
{
Event *result = 0 ;
Event *result = 0;
SV *sv;
PERL_SET_CONTEXT(my_perl);
sv = sv_2mortal(get_sv(name, TRUE));
result = (Event *)new Event(event);
sv = sv_2mortal(get_sv(name, TRUE));
result = (Event *) new Event(event);
SWIG_Perl_MakePtr(sv, result, SWIGTYPE_p_Event, SWIG_OWNER | SWIG_SHADOW);
}
void mod_perl_conjure_stream(PerlInterpreter *my_perl, switch_stream_handle_t *stream, const char *name)
void mod_perl_conjure_stream(PerlInterpreter * my_perl, switch_stream_handle_t *stream, const char *name)
{
Stream *result = 0 ;
Stream *result = 0;
SV *sv;
PERL_SET_CONTEXT(my_perl);
sv = sv_2mortal(get_sv(name, TRUE));
result = (Stream *)new Stream(stream);
sv = sv_2mortal(get_sv(name, TRUE));
result = (Stream *) new Stream(stream);
SWIG_Perl_MakePtr(sv, result, SWIGTYPE_p_Stream, SWIG_OWNER | SWIG_SHADOW);
}
File diff suppressed because it is too large. Load diff
+4 -5
View File
@@ -1,13 +1,12 @@
#include <EXTERN.h>
#include <perl.h>
EXTERN_C void xs_init (pTHX);
EXTERN_C void xs_init(pTHX);
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
EXTERN_C void boot_freeswitch (pTHX_ CV* cv);
EXTERN_C void boot_DynaLoader(pTHX_ CV * cv);
EXTERN_C void boot_freeswitch(pTHX_ CV * cv);
EXTERN_C void
xs_init(pTHX)
EXTERN_C void xs_init(pTHX)
{
char *file = __FILE__;
dXSUB_SYS;
+282 -301
View File
@@ -3,336 +3,317 @@
#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"; swapstate = S_SWAPPED_IN; } while(0)
PySession::PySession() : CoreSession()
PySession::PySession():CoreSession()
{
init_vars();
}
PySession::PySession(char *uuid) : CoreSession(uuid)
PySession::PySession(char *uuid):CoreSession(uuid)
{
init_vars();
}
PySession::PySession(switch_core_session_t *new_session) : CoreSession(new_session)
PySession::PySession(switch_core_session_t *new_session):CoreSession(new_session)
{
init_vars();
}
void PySession::setDTMFCallback(PyObject *pyfunc, char *funcargs)
void PySession::setDTMFCallback(PyObject * pyfunc, char *funcargs)
{
sanity_check();
sanity_check();
if (!PyCallable_Check(pyfunc)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF function is not a python function.\n");
return;
}
Py_XINCREF(pyfunc);
CoreSession::setDTMFCallback((void *) pyfunc, funcargs);
}
void PySession::setHangupHook(PyObject * pyfunc)
{
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);
}
void PySession::check_hangup_hook()
{
PyObject *func;
PyObject *result;
char *resultStr;
bool did_swap_in = false;
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");
return;
}
if (!PyCallable_Check(pyfunc)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF function is not a python function.\n");
return;
}
Py_XINCREF(pyfunc);
CoreSession::setDTMFCallback((void *) pyfunc, funcargs);
/*! NEEDS TO BE FIXED:
// 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();
if (on_hangup == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "on_hangup is null\n");
return;
}
func = (PyObject *) on_hangup;
// 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);
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)
{
PyObject *func, *arglist;
PyObject *pyresult;
PyObject *headerdict;
char *resultStr;
char *funcargs;
switch_file_handle_t *fh = NULL;
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;
}
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)) {
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);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown input type: %d\n", itype);
return SWITCH_STATUS_FALSE;
}
if (!arglist) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error building arglist");
return SWITCH_STATUS_FALSE;
}
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;
} 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) {
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::setHangupHook(PyObject *pyfunc) {
void PySession::hangup(char *cause)
{
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);
// 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);
}
void PySession::check_hangup_hook() {
PyObject *func;
PyObject *result;
char *resultStr;
bool did_swap_in = false;
PySession::~PySession()
{
// Should we do any cleanup here?
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::~PySession started\n");
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");
return;
}
return;
/*! NEEDS TO BE FIXED:
// 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();
if (on_hangup == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "on_hangup is null\n");
return;
}
func = (PyObject *) on_hangup;
// 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);
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) {
PyObject *func, *arglist;
PyObject *pyresult;
PyObject *headerdict;
char *resultStr;
char *funcargs;
switch_file_handle_t *fh = NULL;
bool did_swap_in = false;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "run_dtmf_callback\n");
if (on_hangup) {
PyObject *func = (PyObject *) on_hangup;
Py_XDECREF(func);
}
if (!cb_state.function) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "cb_state->function is null\n");
return SWITCH_STATUS_FALSE;
}
if (cb_state.function != NULL) {
PyObject *func = (PyObject *) cb_state.function;
Py_XDECREF(func);
}
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)) {
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);
}
else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown input type: %d\n", itype);
return SWITCH_STATUS_FALSE;
}
if (!arglist) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error building arglist");
return SWITCH_STATUS_FALSE;
}
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;
}
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) {
begin_allow_threads();
}
Py_XDECREF(pyresult);
return SWITCH_STATUS_SUCCESS;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "PySession::~PySession finished\n");
}
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");
}
+76 -82
View File
@@ -58,7 +58,7 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess
{
PyThreadState *tstate = NULL;
char *dupargs = NULL;
char *argv[128] = {0};
char *argv[128] = { 0 };
int argc;
int lead = 0;
char *script = NULL;
@@ -68,16 +68,16 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess
PyObject *result = NULL;
if (args) {
dupargs = strdup(args);
dupargs = strdup(args);
} else {
return;
return;
}
assert(dupargs != NULL);
if (!(argc = switch_separate_string(dupargs, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No module name specified!\n");
goto done;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No module name specified!\n");
goto done;
}
script = argv[0];
@@ -87,80 +87,76 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess
tstate = PyThreadState_New(mainThreadState->interp);
if (!tstate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error acquiring tstate\n");
goto done;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error acquiring tstate\n");
goto done;
}
// swap in thread state
PyEval_AcquireThread(tstate);
if (session) {
// record the fact that thread state is swapped in
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_set_private(channel, "SwapInThreadState", NULL);
// record the fact that thread state is swapped in
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_set_private(channel, "SwapInThreadState", NULL);
}
init_freeswitch();
init_freeswitch();
// import the module
module = PyImport_ImportModule( (char *) script);
module = PyImport_ImportModule((char *) script);
if (!module) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error importing module\n");
PyErr_Print();
PyErr_Clear();
goto done_swap_out;
}
// reload the module
module = PyImport_ReloadModule(module);
if (!module) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error reloading module\n");
PyErr_Print();
PyErr_Clear();
goto done_swap_out;
}
// get the handler function to be called
function = PyObject_GetAttrString(module, "handler");
if (!function) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Module does not define handler(uuid)\n");
PyErr_Print();
PyErr_Clear();
goto done_swap_out;
}
if (uuid) {
// build a tuple to pass the args, the uuid of session
arg = Py_BuildValue("(s)", uuid);
if (!arg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error building args\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error importing module\n");
PyErr_Print();
PyErr_Clear();
goto done_swap_out;
}
}
else {
arg = PyTuple_New(1);
PyObject *nada = Py_BuildValue("");
PyTuple_SetItem(arg, 0, nada);
// reload the module
module = PyImport_ReloadModule(module);
if (!module) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error reloading module\n");
PyErr_Print();
PyErr_Clear();
goto done_swap_out;
}
// get the handler function to be called
function = PyObject_GetAttrString(module, "handler");
if (!function) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Module does not define handler(uuid)\n");
PyErr_Print();
PyErr_Clear();
goto done_swap_out;
}
if (uuid) {
// build a tuple to pass the args, the uuid of session
arg = Py_BuildValue("(s)", uuid);
if (!arg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error building args\n");
PyErr_Print();
PyErr_Clear();
goto done_swap_out;
}
} else {
arg = PyTuple_New(1);
PyObject *nada = Py_BuildValue("");
PyTuple_SetItem(arg, 0, nada);
}
// invoke the handler
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call python script \n");
result = PyEval_CallObjectWithKeywords(function, arg, (PyObject *)NULL);
result = PyEval_CallObjectWithKeywords(function, arg, (PyObject *) NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Finished calling python script \n");
// check the result and print out any errors
if (!result) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error calling python script\n");
PyErr_Print();
PyErr_Clear();
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error calling python script\n");
PyErr_Print();
PyErr_Clear();
}
goto done_swap_out;
done:
done:
switch_safe_free(dupargs);
done_swap_out:
done_swap_out:
// decrement ref counts
Py_XDECREF(module);
Py_XDECREF(function);
@@ -183,14 +179,12 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess
PyThreadState *cur_tstate = PyThreadState_Get();
PyThreadState_Clear(cur_tstate);
PyEval_ReleaseThread(cur_tstate);
PyThreadState_Delete(cur_tstate);
}
else {
PyThreadState_Delete(cur_tstate);
} else {
// thread state is already swapped out, so, nothing for us to do
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "according to chan priv data, already swapped out \n");
}
}
else {
} else {
// they ran python script from cmd line, behave a bit differently (untested)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No session: Threadstate mod_python.c swap-out! \n");
PyEval_ReleaseThread(tstate);
@@ -203,8 +197,8 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess
SWITCH_STANDARD_APP(python_function)
{
eval_some_python(switch_core_session_get_uuid(session), (char *)data, session);
eval_some_python(switch_core_session_get_uuid(session), (char *) data, session);
}
struct switch_py_thread {
@@ -228,7 +222,7 @@ static void *SWITCH_THREAD_FUNC py_thread_run(switch_thread_t *thread, void *obj
SWITCH_STANDARD_API(launch_python)
{
switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL;
switch_threadattr_t *thd_attr = NULL;
switch_memory_pool_t *pool;
struct switch_py_thread *pt;
@@ -236,7 +230,7 @@ SWITCH_STANDARD_API(launch_python)
stream->write_function(stream, "USAGE: %s\n", python_run_interface.syntax);
return SWITCH_STATUS_SUCCESS;
}
switch_core_new_memory_pool(&pool);
assert(pool != NULL);
@@ -245,11 +239,11 @@ SWITCH_STANDARD_API(launch_python)
pt->pool = pool;
pt->args = switch_core_strdup(pt->pool, cmd);
switch_threadattr_create(&thd_attr, pt->pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&thread, thd_attr, py_thread_run, pt, pt->pool);
switch_threadattr_create(&thd_attr, pt->pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&thread, thd_attr, py_thread_run, pt, pt->pool);
stream->write_function(stream, "OK\n");
return SWITCH_STATUS_SUCCESS;
@@ -290,7 +284,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_python_load)
/* connect my internal structure to the blank pointer passed to me */
*module_interface = &python_module_interface;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Python Framework Loading...\n");
if (!Py_IsInitialized()) {
// initialize python system
@@ -302,13 +296,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_python_load)
// save threadstate since it's interp field will be needed
// to create new threadstates, and will be needed for shutdown
mainThreadState = PyThreadState_Get();
// swap out threadstate since the call threads will create
// their own and swap in their threadstate
PyThreadState_Swap(NULL);
PyThreadState_Swap(NULL);
// release GIL
PyEval_ReleaseLock();
PyEval_ReleaseLock();
}
/* indicate that the module should continue to be loaded */
@@ -319,18 +313,18 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_python_load)
Called when the system shuts down*/
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_python_shutdown)
{
PyInterpreterState *mainInterpreterState;
PyThreadState *myThreadState;
PyInterpreterState *mainInterpreterState;
PyThreadState *myThreadState;
PyEval_AcquireLock();
mainInterpreterState = mainThreadState->interp;
myThreadState = PyThreadState_New(mainInterpreterState);
PyThreadState_Swap(myThreadState);
PyEval_ReleaseLock();
PyEval_AcquireLock();
mainInterpreterState = mainThreadState->interp;
myThreadState = PyThreadState_New(mainInterpreterState);
PyThreadState_Swap(myThreadState);
PyEval_ReleaseLock();
Py_Finalize();
PyEval_ReleaseLock();
return SWITCH_STATUS_SUCCESS;
Py_Finalize();
PyEval_ReleaseLock();
return SWITCH_STATUS_SUCCESS;
}
File diff suppressed because it is too large. Load diff
@@ -571,7 +571,7 @@ extern "C" {
* type checking.
*
* Author : David Beazley (beazley@cs.uchicago.edu)
************************************************************************//* Common SWIG API */
************************************************************************//* Common SWIG API */
#define SWIG_ConvertPtr(obj, pp, type, flags) SWIG_Python_ConvertPtr(obj, pp, type, flags)
#define SWIG_NewPointerObj(p, type, flags) SWIG_Python_NewPointerObj(p, type, flags)
#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags)
@@ -583,11 +583,11 @@ extern "C" {
#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer)
/* -----------------------------------------------------------------------------
* Pointer declarations
* ----------------------------------------------------------------------------- *//*
Use SWIG_NO_COBJECT_TYPES to force the use of strings to represent
C/C++ pointers in the python side. Very useful for debugging, but
not always safe.
*/
* ----------------------------------------------------------------------------- *//*
Use SWIG_NO_COBJECT_TYPES to force the use of strings to represent
C/C++ pointers in the python side. Very useful for debugging, but
not always safe.
*/
#if !defined(SWIG_NO_COBJECT_TYPES) && !defined(SWIG_COBJECT_TYPES)
# define SWIG_COBJECT_TYPES
#endif
@@ -1538,8 +1538,7 @@ extern "C" {
resultobj = Py_None;
return resultobj;
fail:return NULL;
}
static PyObject *_wrap_fs_core_init(PyObject * self, PyObject * args) {
} static PyObject *_wrap_fs_core_init(PyObject * self, PyObject * args) {
PyObject *resultobj = NULL;
char *arg1 = (char *) 0;
int result;
@@ -2683,8 +2682,7 @@ extern "C" {
SWIGINTERN PyObject *swig_varlink_repr(swig_varlinkobject * v) {
v = v;
return PyString_FromString("<Swig global variables>");
}
SWIGINTERN int swig_varlink_print(swig_varlinkobject * v, FILE * fp, int flags) {
} SWIGINTERN int swig_varlink_print(swig_varlinkobject * v, FILE * fp, int flags) {
swig_globalvar *var;
flags = flags;
fprintf(fp, "Swig global variables { ");
@@ -184,7 +184,7 @@ static JSBool request_write(JSContext * cx, JSObject * obj, uintN argc, jsval *
return JS_TRUE;
}
static JSBool request_add_header(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
static JSBool request_add_header(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
struct request_obj *ro = JS_GetPrivate(cx, obj);
@@ -226,7 +226,7 @@ static JSBool request_get_header(JSContext * cx, JSObject * obj, uintN argc, jsv
return JS_TRUE;
}
static JSBool request_dump_env(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
static JSBool request_dump_env(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
struct request_obj *ro = JS_GetPrivate(cx, obj);
char *how = "text";
@@ -244,10 +244,10 @@ static JSBool request_dump_env(JSContext *cx, JSObject *obj, uintN argc, jsval *
switch_xml_t xml;
char *xmlstr;
if ((xml = switch_event_xmlize(ro->stream->param_event, SWITCH_VA_NONE))) {
xmlstr = switch_xml_toxml(xml, SWITCH_FALSE);
xmlstr = switch_xml_toxml(xml, SWITCH_FALSE);
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, xmlstr));
return JS_TRUE;
}
}
} else {
char *buf;
switch_event_serialize(ro->stream->param_event, &buf, SWITCH_TRUE);
@@ -264,7 +264,7 @@ static JSBool request_dump_env(JSContext *cx, JSObject *obj, uintN argc, jsval *
static void request_destroy(JSContext * cx, JSObject * obj)
{
}
enum request_tinyid {
@@ -284,7 +284,7 @@ static JSPropertySpec request_props[] = {
{0}
};
static JSBool request_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
static JSBool request_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
{
JSBool res = JS_TRUE;
struct request_obj *ro = JS_GetPrivate(cx, obj);
@@ -320,12 +320,11 @@ JSClass request_class = {
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, request_destroy, NULL, NULL, NULL, NULL
};
static JSObject *new_request(JSContext *cx, JSObject *obj, struct request_obj *ro)
static JSObject *new_request(JSContext * cx, JSObject * obj, struct request_obj *ro)
{
JSObject *Request;
if ((Request = JS_DefineObject(cx, obj, "request", &request_class, NULL, 0))) {
if ((JS_SetPrivate(cx, Request, ro) &&
JS_DefineProperties(cx, Request, request_props) && JS_DefineFunctions(cx, Request, request_methods))) {
if ((JS_SetPrivate(cx, Request, ro) && JS_DefineProperties(cx, Request, request_props) && JS_DefineFunctions(cx, Request, request_methods))) {
return Request;
}
}
@@ -375,12 +374,12 @@ static JSBool pcre_compile(JSContext * cx, JSObject * obj, uintN argc, jsval * a
char *string, *regex_string;
if (argc > 1) {
string = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
regex_string = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
string = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
regex_string = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
switch_regex_safe_free(pcre_obj->re);
switch_safe_free(pcre_obj->string);
pcre_obj->string = strdup(string);
pcre_obj->proceed = switch_regex_perform(pcre_obj->string, regex_string, &pcre_obj->re, pcre_obj->ovector,
pcre_obj->proceed = switch_regex_perform(pcre_obj->string, regex_string, &pcre_obj->re, pcre_obj->ovector,
sizeof(pcre_obj->ovector) / sizeof(pcre_obj->ovector[0]));
*rval = BOOLEAN_TO_JSVAL(pcre_obj->proceed ? JS_TRUE : JS_FALSE);
} else {
@@ -401,10 +400,10 @@ static JSBool pcre_substitute(JSContext * cx, JSObject * obj, uintN argc, jsval
eval_some_js("~throw new Error(\"REGEX is not compiled or has no matches\");", cx, obj, rval);
return JS_FALSE;
}
if (argc > 0) {
uint32_t len;
subst_string = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
subst_string = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
len = (uint32_t) (strlen(pcre_obj->string) + strlen(subst_string) + 10);
substituted = malloc(len);
switch_assert(substituted != NULL);
@@ -841,7 +840,7 @@ static JSBool dtmf_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval *
case DTMF_DURATION:
{
*vp = INT_TO_JSVAL((int)dtmf->duration);
*vp = INT_TO_JSVAL((int) dtmf->duration);
}
break;
}
@@ -1097,10 +1096,10 @@ static switch_status_t js_common_callback(switch_core_session_t *session, void *
uintN argc = 0;
jsval argv[4];
JSObject *Event = NULL;
jsval nval , *rval = &nval;
jsval nval, *rval = &nval;
JSContext *cx = cb_state->cx;
JSObject *obj = cb_state->obj;
METHOD_SANITY_CHECK();
jss->stack_depth++;
@@ -1126,10 +1125,10 @@ static switch_status_t js_common_callback(switch_core_session_t *session, void *
return SWITCH_STATUS_FALSE;
}
break;
case SWITCH_INPUT_TYPE_DTMF:
case SWITCH_INPUT_TYPE_DTMF:
{
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
if (dtmf) {
if ((Event = new_js_dtmf(dtmf, "_XX_DTMF_XX_", cb_state->cx, cb_state->obj))) {
argv[argc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(cb_state->cx, "dtmf"));
@@ -1624,7 +1623,7 @@ static JSBool session_streamfile(JSContext * cx, JSObject * obj, uintN argc, jsv
switch_input_args_t args = { 0 };
const char *prebuf;
char posbuf[35] = "";
METHOD_SANITY_CHECK();
channel = switch_core_session_get_channel(jss->session);
CHANNEL_SANITY_CHECK();
@@ -1660,13 +1659,13 @@ static JSBool session_streamfile(JSContext * cx, JSObject * obj, uintN argc, jsv
JS_ValueToInt32(cx, argv[3], &samps);
fh.samples = samps;
}
if ((prebuf = switch_channel_get_variable(channel, "stream_prebuffer"))) {
int maybe = atoi(prebuf);
if (maybe > 0) {
fh.prebuf = maybe;
}
}
if ((prebuf = switch_channel_get_variable(channel, "stream_prebuffer"))) {
int maybe = atoi(prebuf);
if (maybe > 0) {
fh.prebuf = maybe;
}
}
cb_state.extra = &fh;
cb_state.ret = BOOLEAN_TO_JSVAL(JS_FALSE);
@@ -1825,7 +1824,7 @@ static JSBool session_speak(JSContext * cx, JSObject * obj, uintN argc, jsval *
if (jss->speech && strcasecmp(jss->speech->sh.name, tts_name)) {
destroy_speech_engine(jss);
}
if (jss->speech) {
switch_core_speech_text_param_tts(&jss->speech->sh, "voice", voice_name);
} else {
@@ -1861,7 +1860,7 @@ static JSBool session_speak(JSContext * cx, JSObject * obj, uintN argc, jsval *
args.input_callback = dtmf_func;
args.buf = bp;
args.buflen = len;
switch_core_speech_flush_tts(&jss->speech->sh);
switch_ivr_speak_text_handle(jss->session, &jss->speech->sh, &jss->speech->codec, NULL, text, &args);
JS_ResumeRequest(cx, cb_state.saveDepth);
@@ -2174,12 +2173,11 @@ static JSBool session_hangup(JSContext * cx, JSObject * obj, uintN argc, jsval *
CHANNEL_SANITY_CHECK();
if (argc > 1) {
if(JSVAL_IS_INT(argv[0])) {
if (JSVAL_IS_INT(argv[0])) {
int32 i = 0;
JS_ValueToInt32(cx, argv[0], &i);
cause = i;
}
else {
} else {
cause_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
cause = switch_channel_str2cause(cause_name);
}
@@ -2204,7 +2202,7 @@ struct fetch_url_data {
JSObject *obj;
switch_size_t buffer_size;
switch_size_t data_len;
char* buffer;
char *buffer;
};
static size_t hash_callback(void *ptr, size_t size, size_t nmemb, void *data)
@@ -2257,7 +2255,7 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
register unsigned int realsize = (unsigned int) (size * nmemb);
struct config_data *config_data = data;
if ((write(config_data->fd, ptr, realsize) != (int)realsize)) {
if ((write(config_data->fd, ptr, realsize) != (int) realsize)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to write all bytes!\n");
}
return realsize;
@@ -2412,7 +2410,7 @@ static JSBool js_fetchurl(JSContext * cx, JSObject * obj, uintN argc, jsval * ar
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, config_data.buffer));
} else {
char errmsg[256];
switch_snprintf(errmsg, 256, "~throw new Error(\"Curl returned error %u.\");", (unsigned)code);
switch_snprintf(errmsg, 256, "~throw new Error(\"Curl returned error %u.\");", (unsigned) code);
eval_some_js(errmsg, cx, obj, rval);
}
@@ -2593,7 +2591,7 @@ static JSObject *new_js_session(JSContext * cx, JSObject * obj, switch_core_sess
*jss = malloc(sizeof(**jss));
switch_assert(*jss);
memset(*jss, 0, sizeof(**jss));
(*jss)->session = session;
(*jss)->flags = flags;
(*jss)->cx = cx;
@@ -2628,7 +2626,7 @@ static JSBool session_construct(JSContext * cx, JSObject * obj, uintN argc, jsva
jss->cx = cx;
jss->obj = obj;
JS_SetPrivate(cx, obj, jss);
if (argc > 0) {
char *uuid = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
if (uuid) {
@@ -2649,7 +2647,7 @@ static JSBool session_set_callerdata(JSContext * cx, JSObject * obj, uintN argc,
char *var, *val, **toset = NULL;
var = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
val = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
if (!strcasecmp(var, "dialplan")) {
toset = &jss->dialplan;
} else if (!strcasecmp(var, "username")) {
@@ -2670,15 +2668,15 @@ static JSBool session_set_callerdata(JSContext * cx, JSObject * obj, uintN argc,
toset = &jss->destination_number;
} else if (!strcasecmp(var, "context")) {
toset = &jss->context;
}
}
if (toset) {
switch_safe_free(*toset);
*toset = strdup(val);
}
}
return JS_TRUE;
}
@@ -2727,14 +2725,22 @@ static JSBool session_originate(JSContext * cx, JSObject * obj, uintN argc, jsva
}
}
if (!switch_strlen_zero(jss->dialplan)) dialplan = jss->dialplan;
if (!switch_strlen_zero(jss->caller_id_name)) cid_name = jss->caller_id_name;
if (!switch_strlen_zero(jss->caller_id_number)) cid_num = jss->caller_id_number;
if (!switch_strlen_zero(jss->ani)) ani = jss->ani;
if (!switch_strlen_zero(jss->aniii)) aniii = jss->aniii;
if (!switch_strlen_zero(jss->rdnis)) rdnis = jss->rdnis;
if (!switch_strlen_zero(jss->context)) context = jss->context;
if (!switch_strlen_zero(jss->username)) username = jss->username;
if (!switch_strlen_zero(jss->dialplan))
dialplan = jss->dialplan;
if (!switch_strlen_zero(jss->caller_id_name))
cid_name = jss->caller_id_name;
if (!switch_strlen_zero(jss->caller_id_number))
cid_num = jss->caller_id_number;
if (!switch_strlen_zero(jss->ani))
ani = jss->ani;
if (!switch_strlen_zero(jss->aniii))
aniii = jss->aniii;
if (!switch_strlen_zero(jss->rdnis))
rdnis = jss->rdnis;
if (!switch_strlen_zero(jss->context))
context = jss->context;
if (!switch_strlen_zero(jss->username))
username = jss->username;
dest = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
@@ -2747,16 +2753,15 @@ static JSBool session_originate(JSContext * cx, JSObject * obj, uintN argc, jsva
tmp = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
if (!switch_strlen_zero(tmp)) {
to = tmp;
}
}
}
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
return JS_FALSE;
}
caller_profile = switch_caller_profile_new(pool,username, dialplan, cid_name, cid_num, network_addr,
ani, aniii, rdnis, modname, context, dest);
caller_profile = switch_caller_profile_new(pool, username, dialplan, cid_name, cid_num, network_addr, ani, aniii, rdnis, modname, context, dest);
saveDepth = JS_SuspendRequest(cx);
status = switch_ivr_originate(session, &peer_session, &jss->cause, dest, to ? atoi(to) : 60, NULL, NULL, NULL, caller_profile, SOF_NONE);
@@ -2766,7 +2771,7 @@ static JSBool session_originate(JSContext * cx, JSObject * obj, uintN argc, jsva
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot Create Outgoing Channel! [%s]\n", dest);
goto done;
}
jss->session = peer_session;
switch_set_flag(jss, S_HUP);
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
@@ -2783,21 +2788,21 @@ static JSBool session_originate(JSContext * cx, JSObject * obj, uintN argc, jsva
static void session_destroy(JSContext * cx, JSObject * obj)
{
struct js_session *jss;
if (cx && obj) {
if ((jss = JS_GetPrivate(cx, obj))) {
JS_SetPrivate(cx, obj, NULL);
if (jss->speech && *jss->speech->sh.name) {
destroy_speech_engine(jss);
}
if (jss->session) {
switch_core_session_t *session = jss->session;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_set_private(channel, "jss", NULL);
switch_core_event_hook_remove_state_change(session, hanguphook);
if (switch_test_flag(jss, S_HUP)) {
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
}
@@ -2816,7 +2821,7 @@ static void session_destroy(JSContext * cx, JSObject * obj)
}
free(jss);
}
}
@@ -3025,7 +3030,7 @@ JSClass fileio_class = {
static JSBool js_exit(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
char *supplied_error, code_buf[256] = "";
if (argc > 0 && (supplied_error = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
switch_snprintf(code_buf, sizeof(code_buf), "~throw new Error(\"%s\");", supplied_error);
eval_some_js(code_buf, cx, obj, rval);
@@ -3078,7 +3083,7 @@ static JSBool js_global_set(JSContext * cx, JSObject * obj, uintN argc, jsval *
char *var_name = NULL, *val = NULL;
if (argc > 1) {
var_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
val = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
val = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
switch_core_set_variable(var_name, val);
return JS_TRUE;
}
@@ -3153,7 +3158,7 @@ static JSBool js_api_execute(JSContext * cx, JSObject * obj, uintN argc, jsval *
if (argc > 1) {
arg = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
}
if (argc > 2) {
JSObject *session_obj;
struct js_session *jss;
@@ -3384,7 +3389,7 @@ SWITCH_STANDARD_APP(js_dp_function)
js_parse_and_execute(session, data, NULL);
}
static void *SWITCH_THREAD_FUNC js_thread_run(switch_thread_t * thread, void *obj)
static void *SWITCH_THREAD_FUNC js_thread_run(switch_thread_t *thread, void *obj)
{
char *input_code = obj;
@@ -3419,17 +3424,17 @@ static void js_thread_launch(const char *text)
SWITCH_STANDARD_API(jsapi_function)
{
struct request_obj ro = {0};
struct request_obj ro = { 0 };
char *path_info = NULL;
if (stream->param_event) {
if (stream->param_event) {
path_info = switch_event_get_header(stream->param_event, "http-path-info");
}
if (switch_strlen_zero(cmd) && path_info) {
cmd = path_info;
}
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "USAGE: %s\n", jsapi_interface.syntax);
return SWITCH_STATUS_SUCCESS;
@@ -3456,14 +3461,14 @@ SWITCH_STANDARD_API(launch_async)
return SWITCH_STATUS_SUCCESS;
}
static void message_query_handler(switch_event_t *event)
static void message_query_handler(switch_event_t *event)
{
char *account = switch_event_get_header(event, "message-account");
if (account) {
char *path, *cmd;
path = switch_mprintf("%s%smwi.js", SWITCH_GLOBAL_dirs.script_dir, SWITCH_PATH_SEPARATOR);
path = switch_mprintf("%s%smwi.js", SWITCH_GLOBAL_dirs.script_dir, SWITCH_PATH_SEPARATOR);
switch_assert(path != NULL);
if (switch_file_exists(path, NULL) == SWITCH_STATUS_SUCCESS) {
@@ -3497,7 +3502,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spidermonkey_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_API(api_interface, "jsrun", "run a script", launch_async, "jsrun <script> [additional_vars [...]]");
SWITCH_ADD_API(api_interface, "jsapi", "execute an api call", jsapi_function, "jsapi <script> [additional_vars [...]]");
SWITCH_ADD_APP(app_interface, "javascript", "Launch JS ivr", "Run a javascript ivr on a channel", js_dp_function, "<script> [additional_vars [...]]", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "javascript", "Launch JS ivr", "Run a javascript ivr on a channel", js_dp_function, "<script> [additional_vars [...]]",
SAF_SUPPORT_NOMEDIA);
curl_global_init(CURL_GLOBAL_ALL);
@@ -73,10 +73,10 @@ static JSBool db_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * a
return JS_FALSE;
}
static JSBool db_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
static JSBool db_close(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
struct db_obj *dbo = JS_GetPrivate(cx, obj);
if (dbo) {
if (dbo->stmt) {
switch_core_db_finalize(dbo->stmt);
@@ -91,7 +91,7 @@ static JSBool db_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js
return JS_TRUE;
}
static void db_destroy(JSContext *cx, JSObject *obj)
static void db_destroy(JSContext * cx, JSObject * obj)
{
struct db_obj *dbo = JS_GetPrivate(cx, obj);
@@ -215,7 +215,7 @@ static JSBool db_fetch(JSContext * cx, JSObject * obj, uintN argc, jsval * argv,
}
for (x = 0; x < colcount; x++) {
switch_snprintf(code, sizeof(code), "~_dB_RoW_DaTa_[\"%s\"] = \"%s\"",
(char *) switch_core_db_column_name(dbo->stmt, x), (char *) switch_core_db_column_text(dbo->stmt, x));
(char *) switch_core_db_column_name(dbo->stmt, x), (char *) switch_core_db_column_text(dbo->stmt, x));
eval_some_js(code, dbo->cx, dbo->obj, rval);
if (*rval == JS_FALSE) {
@@ -275,7 +275,7 @@ static JSPropertySpec db_props[] = {
};
static JSBool db_setProperty(JSContext * cx, JSObject * obj, jsval id, jsval *vp)
static JSBool db_setProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
{
char *name = JS_GetStringBytes(JS_ValueToString(cx, id));
@@ -332,7 +332,7 @@ const sm_module_interface_t DB_module_interface = {
/*.next */ NULL
};
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t ** module_interface)
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t **module_interface)
{
*module_interface = &DB_module_interface;
return SWITCH_STATUS_SUCCESS;
@@ -41,7 +41,7 @@ struct curl_obj {
JSFunction *function;
JSObject *user_data;
jsrefcount saveDepth;
jsval ret;
jsval ret;
};
@@ -51,21 +51,21 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
struct curl_obj *co = data;
uintN argc = 0;
jsval argv[4];
if (!co) {
return 0;
}
if (co->function) {
char *ret;
argv[argc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(co->cx, (char *)ptr));
argv[argc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(co->cx, (char *) ptr));
if (co->user_data) {
argv[argc++] = OBJECT_TO_JSVAL(co->user_data);
}
JS_ResumeRequest(co->cx, co->saveDepth);
JS_CallFunction(co->cx, co->obj, co->function, argc, argv, &co->ret);
co->saveDepth = JS_SuspendRequest(co->cx);
if ((ret = JS_GetStringBytes(JS_ValueToString(co->cx, co->ret)))) {
if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
return realsize;
@@ -81,7 +81,7 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
/* Curl Object */
/*********************************************************************************/
static JSBool curl_construct(JSContext *cx, JSObject *obj, uintN argc, jsval * argv, jsval * rval)
static JSBool curl_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
struct curl_obj *co = NULL;
@@ -98,14 +98,14 @@ static JSBool curl_construct(JSContext *cx, JSObject *obj, uintN argc, jsval * a
return JS_TRUE;
}
static void curl_destroy(JSContext *cx, JSObject *obj)
static void curl_destroy(JSContext * cx, JSObject * obj)
{
struct curl_obj *co = JS_GetPrivate(cx, obj);
switch_safe_free(co);
JS_SetPrivate(cx, obj, NULL);
}
static JSBool curl_run(JSContext *cx, JSObject *obj, uintN argc, jsval * argv, jsval * rval)
static JSBool curl_run(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
struct curl_obj *co = JS_GetPrivate(cx, obj);
char *method = NULL, *url, *cred = NULL;
@@ -127,11 +127,11 @@ static JSBool curl_run(JSContext *cx, JSObject *obj, uintN argc, jsval * argv, j
curl_easy_setopt(co->curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
}
headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
if (argc > 2) {
data = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
}
if (argc > 3) {
co->function = JS_ValueToFunction(cx, argv[3]);
}
@@ -148,7 +148,7 @@ static JSBool curl_run(JSContext *cx, JSObject *obj, uintN argc, jsval * argv, j
}
}
curl_easy_setopt(co->curl_handle, CURLOPT_HTTPHEADER, headers);
url_p = url;
@@ -164,7 +164,7 @@ static JSBool curl_run(JSContext *cx, JSObject *obj, uintN argc, jsval * argv, j
url_p = durl;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Running: method: [%s] url: [%s] data: [%s] cred=[%s] cb: [%s]\n",
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Running: method: [%s] url: [%s] data: [%s] cred=[%s] cb: [%s]\n",
method, url_p, data, switch_str_nil(cred), co->function ? "yes" : "no");
curl_easy_setopt(co->curl_handle, CURLOPT_URL, url_p);
@@ -172,7 +172,7 @@ static JSBool curl_run(JSContext *cx, JSObject *obj, uintN argc, jsval * argv, j
curl_easy_setopt(co->curl_handle, CURLOPT_WRITEDATA, (void *) co);
curl_easy_setopt(co->curl_handle, CURLOPT_USERAGENT, "freeswitch-spidermonkey-curl/1.0");
co->saveDepth = JS_SuspendRequest(cx);
curl_easy_perform(co->curl_handle);
@@ -183,7 +183,7 @@ static JSBool curl_run(JSContext *cx, JSObject *obj, uintN argc, jsval * argv, j
co->function = NULL;
JS_ResumeRequest(cx, co->saveDepth);
switch_safe_free(durl);
return JS_TRUE;
}
@@ -198,7 +198,7 @@ static JSPropertySpec curl_props[] = {
{0}
};
static JSBool curl_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval * vp)
static JSBool curl_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
{
JSBool res = JS_TRUE;
return res;
@@ -212,7 +212,7 @@ JSClass curl_class = {
};
switch_status_t curl_load(JSContext *cx, JSObject *obj)
switch_status_t curl_load(JSContext * cx, JSObject * obj)
{
JS_InitClass(cx, obj, NULL, &curl_class, curl_construct, 3, curl_props, curl_methods, curl_props, curl_methods);
return SWITCH_STATUS_SUCCESS;
@@ -225,7 +225,7 @@ const sm_module_interface_t curl_module_interface = {
/*.next */ NULL
};
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t ** module_interface)
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t **module_interface)
{
curl_global_init(CURL_GLOBAL_ALL);
*module_interface = &curl_module_interface;
@@ -42,7 +42,7 @@ struct odbc_obj {
SQLCHAR *code;
int32 codelen;
};
typedef struct odbc_obj odbc_obj_t;
typedef struct odbc_obj odbc_obj_t;
static odbc_obj_t *new_odbc_obj(char *dsn, char *username, char *password)
{
@@ -56,7 +56,7 @@ static odbc_obj_t *new_odbc_obj(char *dsn, char *username, char *password)
if (!(new_obj->handle = switch_odbc_handle_new(dsn, username, password))) {
goto err;
}
return new_obj;
err:
@@ -72,29 +72,30 @@ static odbc_obj_t *new_odbc_obj(char *dsn, char *username, char *password)
switch_odbc_status_t odbc_obj_connect(odbc_obj_t *obj)
{
return switch_odbc_handle_connect(obj->handle);
}
static void destroy_odbc_obj(odbc_obj_t ** objp)
static void destroy_odbc_obj(odbc_obj_t **objp)
{
odbc_obj_t *obj = *objp;
if (obj == NULL) return;
if (obj == NULL)
return;
if (obj->stmt) {
SQLFreeHandle(SQL_HANDLE_STMT, obj->stmt);
}
if (obj->handle) {
switch_odbc_handle_destroy(&obj->handle);
}
switch_safe_free(obj->colbuf);
switch_safe_free(obj->code);
if (obj->handle) {
switch_odbc_handle_destroy(&obj->handle);
}
switch_safe_free(obj->colbuf);
switch_safe_free(obj->code);
switch_safe_free(obj);
}
/* ODBC Object */
/*********************************************************************************/
static JSBool odbc_construct(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
static JSBool odbc_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
odbc_obj_t *odbc_obj = NULL;
char *dsn, *username, *password;
@@ -156,16 +157,17 @@ static JSBool odbc_construct(JSContext * cx, JSObject * obj, uintN argc, jsval *
static void odbc_destroy(JSContext * cx, JSObject * obj)
{
odbc_obj_t *odbc_obj;
if (obj == NULL) return;
odbc_obj_t *odbc_obj;
if (obj == NULL)
return;
odbc_obj = (odbc_obj_t *) JS_GetPrivate(cx, obj);
if (odbc_obj) {
destroy_odbc_obj(&odbc_obj);
JS_SetPrivate(cx, obj, NULL);
}
JS_SetPrivate(cx, obj, NULL);
}
}
static JSBool odbc_connect(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
static JSBool odbc_connect(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
odbc_obj_t *odbc_obj = (odbc_obj_t *) JS_GetPrivate(cx, obj);
JSBool tf = JS_TRUE;
@@ -183,7 +185,7 @@ static JSBool odbc_connect(JSContext * cx, JSObject * obj, uintN argc, jsval *ar
return JS_TRUE;
}
static JSBool odbc_execute(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
static JSBool odbc_execute(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
odbc_obj_t *odbc_obj = (odbc_obj_t *) JS_GetPrivate(cx, obj);
char *sql;
@@ -217,7 +219,7 @@ static JSBool odbc_execute(JSContext * cx, JSObject * obj, uintN argc, jsval *ar
return JS_TRUE;
}
static JSBool odbc_exec(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
static JSBool odbc_exec(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
odbc_obj_t *odbc_obj = (odbc_obj_t *) JS_GetPrivate(cx, obj);
char *sql;
@@ -253,7 +255,7 @@ static JSBool odbc_exec(JSContext * cx, JSObject * obj, uintN argc, jsval *argv,
return JS_TRUE;
}
static JSBool odbc_num_rows(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
static JSBool odbc_num_rows(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
odbc_obj_t *odbc_obj = (odbc_obj_t *) JS_GetPrivate(cx, obj);
@@ -277,7 +279,7 @@ static JSBool odbc_num_rows(JSContext * cx, JSObject * obj, uintN argc, jsval *a
}
static JSBool odbc_next_row(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
static JSBool odbc_next_row(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
odbc_obj_t *odbc_obj = (odbc_obj_t *) JS_GetPrivate(cx, obj);
int result = 0;
@@ -285,8 +287,8 @@ static JSBool odbc_next_row(JSContext * cx, JSObject * obj, uintN argc, jsval *a
if (switch_odbc_handle_get_state(odbc_obj->handle) != SWITCH_ODBC_STATE_CONNECTED) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not connected!\n");
goto done;
}
goto done;
}
if (odbc_obj->stmt) {
@@ -345,7 +347,7 @@ static char *escape_data(char *in, char escapeChar)
}
static JSBool odbc_get_data(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
static JSBool odbc_get_data(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
odbc_obj_t *odbc_obj = (odbc_obj_t *) JS_GetPrivate(cx, obj);
@@ -353,8 +355,8 @@ static JSBool odbc_get_data(JSContext * cx, JSObject * obj, uintN argc, jsval *a
if (switch_odbc_handle_get_state(odbc_obj->handle) != SWITCH_ODBC_STATE_CONNECTED) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not connected!\n");
goto done;
}
goto done;
}
if (odbc_obj->stmt) {
SQLSMALLINT c = 0, x = 0;
@@ -374,7 +376,7 @@ static JSBool odbc_get_data(JSContext * cx, JSObject * obj, uintN argc, jsval *a
SQLCHAR name[1024] = "";
SQLCHAR *data = odbc_obj->colbuf;
SQLCHAR *esc = NULL;
SQLDescribeCol(odbc_obj->stmt, x, name, sizeof(name), &NameLength, &DataType, &ColumnSize, &DecimalDigits, &Nullable);
SQLGetData(odbc_obj->stmt, x, SQL_C_CHAR, odbc_obj->colbuf, odbc_obj->cblen, NULL);
@@ -407,10 +409,10 @@ static JSBool odbc_get_data(JSContext * cx, JSObject * obj, uintN argc, jsval *a
}
static JSBool odbc_close(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
static JSBool odbc_close(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
odbc_destroy(cx, obj);
return JS_TRUE;
odbc_destroy(cx, obj);
return JS_TRUE;
}
enum odbc_tinyid {
@@ -425,17 +427,17 @@ static JSFunctionSpec odbc_methods[] = {
{"numRows", odbc_num_rows, 1},
{"nextRow", odbc_next_row, 1},
{"getData", odbc_get_data, 1},
{"close", odbc_close, 1},
{"close", odbc_close, 1},
{0}
};
static JSPropertySpec odbc_props[] = {
{"name", odbc_NAME, JSPROP_READONLY|JSPROP_PERMANENT},
{"name", odbc_NAME, JSPROP_READONLY | JSPROP_PERMANENT},
{0}
};
static JSBool odbc_setProperty(JSContext * cx, JSObject * obj, jsval id, jsval *vp)
static JSBool odbc_setProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
{
char *name = JS_GetStringBytes(JS_ValueToString(cx, id));
@@ -446,11 +448,11 @@ static JSBool odbc_setProperty(JSContext * cx, JSObject * obj, jsval id, jsval *
return JS_TRUE;
}
static JSBool odbc_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval *vp)
static JSBool odbc_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
{
int param;
char *name = JS_GetStringBytes(JS_ValueToString(cx, id));
/* numbers are our props anything else is a method */
if (name[0] >= 48 && name[0] <= 57) {
param = atoi(name);
@@ -483,7 +485,7 @@ const sm_module_interface_t odbc_module_interface = {
/*.next */ NULL
};
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t ** module_interface)
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t **module_interface)
{
*module_interface = &odbc_module_interface;
return SWITCH_STATUS_SUCCESS;
@@ -93,7 +93,7 @@ const sm_module_interface_t skel_module_interface = {
/*.next */ NULL
};
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t ** module_interface)
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t **module_interface)
{
*module_interface = &skel_module_interface;
return SWITCH_STATUS_SUCCESS;
@@ -34,7 +34,7 @@ static const char modname[] = "Socket";
struct js_socket_obj {
switch_socket_t *socket;
switch_memory_pool_t *pool;
char* read_buffer;
char *read_buffer;
switch_size_t buffer_size;
int state;
};
@@ -44,20 +44,18 @@ typedef struct js_socket_obj js_socket_obj_t;
/*********************************************************************************/
static JSBool socket_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
js_socket_obj_t* js_socket_obj = 0;
js_socket_obj_t *js_socket_obj = 0;
switch_memory_pool_t *pool;
switch_socket_t *socket;
switch_status_t ret;
switch_core_new_memory_pool(&pool);
ret = switch_socket_create(&socket, AF_INET, SOCK_STREAM, SWITCH_PROTO_TCP, pool);
if (ret != SWITCH_STATUS_SUCCESS)
{
if (ret != SWITCH_STATUS_SUCCESS) {
switch_core_destroy_memory_pool(&pool);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Failed to create socket, reason: %d.\n", ret);
return JS_FALSE;
}
// allocate information needed by JS to be able to write to the log.
// (needed since multitple js sessions can write to the same log)
js_socket_obj = switch_core_alloc(pool, sizeof(js_socket_obj_t));
@@ -73,8 +71,7 @@ static void socket_destroy(JSContext * cx, JSObject * obj)
if (socket == NULL)
return;
if (socket->socket != 0)
{
if (socket->socket != 0) {
switch_socket_shutdown(socket->socket, SWITCH_SHUTDOWN_READWRITE);
switch_socket_close(socket->socket);
switch_core_destroy_memory_pool(&socket->pool);
@@ -84,14 +81,12 @@ static void socket_destroy(JSContext * cx, JSObject * obj)
static JSBool socket_connect(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
if (socket == NULL)
{
if (socket == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find js object.\n");
return JS_FALSE;
}
if (argc == 2)
{
if (argc == 2) {
char *host = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
int32 port;
switch_sockaddr_t *addr;
@@ -99,21 +94,18 @@ static JSBool socket_connect(JSContext * cx, JSObject * obj, uintN argc, jsval *
JS_ValueToInt32(cx, argv[1], &port);
ret = switch_sockaddr_info_get(&addr, host, AF_INET, (switch_port_t)port, 0, socket->pool);
if (ret != SWITCH_STATUS_SUCCESS)
{
ret = switch_sockaddr_info_get(&addr, host, AF_INET, (switch_port_t) port, 0, socket->pool);
if (ret != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_sockaddr_info_get failed: %d.\n", ret);
return JS_FALSE;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Connecting to: %s:%d.\n", host, port);
ret = switch_socket_connect(socket->socket, addr);
if (ret != SWITCH_STATUS_SUCCESS)
{
if (ret != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_socket_connect failed: %d.\n", ret);
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
}
else
} else
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
}
@@ -124,23 +116,19 @@ static JSBool socket_connect(JSContext * cx, JSObject * obj, uintN argc, jsval *
static JSBool socket_send(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
if (socket == NULL)
{
if (socket == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find js object.\n");
return JS_FALSE;
}
if (argc == 1)
{
if (argc == 1) {
char *buffer = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
switch_size_t len = strlen(buffer);
switch_status_t ret = switch_socket_send(socket->socket, buffer, &len);
if (ret != SWITCH_STATUS_SUCCESS)
{
if (ret != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_socket_send failed: %d.\n", ret);
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
}
else
} else
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
}
@@ -150,35 +138,29 @@ static JSBool socket_send(JSContext * cx, JSObject * obj, uintN argc, jsval * ar
static JSBool socket_read_bytes(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
if (socket == NULL)
{
if (socket == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find js object.\n");
return JS_FALSE;
}
if (argc == 1)
{
if (argc == 1) {
int32 bytes_to_read;
switch_status_t ret;
switch_size_t len;
JS_ValueToInt32(cx, argv[0], &bytes_to_read);
len = (switch_size_t)bytes_to_read;
len = (switch_size_t) bytes_to_read;
if (socket->buffer_size < len)
{
socket->read_buffer = switch_core_alloc(socket->pool, len+1);
if (socket->buffer_size < len) {
socket->read_buffer = switch_core_alloc(socket->pool, len + 1);
socket->buffer_size = bytes_to_read + 1;
}
ret = switch_socket_recv(socket->socket, socket->read_buffer, &len);
if (ret != SWITCH_STATUS_SUCCESS)
{
if (ret != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_socket_send failed: %d.\n", ret);
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
}
else
{
} else {
socket->read_buffer[len] = 0;
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, socket->read_buffer));
}
@@ -190,15 +172,13 @@ static JSBool socket_read_bytes(JSContext * cx, JSObject * obj, uintN argc, jsva
static JSBool socket_read(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
if (socket == NULL)
{
if (socket == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find js object.\n");
return JS_FALSE;
}
if (argc >= 0)
{
char* delimiter = "\n";
if (argc >= 0) {
char *delimiter = "\n";
switch_status_t ret = SWITCH_STATUS_FALSE;
switch_size_t len = 1;
switch_size_t total_length = 0;
@@ -212,8 +192,7 @@ static JSBool socket_read(JSContext * cx, JSObject * obj, uintN argc, jsval * ar
if (socket->read_buffer == 0)
socket->read_buffer = switch_core_alloc(socket->pool, socket->buffer_size);
while (can_run == TRUE)
{
while (can_run == TRUE) {
ret = switch_socket_recv(socket->socket, tempbuf, &len);
if (ret != SWITCH_STATUS_SUCCESS)
break;
@@ -223,13 +202,11 @@ static JSBool socket_read(JSContext * cx, JSObject * obj, uintN argc, jsval * ar
break;
else if (tempbuf[0] == '\r' && delimiter[0] == '\n')
continue;
else
{
else {
// Buffer is full, let's increase it.
if (total_length == socket->buffer_size - 1)
{
if (total_length == socket->buffer_size - 1) {
switch_size_t new_size = socket->buffer_size + 4196;
char* new_buffer = switch_core_alloc(socket->pool, socket->buffer_size);
char *new_buffer = switch_core_alloc(socket->pool, socket->buffer_size);
memcpy(new_buffer, socket->read_buffer, total_length);
socket->buffer_size = new_size;
socket->read_buffer = new_buffer;
@@ -238,13 +215,10 @@ static JSBool socket_read(JSContext * cx, JSObject * obj, uintN argc, jsval * ar
++total_length;
}
}
if (ret != SWITCH_STATUS_SUCCESS)
{
if (ret != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "socket receive failed: %d.\n", ret);
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
}
else
{
} else {
socket->read_buffer[total_length] = 0;
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, socket->read_buffer));
}
@@ -256,8 +230,7 @@ static JSBool socket_read(JSContext * cx, JSObject * obj, uintN argc, jsval * ar
static JSBool socket_close(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
if (socket == NULL)
{
if (socket == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find js object.\n");
return JS_FALSE;
}
@@ -290,7 +263,7 @@ static JSPropertySpec socket_props[] = {
static JSBool socket_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
{
JSBool res = JS_TRUE;
// js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
// js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
char *name;
int param = 0;
@@ -335,7 +308,7 @@ const sm_module_interface_t socket_module_interface = {
/*.next */ NULL
};
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t ** module_interface)
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t **module_interface)
{
*module_interface = &socket_module_interface;
return SWITCH_STATUS_SUCCESS;
@@ -56,7 +56,7 @@ struct teletone_obj {
};
static int teletone_handler(teletone_generation_session_t * ts, teletone_tone_map_t * map)
static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
{
struct teletone_obj *tto = ts->user_data;
int wrote;
@@ -249,7 +249,7 @@ static JSBool teletone_generate(JSContext * cx, JSObject * obj, uintN argc, jsva
if (switch_test_flag(tto, TTF_DTMF)) {
char dtmf[128];
char *ret;
if (switch_channel_has_dtmf(channel)) {
uintN aargc = 0;
jsval aargv[4];
@@ -345,7 +345,7 @@ const sm_module_interface_t teletone_module_interface = {
/*.next */ NULL
};
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t ** module_interface)
SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t **module_interface)
{
*module_interface = &teletone_module_interface;
return SWITCH_STATUS_SUCCESS;