diff --git a/src/mod/legacy/languages/mod_spidermonkey/.gitignore b/src/mod/legacy/languages/mod_spidermonkey/.gitignore
deleted file mode 100644
index 1ce7a516b6..0000000000
--- a/src/mod/legacy/languages/mod_spidermonkey/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-Makefile
-Makefile.in
-mod_spidermonkey.log
diff --git a/src/mod/legacy/languages/mod_spidermonkey/Makefile.am b/src/mod/legacy/languages/mod_spidermonkey/Makefile.am
deleted file mode 100644
index eb3eef7fed..0000000000
--- a/src/mod/legacy/languages/mod_spidermonkey/Makefile.am
+++ /dev/null
@@ -1,65 +0,0 @@
-include $(top_srcdir)/build/modmake.rulesam
-
-MODNAME=mod_spidermonkey
-
-JS_DIR=$(switch_srcdir)/libs/js
-JS_BUILDDIR=$(switch_builddir)/libs/js
-JSLA=$(JS_BUILDDIR)/libjs.la
-
-AM_CFLAGS += -I. -I$(JS_DIR)/src -I$(JS_DIR)/nsprpub/dist/include/nspr -I$(JS_BUILDDIR)/src -I$(JS_BUILDDIR)/nsprpub/dist/include/nspr
-AM_CFLAGS += -DXP_UNIX -DJS_THREADSAFE -DJS_HAS_FILE_OBJECT=1 -DJS_HAS_XML_SUPPORT=1
-AM_LIBADD = $(switch_builddir)/libfreeswitch.la $(JSLA) -lnspr4 $(JS_BUILDDIR)/nsprpub/pr/src/libnspr4.*
-AM_LDFLAGS += -avoid-version -module -no-undefined -shared
-AM_LDFLAGS += -L$(JS_BUILDDIR)/nsprpub/dist/lib
-BUILT_SOURCES = $(JSLA)
-
-mod_LTLIBRARIES = mod_spidermonkey.la
-mod_spidermonkey_la_SOURCES = mod_spidermonkey.c
-mod_spidermonkey_la_CFLAGS = $(AM_CFLAGS)
-mod_spidermonkey_la_CPPFLAGS = $(CURL_CFLAGS) $(AM_CPPFLAGS)
-mod_spidermonkey_la_LIBADD = $(AM_LIBADD)
-mod_spidermonkey_la_LDFLAGS = $(CURL_LIBS) $(AM_LDFLAGS)
-
-mod_LTLIBRARIES += mod_spidermonkey_curl.la
-mod_spidermonkey_curl_la_SOURCES = mod_spidermonkey_curl.c
-mod_spidermonkey_curl_la_CFLAGS = $(AM_CFLAGS)
-mod_spidermonkey_curl_la_CPPFLAGS = $(CURL_CFLAGS) $(AM_CPPFLAGS)
-mod_spidermonkey_curl_la_LIBADD = $(AM_LIBADD)
-mod_spidermonkey_curl_la_LDFLAGS = $(CURL_LIBS) $(AM_LDFLAGS)
-
-mod_LTLIBRARIES += mod_spidermonkey_socket.la
-mod_spidermonkey_socket_la_SOURCES = mod_spidermonkey_socket.c
-mod_spidermonkey_socket_la_CFLAGS = $(AM_CFLAGS)
-mod_spidermonkey_socket_la_LIBADD = $(AM_LIBADD)
-mod_spidermonkey_socket_la_LDFLAGS = $(AM_LDFLAGS)
-
-mod_LTLIBRARIES += mod_spidermonkey_core_db.la
-mod_spidermonkey_core_db_la_SOURCES = mod_spidermonkey_core_db.c
-mod_spidermonkey_core_db_la_CFLAGS = $(AM_CFLAGS)
-mod_spidermonkey_core_db_la_LIBADD = $(AM_LIBADD)
-mod_spidermonkey_core_db_la_LDFLAGS = $(AM_LDFLAGS)
-
-mod_LTLIBRARIES += mod_spidermonkey_teletone.la
-mod_spidermonkey_teletone_la_SOURCES = mod_spidermonkey_teletone.c
-mod_spidermonkey_teletone_la_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/libteletone/src
-mod_spidermonkey_teletone_la_LIBADD = $(AM_LIBADD)
-mod_spidermonkey_teletone_la_LDFLAGS = $(AM_LDFLAGS)
-
-if HAVE_ODBC
-mod_LTLIBRARIES += mod_spidermonkey_odbc.la
-mod_spidermonkey_odbc_la_SOURCES = mod_spidermonkey_odbc.c
-mod_spidermonkey_odbc_la_CFLAGS = $(AM_CFLAGS) $(ODBC_INC_FLAGS)
-mod_spidermonkey_odbc_la_LIBADD = $(AM_LIBADD)
-mod_spidermonkey_odbc_la_LDFLAGS = $(AM_LDFLAGS) -lodbc
-endif
-
-$(SOURCES): $(BUILT_SOURCES)
-
-$(JSLA): $(JS_DIR) $(JS_DIR)/.update
- cd $(JS_BUILDDIR)/nsprpub && $(MAKE) -j1 && cd $(JS_BUILDDIR) && $(MAKE)
- $(TOUCH_TARGET)
-
-install-exec-local: $(DESTDIR)$(libdir)/libjs.la
-
-$(DESTDIR)$(libdir)/libjs.la: $(JSLA)
- cd $(JS_BUILDDIR)/nsprpub/ && $(MAKE) -j1 install && cd $(JS_BUILDDIR) && $(MAKE) install
diff --git a/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.2008.vcproj b/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.2008.vcproj
deleted file mode 100644
index cf35ce5e13..0000000000
--- a/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.2008.vcproj
+++ /dev/null
@@ -1,301 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.2010.vcxproj b/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.2010.vcxproj
deleted file mode 100644
index 4506dd561d..0000000000
--- a/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.2010.vcxproj
+++ /dev/null
@@ -1,165 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Debug
- x64
-
-
- Release
- Win32
-
-
- Release
- x64
-
-
-
- mod_spidermonkey
- {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}
- mod_spidermonkey
- Win32Proj
-
-
-
- DynamicLibrary
- MultiByte
-
-
- DynamicLibrary
- MultiByte
-
-
- DynamicLibrary
- MultiByte
-
-
- DynamicLibrary
- MultiByte
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_ProjectFileVersion>10.0.30319.1
-
-
-
- Disabled
- ..\..\..\..\..\libs\curl-7.35.0\include;%(AdditionalIncludeDirectories)
- SM_EXPORTS;JS_HAS_FILE_OBJECT=1;XP_WIN;%(PreprocessorDefinitions)
-
-
-
-
- $(Platform)\$(Configuration)\$(ProjectName).lib
- %(AdditionalLibraryDirectories)
- false
-
-
-
-
-
-
- X64
-
-
- Disabled
- ..\..\..\..\..\libs\curl-7.35.0\include;%(AdditionalIncludeDirectories)
- SM_EXPORTS;JS_HAS_FILE_OBJECT=1;XP_WIN;%(PreprocessorDefinitions)
-
-
-
-
- $(Platform)\$(Configuration)\$(ProjectName).lib
- %(AdditionalLibraryDirectories)
- false
-
-
- MachineX64
-
-
-
-
- ..\..\..\..\..\libs\curl-7.35.0\include;%(AdditionalIncludeDirectories)
- SM_EXPORTS;JS_HAS_FILE_OBJECT=1;XP_WIN;%(PreprocessorDefinitions)
-
-
-
-
- $(Platform)\$(Configuration)\$(ProjectName).lib
- %(AdditionalLibraryDirectories)
- false
-
-
-
-
-
-
- X64
-
-
- ..\..\..\..\..\libs\curl-7.35.0\include;%(AdditionalIncludeDirectories)
- SM_EXPORTS;JS_HAS_FILE_OBJECT=1;XP_WIN;%(PreprocessorDefinitions)
-
-
-
-
- $(Platform)\$(Configuration)\$(ProjectName).lib
- %(AdditionalLibraryDirectories)
- false
-
-
- MachineX64
-
-
-
-
-
-
-
- {f6c55d93-b927-4483-bb69-15aef3dd2dff}
- false
-
-
- {87ee9da4-de1e-4448-8324-183c98dca588}
- false
-
-
- {204fa0de-305d-4414-ae2e-f195a23f390d}
- false
-
-
- {202d7a4e-760d-4d0e-afa1-d7459ced30ff}
- false
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.2012.vcxproj b/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.2012.vcxproj
deleted file mode 100644
index f74c051eb2..0000000000
--- a/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.2012.vcxproj
+++ /dev/null
@@ -1,169 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Debug
- x64
-
-
- Release
- Win32
-
-
- Release
- x64
-
-
-
- mod_spidermonkey
- {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}
- mod_spidermonkey
- Win32Proj
-
-
-
- DynamicLibrary
- MultiByte
- v110
-
-
- DynamicLibrary
- MultiByte
- v110
-
-
- DynamicLibrary
- MultiByte
- v110
-
-
- DynamicLibrary
- MultiByte
- v110
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_ProjectFileVersion>10.0.30319.1
-
-
-
- Disabled
- ..\..\..\..\..\libs\curl-7.35.0\include;%(AdditionalIncludeDirectories)
- SM_EXPORTS;JS_HAS_FILE_OBJECT=1;XP_WIN;%(PreprocessorDefinitions)
-
-
-
-
- $(Platform)\$(Configuration)\$(ProjectName).lib
- %(AdditionalLibraryDirectories)
- false
-
-
-
-
-
-
- X64
-
-
- Disabled
- ..\..\..\..\..\libs\curl-7.35.0\include;%(AdditionalIncludeDirectories)
- SM_EXPORTS;JS_HAS_FILE_OBJECT=1;XP_WIN;%(PreprocessorDefinitions)
-
-
-
-
- $(Platform)\$(Configuration)\$(ProjectName).lib
- %(AdditionalLibraryDirectories)
- false
-
-
- MachineX64
-
-
-
-
- ..\..\..\..\..\libs\curl-7.35.0\include;%(AdditionalIncludeDirectories)
- SM_EXPORTS;JS_HAS_FILE_OBJECT=1;XP_WIN;%(PreprocessorDefinitions)
-
-
-
-
- $(Platform)\$(Configuration)\$(ProjectName).lib
- %(AdditionalLibraryDirectories)
- false
-
-
-
-
-
-
- X64
-
-
- ..\..\..\..\..\libs\curl-7.35.0\include;%(AdditionalIncludeDirectories)
- SM_EXPORTS;JS_HAS_FILE_OBJECT=1;XP_WIN;%(PreprocessorDefinitions)
-
-
-
-
- $(Platform)\$(Configuration)\$(ProjectName).lib
- %(AdditionalLibraryDirectories)
- false
-
-
- MachineX64
-
-
-
-
-
-
-
- {f6c55d93-b927-4483-bb69-15aef3dd2dff}
- false
-
-
- {87ee9da4-de1e-4448-8324-183c98dca588}
- false
-
-
- {204fa0de-305d-4414-ae2e-f195a23f390d}
- false
-
-
- {202d7a4e-760d-4d0e-afa1-d7459ced30ff}
- false
-
-
-
-
-
-
diff --git a/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.c
deleted file mode 100644
index e86eed40d6..0000000000
--- a/src/mod/legacy/languages/mod_spidermonkey/mod_spidermonkey.c
+++ /dev/null
@@ -1,3939 +0,0 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2014, Anthony Minessale II
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II
- * William King
- *
- * mod_spidermonkey.c -- Javascript Module
- *
- */
-#ifndef HAVE_CURL
-#define HAVE_CURL
-#endif
-#include "mod_spidermonkey.h"
-
-#ifdef HAVE_CURL
-#include
-#endif
-static int foo = 0;
-static jsval check_hangup_hook(struct js_session *jss, jsval * rp);
-
-SWITCH_MODULE_LOAD_FUNCTION(mod_spidermonkey_load);
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_spidermonkey_shutdown);
-SWITCH_MODULE_DEFINITION_EX(mod_spidermonkey, mod_spidermonkey_load, mod_spidermonkey_shutdown, NULL, SMODF_GLOBAL_SYMBOLS);
-
-#define METHOD_SANITY_CHECK() if (!jss || !jss->session) { \
- eval_some_js("~throw new Error(\"You must call the session.originate method before calling this method!\");", cx, obj, rval); \
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE); \
- return JS_FALSE; \
- } else check_hangup_hook(jss, NULL)
-
-#define CHANNEL_SANITY_CHECK() do { \
- if (!switch_channel_ready(channel)) { \
- eval_some_js("~throw new Error(\"Session is not active!\");", cx, obj, rval); \
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE); \
- return JS_FALSE; \
- } \
- if (!((switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag(channel, CF_EARLY_MEDIA)))) { \
- switch_channel_pre_answer(channel); \
- if (!((switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag(channel, CF_EARLY_MEDIA)))) { \
- eval_some_js("~throw new Error(\"Session is not answered!\");", cx, obj, rval); \
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE); \
- return JS_FALSE; \
- } \
- } \
- } while (foo == 1)
-
-#define CHANNEL_SANITY_CHECK_ANSWER() do { \
- if (!switch_channel_ready(channel)) { \
- eval_some_js("~throw new Error(\"Session is not active!\");", cx, obj, rval); \
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE); \
- return JS_FALSE; \
- } \
- } while (foo == 1)
-
-#define CHANNEL_MEDIA_SANITY_CHECK() do { \
- if (!switch_channel_media_ready(channel)) { \
- eval_some_js("~throw new Error(\"Session is not in media mode!\");", cx, obj, rval); \
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE); \
- return JS_FALSE; \
- } \
- } while (foo == 1)
-
-static void session_destroy(JSContext * cx, JSObject * obj);
-static JSBool session_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval);
-static JSBool session_originate(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval);
-static JSBool session_set_callerdata(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval);
-static switch_api_interface_t *js_run_interface = NULL;
-static switch_api_interface_t *jsapi_interface = NULL;
-
-struct js_env {
- size_t gStackChunkSize;
- jsuword gStackBase;
- int gExitCode;
- JSBool gQuitting;
- FILE *gErrFile;
- FILE *gOutFile;
- int stackDummy;
- JSRuntime *rt;
-};
-
-static JSClass global_class = {
- "Global", JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
-};
-
-
-static struct {
- switch_hash_t *mod_hash;
- switch_hash_t *load_hash;
- switch_memory_pool_t *pool;
-} module_manager;
-
-struct sm_loadable_module {
- char *filename;
- void *lib;
- const sm_module_interface_t *module_interface;
- spidermonkey_init_t spidermonkey_init;
-};
-typedef struct sm_loadable_module sm_loadable_module_t;
-
-typedef enum {
- S_HUP = (1 << 0),
-} session_flag_t;
-
-struct input_callback_state {
- struct js_session *session_state;
- char code_buffer[1024];
- size_t code_buffer_len;
- char ret_buffer[1024];
- int ret_buffer_len;
- int digit_count;
- JSFunction *function;
- jsval arg;
- jsval ret;
- JSContext *cx;
- JSObject *obj;
- jsrefcount saveDepth;
- void *extra;
- struct js_session *jss_a;
- struct js_session *jss_b;
- JSObject *session_obj_a;
- JSObject *session_obj_b;
-};
-
-struct fileio_obj {
- char *path;
- unsigned int flags;
- switch_file_t *fd;
- switch_memory_pool_t *pool;
- char *buf;
- switch_size_t buflen;
- int32 bufsize;
-};
-
-struct request_obj {
- const char *cmd;
- switch_core_session_t *session;
- switch_stream_handle_t *stream;
-};
-
-
-/* Request Object */
-/*********************************************************************************/
-
-static JSBool request_write(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct request_obj *ro = JS_GetPrivate(cx, obj);
-
- if (!ro) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (argc > 0) {
- char *string = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- ro->stream->write_function(ro->stream, "%s", string);
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
-}
-
-static JSBool request_add_header(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct request_obj *ro = JS_GetPrivate(cx, obj);
-
- if (!ro) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (argc > 1) {
- char *hname = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- char *hval = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- switch_event_add_header_string(ro->stream->param_event, SWITCH_STACK_BOTTOM, hname, hval);
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
-}
-
-static JSBool request_get_header(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct request_obj *ro = JS_GetPrivate(cx, obj);
-
- if (!ro) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
-
- if (argc > 0) {
- char *hname = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- char *val = switch_event_get_header(ro->stream->param_event, hname);
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val));
- return JS_TRUE;
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
-}
-
-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";
-
- if (!ro) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (argc > 0) {
- how = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- }
-
- if (!strcasecmp(how, "xml")) {
- 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);
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, xmlstr));
- free(xmlstr);
- return JS_TRUE;
- }
- } else {
- char *buf;
- switch_event_serialize(ro->stream->param_event, &buf, SWITCH_TRUE);
- if (buf) {
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
- free(buf);
- return JS_TRUE;
- }
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_FALSE;
-}
-
-static void request_destroy(JSContext * cx, JSObject * obj)
-{
-
-}
-
-enum request_tinyid {
- REQUEST_COMMAND
-};
-
-static JSFunctionSpec request_methods[] = {
- {"write", request_write, 1},
- {"getHeader", request_get_header, 1},
- {"addHeader", request_add_header, 1},
- {"dumpENV", request_dump_env, 1},
- {0}
-};
-
-static JSPropertySpec request_props[] = {
- {"command", REQUEST_COMMAND, JSPROP_READONLY | JSPROP_PERMANENT},
- {0}
-};
-
-static JSBool request_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
-{
- JSBool res = JS_TRUE;
- struct request_obj *ro = JS_GetPrivate(cx, obj);
- char *name;
- int param = 0;
-
- if (!ro) {
- *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
-
- 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);
- } else {
- return JS_TRUE;
- }
-
- switch (param) {
- case REQUEST_COMMAND:
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, ro->cmd));
- break;
- }
-
- return res;
-}
-
-JSClass request_class = {
- "Request", JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, request_getProperty, DEFAULT_SET_PROPERTY,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, request_destroy, NULL, NULL, NULL, NULL
-};
-
-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))) {
- return Request;
- }
- }
-
- return NULL;
-}
-
-struct pcre_obj {
- switch_regex_t *re;
- char *string;
- int proceed;
- int ovector[30];
- int freed;
-};
-
-/* Pcre Object */
-/*********************************************************************************/
-static JSBool pcre_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct pcre_obj *pcre_obj;
-
- if (!((pcre_obj = malloc(sizeof(*pcre_obj))))) {
- abort();
- }
- memset(pcre_obj, 0, sizeof(*pcre_obj));
- JS_SetPrivate(cx, obj, pcre_obj);
- return JS_TRUE;
-
-}
-
-static void pcre_destroy(JSContext * cx, JSObject * obj)
-{
- struct pcre_obj *pcre_obj = JS_GetPrivate(cx, obj);
-
- if (pcre_obj) {
- if (!pcre_obj->freed && pcre_obj->re) {
- switch_regex_safe_free(pcre_obj->re);
- switch_safe_free(pcre_obj->string);
- }
- switch_safe_free(pcre_obj);
- }
-}
-
-static JSBool pcre_compile(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct pcre_obj *pcre_obj = JS_GetPrivate(cx, obj);
- char *string, *regex_string;
-
- if (argc > 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,
- sizeof(pcre_obj->ovector) / sizeof(pcre_obj->ovector[0]));
- *rval = BOOLEAN_TO_JSVAL(pcre_obj->proceed ? JS_TRUE : JS_FALSE);
- } else {
- eval_some_js("~throw new Error(\"Invalid Args\");", cx, obj, rval);
- return JS_FALSE;
- }
-
- return JS_TRUE;
-}
-
-static JSBool pcre_substitute(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct pcre_obj *pcre_obj = JS_GetPrivate(cx, obj);
- char *subst_string;
- char *substituted;
-
- if (!pcre_obj->proceed) {
- 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]));
- len = (uint32_t) (strlen(pcre_obj->string) + strlen(subst_string) + 10) * pcre_obj->proceed;
- substituted = malloc(len);
- switch_assert(substituted != NULL);
- switch_perform_substitution(pcre_obj->re, pcre_obj->proceed, subst_string, pcre_obj->string, substituted, len, pcre_obj->ovector);
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, substituted));
- free(substituted);
- } else {
- eval_some_js("~throw new Error(\"Invalid Args\");", cx, obj, rval);
- return JS_FALSE;
- }
-
- return JS_TRUE;
-}
-
-enum pcre_tinyid {
- PCRE_READY
-};
-
-static JSFunctionSpec pcre_methods[] = {
- {"compile", pcre_compile, 2},
- {"substitute", pcre_substitute, 2},
- {0}
-};
-
-static JSPropertySpec pcre_props[] = {
- {"ready", PCRE_READY, JSPROP_READONLY | JSPROP_PERMANENT},
- {0}
-};
-
-static JSBool pcre_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
-{
- JSBool res = JS_TRUE;
- struct pcre_obj *pcre_obj = JS_GetPrivate(cx, obj);
- char *name;
- int param = 0;
-
- if (!pcre_obj) {
- *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
-
- 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);
- } else {
- return JS_TRUE;
- }
-
- switch (param) {
- case PCRE_READY:
- *vp = BOOLEAN_TO_JSVAL(JS_TRUE);
- break;
- }
-
- return res;
-}
-
-JSClass pcre_class = {
- "PCRE", JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, pcre_getProperty, DEFAULT_SET_PROPERTY,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, pcre_destroy, NULL, NULL, NULL,
- pcre_construct
-};
-
-struct event_obj {
- switch_event_t *event;
- int freed;
-};
-
-/* Event Object */
-/*********************************************************************************/
-static JSBool event_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- if (argc > 0) {
- switch_event_t *event;
- struct event_obj *eo;
- switch_event_types_t etype;
- char *ename = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
-
- if ((eo = malloc(sizeof(*eo)))) {
-
- if (switch_name_event(ename, &etype) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown event %s\n", ename);
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (etype == SWITCH_EVENT_CUSTOM) {
- char *subclass_name;
- if (argc > 1) {
- subclass_name = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- } else {
- subclass_name = "none";
- }
-
- if (switch_event_create_subclass(&event, etype, subclass_name) != SWITCH_STATUS_SUCCESS) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- } else {
- if (switch_event_create(&event, etype) != SWITCH_STATUS_SUCCESS) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
- }
-
- eo->event = event;
- eo->freed = 0;
-
- JS_SetPrivate(cx, obj, eo);
- return JS_TRUE;
- }
- }
-
- return JS_FALSE;
-}
-
-static void event_destroy(JSContext * cx, JSObject * obj)
-{
- struct event_obj *eo = JS_GetPrivate(cx, obj);
-
- if (eo) {
- if (!eo->freed && eo->event) {
- switch_event_destroy(&eo->event);
- }
- switch_safe_free(eo);
- }
-}
-
-static JSBool event_add_header(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct event_obj *eo = JS_GetPrivate(cx, obj);
-
- if (!eo || eo->freed) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (argc > 1) {
- char *hname = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- char *hval = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- switch_event_add_header_string(eo->event, SWITCH_STACK_BOTTOM, hname, hval);
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
-}
-
-static JSBool event_get_header(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct event_obj *eo = JS_GetPrivate(cx, obj);
-
- if (!eo) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (argc > 0) {
- char *hname = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- char *val = switch_event_get_header(eo->event, hname);
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val));
- return JS_TRUE;
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
-}
-
-static JSBool event_add_body(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct event_obj *eo = JS_GetPrivate(cx, obj);
-
- if (!eo || eo->freed) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (argc > 0) {
- char *body = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- switch_event_add_body(eo->event, "%s", body);
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
-}
-
-static JSBool event_get_body(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct event_obj *eo = JS_GetPrivate(cx, obj);
-
- if (!eo) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_event_get_body(eo->event)));
-
- return JS_TRUE;
-}
-
-static JSBool event_get_type(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct event_obj *eo = JS_GetPrivate(cx, obj);
-
- if (!eo) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_event_name(eo->event->event_id)));
-
- return JS_TRUE;
-}
-
-static JSBool event_serialize(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct event_obj *eo = JS_GetPrivate(cx, obj);
- char *buf;
- uint8_t isxml = 0, isjson = 0;
-
- if (!eo) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (argc > 0) {
- char *arg = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- if (!strcasecmp(arg, "xml")) {
- isxml++;
- } else if (!strcasecmp(arg, "json")) {
- isjson++;
- }
- }
-
- if (isxml) {
- switch_xml_t xml;
- char *xmlstr;
- if ((xml = switch_event_xmlize(eo->event, SWITCH_VA_NONE))) {
- xmlstr = switch_xml_toxml(xml, SWITCH_FALSE);
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, xmlstr));
- switch_xml_free(xml);
- free(xmlstr);
- } else {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- }
- } else if (isjson) {
- if (switch_event_serialize_json(eo->event, &buf) == SWITCH_STATUS_SUCCESS) {
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
- switch_safe_free(buf);
- }
- } else {
- if (switch_event_serialize(eo->event, &buf, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
- switch_safe_free(buf);
- }
- }
-
- return JS_TRUE;
-}
-
-static JSBool event_fire(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct event_obj *eo = JS_GetPrivate(cx, obj);
-
- if (eo) {
- switch_event_fire(&eo->event);
- JS_SetPrivate(cx, obj, NULL);
- switch_safe_free(eo);
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
-}
-
-
-static JSBool event_chat_execute(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct event_obj *eo = JS_GetPrivate(cx, obj);
-
- if (eo) {
- if (argc > 0) {
- char *app = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- char *arg = NULL;
-
- if (argc > 1) {
- arg = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- }
-
- switch_core_execute_chat_app(eo->event, app, arg);
-
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
- }
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_FALSE;
-}
-
-static JSBool event_destroy_(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct event_obj *eo = JS_GetPrivate(cx, obj);
-
- if (eo) {
- if (!eo->freed) {
- switch_event_destroy(&eo->event);
- }
- JS_SetPrivate(cx, obj, NULL);
- switch_safe_free(eo);
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
-}
-
-enum event_tinyid {
- EVENT_READY
-};
-
-static JSFunctionSpec event_methods[] = {
- {"addHeader", event_add_header, 1},
- {"getHeader", event_get_header, 1},
- {"addBody", event_add_body, 1},
- {"getBody", event_get_body, 1},
- {"getType", event_get_type, 1},
- {"serialize", event_serialize, 0},
- {"fire", event_fire, 0},
- {"chatExecute", event_chat_execute, 0},
- {"destroy", event_destroy_, 0},
- {0}
-};
-
-static JSPropertySpec event_props[] = {
- {"ready", EVENT_READY, JSPROP_READONLY | JSPROP_PERMANENT},
- {0}
-};
-
-static JSBool event_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
-{
- JSBool res = JS_TRUE;
- switch_event_t *event = JS_GetPrivate(cx, obj);
- char *name;
- int param = 0;
-
- if (!event) {
- *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- 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);
- } else {
- return JS_TRUE;
- }
-
- switch (param) {
- case EVENT_READY:
- *vp = BOOLEAN_TO_JSVAL(JS_TRUE);
- break;
- }
-
- return res;
-}
-
-JSClass event_class = {
- "Event", JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, event_getProperty, DEFAULT_SET_PROPERTY,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, event_destroy, NULL, NULL, NULL,
- event_construct
-};
-
-/* Dtmf Object */
-/*********************************************************************************/
-static JSBool dtmf_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- switch_dtmf_t *dtmf;
- int32 duration = switch_core_default_dtmf_duration(0);
-
- if (argc <= 0) {
- eval_some_js("~throw new Error(\"Invalid Args\");", cx, obj, rval);
- return JS_FALSE;
- }
-
- if (argc > 1) {
- JS_ValueToInt32(cx, argv[1], &duration);
- if (duration <= 0) {
- duration = switch_core_default_dtmf_duration(0);
- }
- }
-
- if ((dtmf = malloc(sizeof(*dtmf)))) {
- JS_SetPrivate(cx, obj, dtmf);
- return JS_TRUE;
- }
-
- return JS_FALSE;
-}
-
-static void dtmf_destroy(JSContext * cx, JSObject * obj)
-{
- switch_dtmf_t *dtmf = JS_GetPrivate(cx, obj);
-
- if (dtmf) {
- switch_safe_free(dtmf);
- JS_SetPrivate(cx, obj, NULL);
- }
-}
-
-enum dtmf_tinyid {
- DTMF_DIGIT, DTMF_DURATION
-};
-
-static JSFunctionSpec dtmf_methods[] = {
- {0}
-};
-
-
-static JSPropertySpec dtmf_props[] = {
- {"digit", DTMF_DIGIT, JSPROP_READONLY | JSPROP_PERMANENT},
- {"duration", DTMF_DURATION, JSPROP_READONLY | JSPROP_PERMANENT},
- {0}
-};
-
-static JSBool dtmf_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
-{
- JSBool res = JS_TRUE;
- switch_dtmf_t *dtmf = JS_GetPrivate(cx, obj);
- char *name;
- int param = 0;
-
- if (!dtmf) {
- *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- 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);
- } else {
- return JS_TRUE;
- }
-
- switch (param) {
- case DTMF_DIGIT:
- {
- char tmp[2] = { dtmf->digit, '\0' };
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, tmp));
- }
- break;
-
- case DTMF_DURATION:
- {
- *vp = INT_TO_JSVAL((int) dtmf->duration);
- }
- break;
- }
-
- return res;
-}
-
-JSClass dtmf_class = {
- "DTMF", JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, dtmf_getProperty, DEFAULT_SET_PROPERTY,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, dtmf_destroy, NULL, NULL, NULL,
- dtmf_construct
-};
-
-static void js_error(JSContext * cx, const char *message, JSErrorReport * report)
-{
- const char *filename = __FILE__;
- int line = __LINE__;
- const char *text = "";
- char *ex = "";
-
- if (message && report) {
- if (report->filename) {
- filename = report->filename;
- }
- line = report->lineno;
- if (report->linebuf) {
- text = report->linebuf;
- ex = "near ";
- }
- }
-
- if (!message) {
- message = "(N/A)";
- }
-
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, filename, modname, line, NULL, SWITCH_LOG_ERROR, "%s %s%s\n", ex, message, text);
-}
-
-static switch_status_t sm_load_file(char *filename)
-{
- sm_loadable_module_t *module = NULL;
- switch_dso_lib_t dso = NULL;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- switch_loadable_module_function_table_t *function_handle = NULL;
- spidermonkey_init_t spidermonkey_init = NULL;
- const sm_module_interface_t *module_interface = NULL, *mp;
- char *derr = NULL;
- const char *err = NULL;
-
- switch_assert(filename != NULL);
-
- if (!(dso = switch_dso_open(filename, 1, &derr))) {
- status = SWITCH_STATUS_FALSE;
- }
-
- if (derr || status != SWITCH_STATUS_SUCCESS) {
- err = derr;
- goto err;
- }
-
- function_handle = switch_dso_data_sym(dso, "spidermonkey_init", &derr);
-
- if (!function_handle || derr) {
- status = SWITCH_STATUS_FALSE;
- err = derr;
- goto err;
- }
-
- spidermonkey_init = (spidermonkey_init_t) (intptr_t) function_handle;
-
- if (spidermonkey_init == NULL) {
- err = "Cannot Load";
- goto err;
- }
-
- if (spidermonkey_init(&module_interface) != SWITCH_STATUS_SUCCESS) {
- err = "Module load routine returned an error";
- goto err;
- }
-
- if (!(module = (sm_loadable_module_t *) switch_core_permanent_alloc(sizeof(*module)))) {
- err = "Could not allocate memory\n";
- }
-
- err:
-
- if (err || !module) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Loading module %s\n**%s**\n", filename, switch_str_nil(err));
- switch_safe_free(derr);
- return SWITCH_STATUS_GENERR;
- }
-
- module->filename = switch_core_permanent_strdup(filename);
- module->spidermonkey_init = spidermonkey_init;
- module->module_interface = module_interface;
-
- module->lib = dso;
-
- switch_core_hash_insert(module_manager.mod_hash, (char *) module->filename, (void *) module);
-
- for (mp = module->module_interface; mp; mp = mp->next) {
- switch_core_hash_insert(module_manager.load_hash, (char *) mp->name, (void *) mp);
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Successfully Loaded [%s]\n", module->filename);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t sm_load_module(const char *dir, const char *fname)
-{
- switch_size_t len = 0;
- char *path;
- char *file;
-
-#ifdef WIN32
- const char *ext = ".dll";
-#else
- const char *ext = ".so";
-#endif
-
- if ((file = switch_core_strdup(module_manager.pool, fname)) == 0) {
- return SWITCH_STATUS_FALSE;
- }
-
- if (*file == '/') {
- path = switch_core_strdup(module_manager.pool, file);
- } else {
- if (strchr(file, '.')) {
- len = strlen(dir);
- len += strlen(file);
- len += 4;
- path = (char *) switch_core_alloc(module_manager.pool, len);
- switch_snprintf(path, len, "%s%s%s", dir, SWITCH_PATH_SEPARATOR, file);
- } else {
- len = strlen(dir);
- len += strlen(file);
- len += 8;
- path = (char *) switch_core_alloc(module_manager.pool, len);
- switch_snprintf(path, len, "%s%s%s%s", dir, SWITCH_PATH_SEPARATOR, file, ext);
- }
- }
-
- return sm_load_file(path);
-}
-
-static switch_status_t load_modules(void)
-{
- char *cf = "spidermonkey.conf";
- switch_xml_t cfg, xml;
- unsigned int count = 0;
-
-#ifdef WIN32
- const char *ext = ".dll";
- const char *EXT = ".DLL";
-#elif defined (MACOSX) || defined (DARWIN)
- const char *ext = ".dylib";
- const char *EXT = ".DYLIB";
-#else
- const char *ext = ".so";
- const char *EXT = ".SO";
-#endif
-
- memset(&module_manager, 0, sizeof(module_manager));
- switch_core_new_memory_pool(&module_manager.pool);
-
- switch_core_hash_init(&module_manager.mod_hash);
- switch_core_hash_init(&module_manager.load_hash);
-
- if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
- switch_xml_t mods, ld;
-
- if ((mods = switch_xml_child(cfg, "modules"))) {
- for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
- const char *val = switch_xml_attr_soft(ld, "module");
- if (!zstr(val) && strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
- continue;
- }
- sm_load_module(SWITCH_GLOBAL_dirs.mod_dir, val);
- count++;
- }
- }
- switch_xml_free(xml);
-
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Open of %s failed\n", cf);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t init_js(struct js_env *env)
-{
-
- memset(env, 0, sizeof(*env));
- env->gQuitting = JS_FALSE;
- env->gErrFile = NULL;
- env->gOutFile = NULL;
- env->gStackChunkSize = 8192;
- env->gStackBase = (jsuword) & env->stackDummy;
- env->gErrFile = stderr;
- env->gOutFile = stdout;
-
- if (!(env->rt = JS_NewRuntime(64L * 1024L * 1024L))) {
- return SWITCH_STATUS_FALSE;
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-JSObject *new_js_event(switch_event_t *event, char *name, JSContext * cx, JSObject * obj)
-{
- struct event_obj *eo;
- JSObject *Event = NULL;
-
- if ((eo = malloc(sizeof(*eo)))) {
- eo->event = event;
- eo->freed = 1;
- if ((Event = JS_DefineObject(cx, obj, name, &event_class, NULL, 0))) {
- if ((JS_SetPrivate(cx, Event, eo) && JS_DefineProperties(cx, Event, event_props) && JS_DefineFunctions(cx, Event, event_methods))) {
- }
- } else {
- free(eo);
- }
- }
- return Event;
-}
-
-JSObject *new_js_dtmf(switch_dtmf_t *dtmf, char *name, JSContext * cx, JSObject * obj)
-{
- JSObject *DTMF = NULL;
- switch_dtmf_t *ddtmf;
-
- if ((ddtmf = malloc(sizeof(*ddtmf)))) {
- *ddtmf = *dtmf;
- if ((DTMF = JS_DefineObject(cx, obj, name, &dtmf_class, NULL, 0))) {
- JS_SetPrivate(cx, DTMF, ddtmf);
- JS_DefineProperties(cx, DTMF, dtmf_props);
- JS_DefineFunctions(cx, DTMF, dtmf_methods);
- } else {
- free(ddtmf);
- }
- }
- return DTMF;
-}
-
-#define MAX_STACK_DEPTH 2
-
-static switch_status_t js_common_callback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
-{
- switch_event_t *event = NULL;
- struct input_callback_state *cb_state = buf;
- struct js_session *jss = cb_state->session_state;
- uintN argc = 0;
- jsval argv[4];
- JSObject *Event = NULL;
- jsval ret, nval, *rval = &nval;
- JSContext *cx = cb_state->cx;
- JSObject *obj = cb_state->obj;
- switch_uuid_t uuid;
- char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
- char var_name[SWITCH_UUID_FORMATTED_LENGTH + 25];
- char *p;
- switch_status_t status = SWITCH_STATUS_FALSE;
-
- if (!jss || !jss->session) {
- return SWITCH_STATUS_FALSE;
- }
-
- if (++jss->stack_depth > MAX_STACK_DEPTH) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Maximum recursive callback limit %d reached.\n", MAX_STACK_DEPTH);
- jss->stack_depth--;
- return SWITCH_STATUS_FALSE;
- }
-
- switch_uuid_get(&uuid);
- switch_uuid_format(uuid_str, &uuid);
-
- switch_snprintf(var_name, sizeof(var_name), "__event_%s", uuid_str);
- for (p = var_name; p && *p; p++) {
- if (*p == '-') {
- *p = '_';
- }
- }
-
- JS_ResumeRequest(cb_state->cx, cb_state->saveDepth);
- METHOD_SANITY_CHECK();
-
- if (cb_state->jss_a && cb_state->jss_a->session && cb_state->jss_a->session == session) {
- argv[argc++] = OBJECT_TO_JSVAL(cb_state->session_obj_a);
- } else if (cb_state->jss_b && cb_state->jss_b->session && cb_state->jss_b->session == session) {
- argv[argc++] = OBJECT_TO_JSVAL(cb_state->session_obj_b);
- } else {
- argv[argc++] = OBJECT_TO_JSVAL(cb_state->session_state->obj);
- }
-
- switch (itype) {
- case SWITCH_INPUT_TYPE_EVENT:
- if ((event = (switch_event_t *) input)) {
- if ((Event = new_js_event(event, var_name, cb_state->cx, cb_state->obj))) {
- argv[argc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(cb_state->cx, "event"));
- argv[argc++] = OBJECT_TO_JSVAL(Event);
- }
- }
- if (!Event) {
- goto done;
- }
- break;
- case SWITCH_INPUT_TYPE_DTMF:
- {
- switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
-
- if (dtmf) {
- if ((Event = new_js_dtmf(dtmf, var_name, cb_state->cx, cb_state->obj))) {
- argv[argc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(cb_state->cx, "dtmf"));
- argv[argc++] = OBJECT_TO_JSVAL(Event);
- } else {
- goto done;
- }
- }
- }
- break;
- }
-
- if (cb_state->arg) {
- argv[argc++] = cb_state->arg;
- }
-
- check_hangup_hook(jss, &ret);
-
- if (ret == JS_TRUE) {
- JS_CallFunction(cb_state->cx, cb_state->obj, cb_state->function, argc, argv, &cb_state->ret);
- }
-
- status = SWITCH_STATUS_SUCCESS;
- done:
- cb_state->saveDepth = JS_SuspendRequest(cb_state->cx);
- jss->stack_depth--;
- return status;
-}
-
-static switch_status_t js_stream_input_callback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
-{
- char *ret;
- switch_status_t status;
- struct input_callback_state *cb_state = buf;
- switch_file_handle_t *fh = cb_state->extra;
- //struct js_session *jss = cb_state->session_state;
-
- if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) {
- return SWITCH_STATUS_FALSE;
- }
-
- if ((status = js_common_callback(session, input, itype, buf, buflen)) != SWITCH_STATUS_SUCCESS) {
- return status;
- }
-
- if ((ret = JS_GetStringBytes(JS_ValueToString(cb_state->cx, cb_state->ret)))) {
- if (!strncasecmp(ret, "speed", 5)) {
- char *p;
-
- if ((p = strchr(ret, ':'))) {
- p++;
- if (*p == '+' || *p == '-') {
- int step;
- if (!(step = atoi(p))) {
- step = 1;
- }
- fh->speed += step;
- } else {
- int speed = atoi(p);
- fh->speed = speed;
- }
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_FALSE;
- } else if (!strncasecmp(ret, "volume", 6)) {
- char *p;
-
- if ((p = strchr(ret, ':'))) {
- p++;
- if (*p == '+' || *p == '-') {
- int step;
- if (!(step = atoi(p))) {
- step = 1;
- }
- fh->vol += step;
- } else {
- int vol = atoi(p);
- fh->vol = vol;
- }
- return SWITCH_STATUS_SUCCESS;
- }
-
- if (fh->vol) {
- switch_normalize_volume(fh->vol);
- }
-
- return SWITCH_STATUS_FALSE;
- } else if (!strcasecmp(ret, "pause")) {
- if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
- switch_clear_flag(fh, SWITCH_FILE_PAUSE);
- } else {
- switch_set_flag(fh, SWITCH_FILE_PAUSE);
- }
- return SWITCH_STATUS_SUCCESS;
- } else if (!strcasecmp(ret, "truncate")) {
- switch_core_file_truncate(fh, 0);
- } else if (!strcasecmp(ret, "restart")) {
- uint32_t pos = 0;
- fh->speed = 0;
- switch_core_file_seek(fh, &pos, 0, SEEK_SET);
- return SWITCH_STATUS_SUCCESS;
- } else if (!strncasecmp(ret, "seek", 4)) {
- //switch_codec_t *codec;
- uint32_t samps = 0;
- uint32_t pos = 0;
- char *p;
- //codec = switch_core_session_get_read_codec(jss->session);
-
- if ((p = strchr(ret, ':'))) {
- p++;
- if (*p == '+' || *p == '-') {
- int step;
- if (!(step = atoi(p))) {
- step = 1000;
- }
- if (step > 0) {
- samps = step * (fh->native_rate / 1000);
- switch_core_file_seek(fh, &pos, samps, SEEK_CUR);
- } else {
- samps = abs(step) * (fh->native_rate / 1000);
- switch_core_file_seek(fh, &pos, fh->pos - samps, SEEK_SET);
- }
- } else {
- samps = atoi(p) * (fh->native_rate / 1000);
- switch_core_file_seek(fh, &pos, samps, SEEK_SET);
- }
- }
-
- return SWITCH_STATUS_SUCCESS;
- }
-
- if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_BREAK;
-
- }
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t js_record_input_callback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
-{
- char *ret;
- switch_status_t status;
- struct input_callback_state *cb_state = buf;
- switch_file_handle_t *fh = cb_state->extra;
-
- if ((status = js_common_callback(session, input, itype, buf, buflen)) != SWITCH_STATUS_SUCCESS) {
- return status;
- }
-
- if ((ret = JS_GetStringBytes(JS_ValueToString(cb_state->cx, cb_state->ret)))) {
- if (!strcasecmp(ret, "pause")) {
- if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
- switch_clear_flag(fh, SWITCH_FILE_PAUSE);
- } else {
- switch_set_flag(fh, SWITCH_FILE_PAUSE);
- }
- return SWITCH_STATUS_SUCCESS;
- } else if (!strcasecmp(ret, "restart")) {
- unsigned int pos = 0;
- fh->speed = 0;
- switch_core_file_seek(fh, &pos, 0, SEEK_SET);
- return SWITCH_STATUS_SUCCESS;
- }
-
- if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_BREAK;
-
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t js_collect_input_callback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
-{
- char *ret;
- switch_status_t status;
- struct input_callback_state *cb_state = buf;
-
- if ((status = js_common_callback(session, input, itype, buf, buflen)) != SWITCH_STATUS_SUCCESS) {
- return status;
- }
-
- if ((ret = JS_GetStringBytes(JS_ValueToString(cb_state->cx, cb_state->ret)))) {
- if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
- return SWITCH_STATUS_SUCCESS;
- }
- }
-
- return SWITCH_STATUS_BREAK;
-}
-
-static JSBool session_flush_digits(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_MEDIA_SANITY_CHECK();
-
- switch_channel_flush_dtmf(switch_core_session_get_channel(jss->session));
-
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
-}
-
-static JSBool session_flush_events(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_event_t *event;
-
- if (!jss || !jss->session) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- while (switch_core_session_dequeue_event(jss->session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
- switch_event_destroy(&event);
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
-
-}
-
-static JSBool session_recordfile(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
- char *file_name = NULL;
- void *bp = NULL;
- int len = 0;
- switch_input_callback_function_t dtmf_func = NULL;
- struct input_callback_state cb_state = { 0 };
- switch_file_handle_t fh = { 0 };
- JSFunction *function;
- int32 limit = 0;
- switch_input_args_t args = { 0 };
- jsval ret = JS_TRUE;
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_SANITY_CHECK();
-
- CHANNEL_MEDIA_SANITY_CHECK();
-
- if (argc > 0) {
- file_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- if (zstr(file_name)) {
- return JS_FALSE;
- }
- }
- if (argc > 1) {
- if ((function = JS_ValueToFunction(cx, argv[1]))) {
- memset(&cb_state, 0, sizeof(cb_state));
- cb_state.session_state = jss;
- cb_state.function = function;
- cb_state.cx = cx;
- cb_state.obj = obj;
- if (argc > 2) {
- cb_state.arg = argv[2];
- }
-
- dtmf_func = js_record_input_callback;
- bp = &cb_state;
- len = sizeof(cb_state);
- }
-
- if (argc > 3) {
- JS_ValueToInt32(cx, argv[3], &limit);
- }
-
- if (argc > 4) {
- int32 thresh;
- JS_ValueToInt32(cx, argv[4], &thresh);
- fh.thresh = thresh;
- }
-
- if (argc > 5) {
- int32 silence_hits;
- JS_ValueToInt32(cx, argv[5], &silence_hits);
- fh.silence_hits = silence_hits;
- }
- }
-
- cb_state.extra = &fh;
- cb_state.ret = BOOLEAN_TO_JSVAL(JS_FALSE);
- cb_state.saveDepth = JS_SuspendRequest(cx);
- args.input_callback = dtmf_func;
- args.buf = bp;
- args.buflen = len;
-
- switch_ivr_record_file(jss->session, &fh, file_name, &args, limit);
- JS_ResumeRequest(cx, cb_state.saveDepth);
- check_hangup_hook(jss, &ret);
- *rval = cb_state.ret;
-
- return (JSBool)ret;
-}
-
-static JSBool session_collect_input(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
- void *bp = NULL;
- int len = 0;
- int32 abs_timeout = 0;
- int32 digit_timeout = 0;
-
- switch_input_callback_function_t dtmf_func = NULL;
- struct input_callback_state cb_state = { 0 };
- JSFunction *function;
- switch_input_args_t args = { 0 };
- jsval ret = JS_TRUE;
-
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_SANITY_CHECK();
- CHANNEL_MEDIA_SANITY_CHECK();
-
- if (argc > 0) {
- if ((function = JS_ValueToFunction(cx, argv[0]))) {
- memset(&cb_state, 0, sizeof(cb_state));
- cb_state.function = function;
-
- if (argc > 1) {
- cb_state.arg = argv[1];
- }
-
- cb_state.session_state = jss;
- cb_state.cx = cx;
- cb_state.obj = obj;
- dtmf_func = js_collect_input_callback;
- bp = &cb_state;
- len = sizeof(cb_state);
- }
- }
-
- if (argc == 3) {
- JS_ValueToInt32(jss->cx, argv[2], &abs_timeout);
- } else if (argc > 3) {
- JS_ValueToInt32(jss->cx, argv[2], &digit_timeout);
- JS_ValueToInt32(jss->cx, argv[3], &abs_timeout);
- }
-
- cb_state.saveDepth = JS_SuspendRequest(cx);
- args.input_callback = dtmf_func;
- args.buf = bp;
- args.buflen = len;
-
- switch_ivr_collect_digits_callback(jss->session, &args, digit_timeout, abs_timeout);
- JS_ResumeRequest(cx, cb_state.saveDepth);
- check_hangup_hook(jss, &ret);
- *rval = cb_state.ret;
-
- return (JSBool)ret;
-}
-
-/* session.sayphrase(phrase_name, phrase_data, language, dtmf_callback, dtmf_callback_args)*/
-
-static JSBool session_sayphrase(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
- char *phrase_name = NULL;
- char *phrase_data = NULL;
- char *phrase_lang = NULL;
- char *tmp = NULL;
- //char *input_callback = NULL;
- void *bp = NULL;
- int len = 0;
- switch_input_callback_function_t dtmf_func = NULL;
- struct input_callback_state cb_state = { 0 };
- JSFunction *function;
- switch_input_args_t args = { 0 };
- jsval ret = JS_TRUE;
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_SANITY_CHECK();
- CHANNEL_MEDIA_SANITY_CHECK();
-
- if (argc > 0) {
- phrase_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- if (zstr(phrase_name)) {
- return JS_FALSE;
- }
- } else {
- return JS_FALSE;
- }
-
- if (argc > 1) {
- phrase_data = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- }
-
- if (argc > 2) {
- tmp = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
- if (!zstr(tmp)) {
- phrase_lang = tmp;
- }
- }
-
- if (argc > 3) {
- if ((function = JS_ValueToFunction(cx, argv[3]))) {
- memset(&cb_state, 0, sizeof(cb_state));
- cb_state.function = function;
-
- if (argc > 4) {
- cb_state.arg = argv[4];
- }
-
- cb_state.session_state = jss;
- cb_state.cx = cx;
- cb_state.obj = obj;
- dtmf_func = js_collect_input_callback;
- bp = &cb_state;
- len = sizeof(cb_state);
- }
- }
-
- cb_state.ret = BOOLEAN_TO_JSVAL(JS_FALSE);
- cb_state.saveDepth = JS_SuspendRequest(cx);
- args.input_callback = dtmf_func;
- args.buf = bp;
- args.buflen = len;
-
- switch_ivr_phrase_macro(jss->session, phrase_name, phrase_data, phrase_lang, &args);
- JS_ResumeRequest(cx, cb_state.saveDepth);
- check_hangup_hook(jss, &ret);
- *rval = cb_state.ret;
-
- return (JSBool)ret;
-}
-
-static jsval check_hangup_hook(struct js_session *jss, jsval * rp)
-{
- jsval argv[3] = { 0 };
- int argc = 0;
- jsval ret = JS_TRUE;
- char *resp;
-
- if (jss && !jss->check_state && jss->on_hangup && (jss->hook_state == CS_HANGUP || jss->hook_state == CS_ROUTING)) {
- jss->check_state++;
- argv[argc++] = OBJECT_TO_JSVAL(jss->obj);
- if (jss->hook_state == CS_HANGUP) {
- argv[argc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(jss->cx, "hangup"));
- } else {
- argv[argc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(jss->cx, "transfer"));
- }
- JS_CallFunction(jss->cx, jss->obj, jss->on_hangup, argc, argv, &ret);
- resp = JS_GetStringBytes(JS_ValueToString(jss->cx, ret));
- if (!zstr(resp)) {
- ret = !strcasecmp(resp, "exit") ? JS_FALSE : JS_TRUE;
- }
- }
-
- if (rp) {
- *rp = ret;
- }
-
- return ret;
-}
-
-static switch_status_t hanguphook(switch_core_session_t *session)
-{
- switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_channel_state_t state = switch_channel_get_state(channel);
- struct js_session *jss = NULL;
-
- if (state == CS_HANGUP || state == CS_ROUTING) {
- if ((jss = switch_channel_get_private(channel, "jss"))) {
- jss->hook_state = state;
- jss->check_state = 0;
- }
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static JSBool session_hanguphook(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- JSFunction *function;
- struct js_session *jss;
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
-
- if ((jss = JS_GetPrivate(cx, obj)) && jss->session) {
- if (argc > 0) {
- if ((function = JS_ValueToFunction(cx, argv[0]))) {
- switch_channel_t *channel = switch_core_session_get_channel(jss->session);
- jss->on_hangup = function;
- jss->hook_state = switch_channel_get_state(channel);
- switch_channel_set_private(channel, "jss", jss);
- switch_core_event_hook_add_state_change(jss->session, hanguphook);
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- }
- }
- }
-
- return JS_TRUE;
-}
-
-static JSBool session_streamfile(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
- char *file_name = NULL;
- //char *input_callback = NULL;
- void *bp = NULL;
- int len = 0;
- switch_input_callback_function_t dtmf_func = NULL;
- struct input_callback_state cb_state = { 0 };
- switch_file_handle_t fh = { 0 };
- JSFunction *function;
- switch_input_args_t args = { 0 };
- const char *prebuf;
- char posbuf[35] = "";
- jsval ret = JS_TRUE;
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_SANITY_CHECK();
- CHANNEL_MEDIA_SANITY_CHECK();
-
- if (argc > 0) {
- file_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- if (zstr(file_name)) {
- return JS_FALSE;
- }
- }
-
- if (argc > 1) {
- if ((function = JS_ValueToFunction(cx, argv[1]))) {
- memset(&cb_state, 0, sizeof(cb_state));
- cb_state.function = function;
-
- if (argc > 2) {
- cb_state.arg = argv[2];
- }
-
- cb_state.session_state = jss;
- cb_state.cx = cx;
- cb_state.obj = obj;
- dtmf_func = js_stream_input_callback;
- bp = &cb_state;
- len = sizeof(cb_state);
- }
- }
-
- if (argc > 3) {
- int32 samps;
- 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;
- }
- }
-
- cb_state.extra = &fh;
- cb_state.ret = BOOLEAN_TO_JSVAL(JS_FALSE);
- cb_state.saveDepth = JS_SuspendRequest(cx);
- args.input_callback = dtmf_func;
- args.buf = bp;
- args.buflen = len;
- switch_ivr_play_file(jss->session, &fh, file_name, &args);
- JS_ResumeRequest(cx, cb_state.saveDepth);
- check_hangup_hook(jss, &ret);
- *rval = cb_state.ret;
-
- switch_snprintf(posbuf, sizeof(posbuf), "%u", fh.offset_pos);
- switch_channel_set_variable(channel, "last_file_position", posbuf);
-
- return (JSBool)ret;
-}
-
-
-
-static JSBool session_sleep(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
- void *bp = NULL;
- int len = 0;
- switch_input_callback_function_t dtmf_func = NULL;
- struct input_callback_state cb_state = { 0 };
- JSFunction *function;
- switch_input_args_t args = { 0 };
- int32 ms = 0;
- jsval ret = JS_TRUE;
- int32 sync = 0;
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_SANITY_CHECK();
- CHANNEL_MEDIA_SANITY_CHECK();
-
- if (argc > 0) {
- JS_ValueToInt32(cx, argv[0], &ms);
- }
-
- if (ms <= 0) {
- return JS_FALSE;
- }
-
- if (argc > 1) {
- if ((function = JS_ValueToFunction(cx, argv[1]))) {
- memset(&cb_state, 0, sizeof(cb_state));
- cb_state.function = function;
-
- if (argc > 2) {
- cb_state.arg = argv[2];
- }
-
- cb_state.session_state = jss;
- cb_state.cx = cx;
- cb_state.obj = obj;
- dtmf_func = js_stream_input_callback;
- bp = &cb_state;
- len = sizeof(cb_state);
- }
- }
-
- if (argc > 2) {
- JS_ValueToInt32(cx, argv[2], &sync);
- }
-
- cb_state.ret = BOOLEAN_TO_JSVAL(JS_FALSE);
- cb_state.saveDepth = JS_SuspendRequest(cx);
- args.input_callback = dtmf_func;
- args.buf = bp;
- args.buflen = len;
- switch_ivr_sleep(jss->session, ms, sync, &args);
- JS_ResumeRequest(cx, cb_state.saveDepth);
- check_hangup_hook(jss, &ret);
- *rval = cb_state.ret;
-
- return (JSBool)ret;
-}
-
-static JSBool session_set_variable(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
-
- METHOD_SANITY_CHECK();
-
- channel = switch_core_session_get_channel(jss->session);
-
- if (argc > 1) {
- char *var, *val;
-
- var = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- val = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- switch_channel_set_variable_var_check(channel, var, val, SWITCH_FALSE);
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- } else {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- }
-
- return JS_TRUE;
-}
-
-static JSBool session_get_variable(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
-
- METHOD_SANITY_CHECK();
-
- channel = switch_core_session_get_channel(jss->session);
-
- if (argc > 0) {
- const char *var, *val;
-
- var = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- val = switch_channel_get_variable(channel, var);
-
- if (val) {
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val));
- } else {
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, ""));
- }
- } else {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- }
-
- return JS_TRUE;
-}
-
-static void destroy_speech_engine(struct js_session *jss)
-{
- if (jss->speech) {
- switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
- switch_core_codec_destroy(&jss->speech->codec);
- switch_core_speech_close(&jss->speech->sh, &flags);
- jss->speech = NULL;
- }
-}
-
-static switch_status_t init_speech_engine(struct js_session *jss, char *engine, char *voice)
-{
- switch_codec_t *read_codec;
- switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
- uint32_t rate = 0, channels;
- int interval = 0;
-
- read_codec = switch_core_session_get_read_codec(jss->session);
- rate = read_codec->implementation->actual_samples_per_second;
- interval = read_codec->implementation->microseconds_per_packet / 1000;
- channels = read_codec->implementation->number_of_channels;
-
- if (switch_core_codec_init(&jss->speech->codec,
- "L16",
- NULL,
- rate,
- interval,
- 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
- switch_core_session_get_pool(jss->session)) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Success L16@%uhz 1 channel %dms\n", rate, interval);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n", rate, interval);
- return SWITCH_STATUS_FALSE;
- }
-
- if (switch_core_speech_open(&jss->speech->sh, engine, voice, rate, interval, channels,
- &flags, switch_core_session_get_pool(jss->session)) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid TTS module!\n");
- switch_core_codec_destroy(&jss->speech->codec);
- return SWITCH_STATUS_FALSE;
- }
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static JSBool session_speak(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
- char *tts_name = NULL;
- char *voice_name = NULL;
- char *text = NULL;
- void *bp = NULL;
- int len = 0;
- struct input_callback_state cb_state = { 0 };
- switch_input_callback_function_t dtmf_func = NULL;
- JSFunction *function;
- switch_input_args_t args = { 0 };
- jsval ret = JS_TRUE;
-
- METHOD_SANITY_CHECK();
-
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_SANITY_CHECK();
- CHANNEL_MEDIA_SANITY_CHECK();
-
- if (argc < 3) {
- return JS_FALSE;
- }
-
- tts_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- voice_name = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- text = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
-
- if (zstr(tts_name)) {
- eval_some_js("~throw new Error(\"Invalid TTS Name\");", cx, obj, rval);
- return JS_FALSE;
- }
-
- if (zstr(text)) {
- eval_some_js("~throw new Error(\"Invalid Text\");", cx, obj, rval);
- return JS_FALSE;
- }
-
- if (jss->speech && jss->speech->speaking) {
- eval_some_js("~throw new Error(\"Recursive call not allowed\");", cx, obj, rval);
- return JS_FALSE;
- }
-
-
- 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 {
- jss->speech = switch_core_session_alloc(jss->session, sizeof(*jss->speech));
- switch_assert(jss->speech != NULL);
- if (init_speech_engine(jss, tts_name, voice_name) != SWITCH_STATUS_SUCCESS) {
- eval_some_js("~throw new Error(\"Cannot allocate speech engine!\");", cx, obj, rval);
- jss->speech = NULL;
- return JS_FALSE;
- }
- }
-
- if (argc > 3) {
- if ((function = JS_ValueToFunction(cx, argv[3]))) {
- memset(&cb_state, 0, sizeof(cb_state));
- cb_state.function = function;
- if (argc > 4) {
- cb_state.arg = argv[4];
- }
-
- cb_state.cx = cx;
- cb_state.obj = obj;
- cb_state.session_state = jss;
- dtmf_func = js_collect_input_callback;
- bp = &cb_state;
- len = sizeof(cb_state);
- }
- }
-
- cb_state.ret = BOOLEAN_TO_JSVAL(JS_FALSE);
- cb_state.saveDepth = JS_SuspendRequest(cx);
- args.input_callback = dtmf_func;
- args.buf = bp;
- args.buflen = len;
-
- switch_core_speech_flush_tts(&jss->speech->sh);
- if (switch_core_codec_ready(&jss->speech->codec)) {
- jss->speech->speaking = 1;
- switch_ivr_speak_text_handle(jss->session, &jss->speech->sh, &jss->speech->codec, NULL, text, &args);
- jss->speech->speaking = 0;
- }
- JS_ResumeRequest(cx, cb_state.saveDepth);
- check_hangup_hook(jss, &ret);
- *rval = cb_state.ret;
-
- return (JSBool)ret;
-}
-
-static JSBool session_get_digits(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- char *terminators = NULL;
- char buf[513] = { 0 };
- int32 digits = 0, timeout = 5000, digit_timeout = 0, abs_timeout = 0;
- switch_channel_t *channel;
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_SANITY_CHECK();
-
- if (argc > 0) {
- char term;
- JS_ValueToInt32(cx, argv[0], &digits);
-
- if (digits > sizeof(buf) - 1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exceeded max digits of %" SWITCH_SIZE_T_FMT "\n", sizeof(buf) - 1);
- return JS_FALSE;
- }
-
- if (argc > 1) {
- terminators = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- }
-
- if (argc > 2) {
- JS_ValueToInt32(cx, argv[2], &timeout);
- }
-
- if (argc > 3) {
- JS_ValueToInt32(cx, argv[3], &digit_timeout);
- }
-
- if (argc > 4) {
- JS_ValueToInt32(cx, argv[4], &abs_timeout);
- }
-
- switch_ivr_collect_digits_count(jss->session, buf, sizeof(buf), digits, terminators, &term, timeout, digit_timeout, abs_timeout);
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
- return JS_TRUE;
- }
-
- return JS_FALSE;
-}
-
-static JSBool session_autohangup(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
-
- METHOD_SANITY_CHECK();
-
- if (argv[0]) {
- JSBool tf;
- JS_ValueToBoolean(cx, argv[0], &tf);
- if (tf == JS_TRUE) {
- switch_set_flag(jss, S_HUP);
- } else {
- switch_clear_flag(jss, S_HUP);
- }
- *rval = BOOLEAN_TO_JSVAL(tf);
- }
-
- return JS_TRUE;
-}
-
-static JSBool session_answer(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_SANITY_CHECK_ANSWER();
-
- switch_channel_answer(channel);
- return JS_TRUE;
-}
-
-static JSBool session_pre_answer(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_SANITY_CHECK_ANSWER();
-
- switch_channel_pre_answer(channel);
- return JS_TRUE;
-}
-
-static JSBool session_cdr(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_xml_t cdr = NULL;
-
- /*Always a pessimist... sheesh! */
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
-
- if (switch_ivr_generate_xml_cdr(jss->session, &cdr) == SWITCH_STATUS_SUCCESS) {
- char *xml_text;
- if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) {
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, xml_text));
- }
- switch_safe_free(xml_text);
- switch_xml_free(cdr);
- }
-
- return JS_TRUE;
-}
-
-static JSBool session_ready(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
-
- *rval = BOOLEAN_TO_JSVAL((jss && jss->session && switch_channel_ready(switch_core_session_get_channel(jss->session))) ? JS_TRUE : JS_FALSE);
-
- return JS_TRUE;
-}
-
-static JSBool session_media_ready(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
-
- *rval = BOOLEAN_TO_JSVAL((jss && jss->session && switch_channel_media_ready(switch_core_session_get_channel(jss->session))) ? JS_TRUE : JS_FALSE);
-
- return JS_TRUE;
-}
-
-
-static JSBool session_ring_ready(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
-
- *rval = BOOLEAN_TO_JSVAL((jss && jss->session && switch_channel_test_flag(switch_core_session_get_channel(jss->session), CF_RING_READY)) ? JS_TRUE : JS_FALSE);
-
- return JS_TRUE;
-}
-
-static JSBool session_answered(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
-
- *rval =
- BOOLEAN_TO_JSVAL((jss && jss->session
- && switch_channel_test_flag(switch_core_session_get_channel(jss->session), CF_ANSWERED)) ? JS_TRUE : JS_FALSE);
-
- return JS_TRUE;
-}
-
-static JSBool session_wait_for_media(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
- switch_time_t started;
- unsigned int elapsed;
- int32 timeout = 60000;
- jsrefcount saveDepth;
- jsval ret = JS_TRUE;
-
- METHOD_SANITY_CHECK();
-
- channel = switch_core_session_get_channel(jss->session);
- CHANNEL_MEDIA_SANITY_CHECK();
-
- started = switch_micro_time_now();
-
- if (argc > 0) {
- JS_ValueToInt32(cx, argv[0], &timeout);
- if (timeout < 1000) {
- timeout = 1000;
- }
- }
-
- if (check_hangup_hook(jss, NULL) != JS_TRUE) {
- return JS_FALSE;
- }
- saveDepth = JS_SuspendRequest(cx);
- for (;;) {
- if (((elapsed = (unsigned int) ((switch_micro_time_now() - started) / 1000)) > (switch_time_t) timeout)
- || switch_channel_down(channel)) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- break;
- }
-
- if (switch_channel_ready(channel)
- && (switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag(channel, CF_EARLY_MEDIA))) {
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- break;
- }
-
- switch_cond_next();
- }
- JS_ResumeRequest(cx, saveDepth);
- check_hangup_hook(jss, &ret);
-
- return (JSBool)ret;
-}
-
-static JSBool session_wait_for_answer(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
- switch_time_t started;
- unsigned int elapsed;
- int32 timeout = 60000;
- jsrefcount saveDepth;
- jsval ret = JS_TRUE;
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
-
- started = switch_micro_time_now();
-
- if (argc > 0) {
- JS_ValueToInt32(cx, argv[0], &timeout);
- if (timeout < 1000) {
- timeout = 1000;
- }
- }
-
- if (check_hangup_hook(jss, NULL) != JS_TRUE) {
- return JS_FALSE;
- }
-
- saveDepth = JS_SuspendRequest(cx);
- for (;;) {
- if (((elapsed = (unsigned int) ((switch_micro_time_now() - started) / 1000)) > (switch_time_t) timeout)
- || switch_channel_down(channel)) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- break;
- }
-
- if (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_ANSWERED)) {
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- break;
- }
-
- switch_cond_next();
- }
- JS_ResumeRequest(cx, saveDepth);
- check_hangup_hook(jss, &ret);
- return (JSBool)ret;
-}
-
-static JSBool session_detach(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- jsval ret = JS_TRUE;
- switch_call_cause_t cause = 0;
- switch_channel_t *channel;
- switch_core_session_t *session;
- METHOD_SANITY_CHECK();
-
- if ((session = jss->session)) {
- jss->session = NULL;
-
- if (argc > 1) {
- if (JSVAL_IS_INT(argv[0])) {
- int32 i = 0;
- JS_ValueToInt32(cx, argv[0], &i);
- cause = i;
- } else {
- const char *cause_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- cause = switch_channel_str2cause(cause_name);
- }
- }
-
- if (cause) {
- channel = switch_core_session_get_channel(session);
- switch_channel_hangup(channel, cause);
- }
-
- switch_core_session_rwunlock(session);
- *rval = JS_TRUE;
- } else {
- *rval = JS_FALSE;
- }
-
- return (JSBool)ret;
-}
-
-static JSBool session_execute(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- JSBool retval = JS_FALSE;
-
- struct js_session *jss = JS_GetPrivate(cx, obj);
- jsval ret = JS_TRUE;
-
- METHOD_SANITY_CHECK();
-
- /* you can execute some apps before you answer CHANNEL_SANITY_CHECK(); */
-
- if (argc > 0) {
- switch_application_interface_t *application_interface;
- char *app_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- char *app_arg = NULL;
- jsrefcount saveDepth;
-
- METHOD_SANITY_CHECK();
-
- if (argc > 1) {
- app_arg = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- }
-
- if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
- if (application_interface->application_function) {
- if (check_hangup_hook(jss, NULL) != JS_TRUE) {
- return JS_FALSE;
- }
-
- saveDepth = JS_SuspendRequest(cx);
- switch_core_session_exec(jss->session, application_interface, app_arg);
- JS_ResumeRequest(cx, saveDepth);
- check_hangup_hook(jss, &ret);
- retval = JS_TRUE;
- }
- UNPROTECT_INTERFACE(application_interface);
- }
- }
-
- *rval = BOOLEAN_TO_JSVAL(retval);
- return (JSBool)ret;
-}
-
-static JSBool session_get_event(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_event_t *event;
-
- METHOD_SANITY_CHECK();
-
- if (switch_core_session_dequeue_event(jss->session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
- JSObject *Event;
- struct event_obj *eo;
-
- if ((eo = malloc(sizeof(*eo)))) {
- eo->event = event;
- eo->freed = 0;
-
- if ((Event = JS_DefineObject(cx, obj, "__event__", &event_class, NULL, 0))) {
- if ((JS_SetPrivate(cx, Event, eo) && JS_DefineProperties(cx, Event, event_props) && JS_DefineFunctions(cx, Event, event_methods))) {
- *rval = OBJECT_TO_JSVAL(Event);
- return JS_TRUE;
- }
- }
- }
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
-}
-
-static JSBool session_send_event(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- JSObject *Event;
- struct event_obj *eo;
-
- METHOD_SANITY_CHECK();
-
- if (argc > 0) {
- if (JS_ValueToObject(cx, argv[0], &Event)) {
- if ((eo = JS_GetPrivate(cx, Event))) {
- if (switch_core_session_receive_event(jss->session, &eo->event) != SWITCH_STATUS_SUCCESS) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- JS_SetPrivate(cx, Event, NULL);
- }
- }
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
-}
-
-static JSBool session_hangup(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- switch_channel_t *channel;
- char *cause_name = NULL;
- switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
-
- METHOD_SANITY_CHECK();
- channel = switch_core_session_get_channel(jss->session);
- //CHANNEL_SANITY_CHECK();
-
- if (switch_channel_up(channel)) {
- jsval ret = JS_TRUE;
-
- if (argc > 0) {
- if (JSVAL_IS_INT(argv[0])) {
- int32 i = 0;
- JS_ValueToInt32(cx, argv[0], &i);
- cause = i;
- } else {
- cause_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- cause = switch_channel_str2cause(cause_name);
- }
- }
-
- switch_channel_hangup(channel, cause);
- switch_core_session_kill_channel(jss->session, SWITCH_SIG_KILL);
-
- jss->hook_state = CS_HANGUP;
- check_hangup_hook(jss, &ret);
-
- }
-
- return JS_TRUE;
-}
-
-#ifdef HAVE_CURL
-
-struct config_data {
- JSContext *cx;
- JSObject *obj;
- char *name;
- int fd;
-};
-
-struct fetch_url_data {
- JSContext *cx;
- JSObject *obj;
- switch_size_t buffer_size;
- switch_size_t data_len;
- char *buffer;
-};
-
-static size_t hash_callback(void *ptr, size_t size, size_t nmemb, void *data)
-{
- register size_t realsize = size * nmemb;
- char *line, lineb[2048], *nextline = NULL, *val = NULL, *p = NULL;
- jsval rval;
- struct config_data *config_data = data;
- char code[256];
-
- if (config_data->name) {
- switch_copy_string(lineb, (char *) ptr, sizeof(lineb));
- line = lineb;
- while (line) {
- if ((nextline = strchr(line, '\n'))) {
- *nextline = '\0';
- nextline++;
- }
-
- if ((val = strchr(line, '='))) {
- *val = '\0';
- val++;
- if (val[0] == '>') {
- *val = '\0';
- val++;
- }
-
- for (p = line; p && *p == ' '; p++);
- line = p;
- for (p = line + strlen(line) - 1; *p == ' '; p--)
- *p = '\0';
- for (p = val; p && *p == ' '; p++);
- val = p;
- for (p = val + strlen(val) - 1; *p == ' '; p--)
- *p = '\0';
-
- switch_snprintf(code, sizeof(code), "~%s[\"%s\"] = \"%s\"", config_data->name, line, val);
- eval_some_js(code, config_data->cx, config_data->obj, &rval);
-
- }
-
- line = nextline;
- }
- }
- return realsize;
-}
-
-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)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to write all bytes!\n");
- }
- return realsize;
-}
-
-static size_t fetch_url_callback(void *ptr, size_t size, size_t nmemb, void *data)
-{
- register unsigned int realsize = (unsigned int) (size * nmemb);
- struct fetch_url_data *config_data = data;
-
- /* Too much data. Do not increase buffer, but abort fetch instead. */
- if (config_data->data_len + realsize >= config_data->buffer_size) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Data do not fit in the allocated buffer\n");
- return 0;
- }
-
- memcpy(config_data->buffer + config_data->data_len, ptr, realsize);
- config_data->data_len += realsize;
- config_data->buffer[config_data->data_len] = 0;
-
- return realsize;
-}
-
-
-static JSBool js_fetchurl_hash(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- char *url = NULL, *name = NULL;
- CURL *curl_handle = NULL;
- struct config_data config_data;
- int saveDepth = 0;
-
- if (argc > 1) {
- url = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- name = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
-
- curl_handle = curl_easy_init();
- if (!strncasecmp(url, "https", 5)) {
- curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
- }
- config_data.cx = cx;
- config_data.obj = obj;
- if (name) {
- config_data.name = name;
- }
- curl_easy_setopt(curl_handle, CURLOPT_URL, url);
- curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
- curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, hash_callback);
- curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
- curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-js/1.0");
-
- saveDepth = JS_SuspendRequest(cx);
- curl_easy_perform(curl_handle);
- JS_ResumeRequest(cx, saveDepth);
-
- curl_easy_cleanup(curl_handle);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
- return JS_FALSE;
- }
-
- return JS_TRUE;
-}
-
-
-
-static JSBool js_fetchurl_file(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- char *url = NULL, *filename = NULL;
- CURL *curl_handle = NULL;
- struct config_data config_data;
- int saveDepth = 0;
-
- if (argc > 1) {
- url = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- filename = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
-
- curl_handle = curl_easy_init();
- if (!strncasecmp(url, "https", 5)) {
- curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
- }
- config_data.cx = cx;
- config_data.obj = obj;
-
- config_data.name = filename;
- if ((config_data.fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
- curl_easy_setopt(curl_handle, CURLOPT_URL, url);
- curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
- curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, file_callback);
- curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
- curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-js/1.0");
-
- saveDepth = JS_SuspendRequest(cx);
- curl_easy_perform(curl_handle);
- JS_ResumeRequest(cx, saveDepth);
-
- curl_easy_cleanup(curl_handle);
- close(config_data.fd);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
- }
-
- return JS_TRUE;
-}
-
-static JSBool js_fetchurl(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- char *url = NULL;
- CURL *curl_handle = NULL;
- struct fetch_url_data config_data;
- int32 buffer_size = 65535;
- CURLcode code = 0;
- int saveDepth = 0;
-
- if (argc >= 1) {
- url = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- if (argc > 1) {
- JS_ValueToInt32(cx, argv[1], &buffer_size);
- }
-
- curl_handle = curl_easy_init();
- if (!strncasecmp(url, "https", 5)) {
- curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
- }
-
- config_data.buffer_size = buffer_size;
- config_data.buffer = malloc(config_data.buffer_size);
- config_data.data_len = 0;
- if (config_data.buffer == NULL) {
- eval_some_js("~throw new Error(\"Failed to allocate data buffer.\");", cx, obj, rval);
- return JS_TRUE;
- }
-
- curl_easy_setopt(curl_handle, CURLOPT_URL, url);
- curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
- curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, fetch_url_callback);
- curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
- curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-js/1.0");
-
- saveDepth = JS_SuspendRequest(cx);
- code = curl_easy_perform(curl_handle);
- JS_ResumeRequest(cx, saveDepth);
-
- curl_easy_cleanup(curl_handle);
-
- if (code != CURLE_WRITE_ERROR) {
- config_data.buffer[config_data.data_len] = 0;
- *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);
- eval_some_js(errmsg, cx, obj, rval);
- }
-
- free(config_data.buffer);
-
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
- }
-
- return JS_TRUE;
-}
-#endif
-
-/* Session Object */
-/*********************************************************************************/
-enum session_tinyid {
- SESSION_NAME, SESSION_STATE,
- PROFILE_DIALPLAN, PROFILE_CID_NAME, PROFILE_CID_NUM, PROFILE_IP, PROFILE_ANI, PROFILE_ANI_II, PROFILE_DEST,
- SESSION_UUID, SESSION_CAUSE, SESSION_CAUSECODE
-};
-
-static JSFunctionSpec session_methods[] = {
- {"originate", session_originate, 2},
- {"setCallerData", session_set_callerdata, 2},
- {"setHangupHook", session_hanguphook, 1},
- {"setAutoHangup", session_autohangup, 1},
- {"sayPhrase", session_sayphrase, 1},
- {"streamFile", session_streamfile, 1},
- {"collectInput", session_collect_input, 1},
- {"recordFile", session_recordfile, 1},
- {"flushEvents", session_flush_events, 1},
- {"flushDigits", session_flush_digits, 1},
- {"speak", session_speak, 1},
- {"setVariable", session_set_variable, 1},
- {"getVariable", session_get_variable, 1},
- {"getDigits", session_get_digits, 1},
- {"answer", session_answer, 0},
- {"preAnswer", session_pre_answer, 0},
- {"generateXmlCdr", session_cdr, 0},
- {"ready", session_ready, 0},
- {"answered", session_answered, 0},
- {"mediaReady", session_media_ready, 0},
- {"ringReady", session_ring_ready, 0},
- {"waitForAnswer", session_wait_for_answer, 0},
- {"waitForMedia", session_wait_for_media, 0},
- {"getEvent", session_get_event, 0},
- {"sendEvent", session_send_event, 0},
- {"hangup", session_hangup, 0},
- {"execute", session_execute, 0},
- {"destroy", session_detach, 0},
- {"sleep", session_sleep, 1},
- {0}
-};
-
-static JSPropertySpec session_props[] = {
- {"name", SESSION_NAME, JSPROP_READONLY | JSPROP_PERMANENT},
- {"state", SESSION_STATE, JSPROP_READONLY | JSPROP_PERMANENT},
- {"dialplan", PROFILE_DIALPLAN, JSPROP_READONLY | JSPROP_PERMANENT},
- {"caller_id_name", PROFILE_CID_NAME, JSPROP_READONLY | JSPROP_PERMANENT},
- {"caller_id_num", PROFILE_CID_NUM, JSPROP_READONLY | JSPROP_PERMANENT},
- {"caller_id_number", PROFILE_CID_NUM, JSPROP_READONLY | JSPROP_PERMANENT},
- {"network_addr", PROFILE_IP, JSPROP_READONLY | JSPROP_PERMANENT},
- {"network_address", PROFILE_IP, JSPROP_READONLY | JSPROP_PERMANENT},
- {"ani", PROFILE_ANI, JSPROP_READONLY | JSPROP_PERMANENT},
- {"aniii", PROFILE_ANI_II, JSPROP_READONLY | JSPROP_PERMANENT},
- {"destination", PROFILE_DEST, JSPROP_READONLY | JSPROP_PERMANENT},
- {"uuid", SESSION_UUID, JSPROP_READONLY | JSPROP_PERMANENT},
- {"cause", SESSION_CAUSE, JSPROP_READONLY | JSPROP_PERMANENT},
- {"causecode", SESSION_CAUSECODE, JSPROP_READONLY | JSPROP_PERMANENT},
- {0}
-};
-
-static JSBool session_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
-{
- struct js_session *jss = JS_GetPrivate(cx, obj);
- int param = 0;
- switch_channel_t *channel = NULL;
- switch_caller_profile_t *caller_profile = NULL;
- char *name = NULL;
-
- if (jss && jss->session) {
- channel = switch_core_session_get_channel(jss->session);
- caller_profile = switch_channel_get_caller_profile(channel);
- }
-
- 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);
- } else {
- return JS_TRUE;
- }
-
- if (!channel) {
- switch (param) {
- case SESSION_CAUSE:
- if (jss) {
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_cause2str(jss->cause)));
- }
- break;
- case SESSION_CAUSECODE:
- if (jss) {
- *vp = INT_TO_JSVAL(jss->cause);
- }
- break;
- default:
- *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
- }
- return JS_TRUE;
- }
-
- switch (param) {
- case SESSION_CAUSE:
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_cause2str(switch_channel_get_cause(channel))));
- break;
- case SESSION_CAUSECODE:
- *vp = INT_TO_JSVAL(switch_channel_get_cause(channel));
- break;
- case SESSION_NAME:
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_get_name(channel)));
- break;
- case SESSION_UUID:
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_get_uuid(channel)));
- break;
- case SESSION_STATE:
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_state_name(switch_channel_get_state(channel))));
- break;
- case PROFILE_DIALPLAN:
- if (caller_profile) {
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->dialplan));
- }
- break;
- case PROFILE_CID_NAME:
- if (caller_profile) {
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->caller_id_name));
- }
- break;
- case PROFILE_CID_NUM:
- if (caller_profile) {
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->caller_id_number));
- }
- break;
- case PROFILE_IP:
- if (caller_profile) {
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->network_addr));
- }
- break;
- case PROFILE_ANI:
- if (caller_profile) {
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->ani));
- }
- break;
- case PROFILE_ANI_II:
- if (caller_profile) {
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->aniii));
- }
- break;
- case PROFILE_DEST:
- if (caller_profile) {
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->destination_number));
- }
- break;
- default:
- *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
- break;
- }
-
- return JS_TRUE;
-}
-
-JSClass session_class = {
- "Session", JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, session_getProperty, DEFAULT_SET_PROPERTY,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, session_destroy, NULL, NULL, NULL,
- session_construct
-};
-
-static JSObject *new_js_session(JSContext * cx, JSObject * obj, switch_core_session_t *session, struct js_session **jss, char *name, int flags)
-{
- JSObject *session_obj;
- if ((session_obj = JS_DefineObject(cx, obj, name, &session_class, NULL, 0))) {
- *jss = malloc(sizeof(**jss));
- switch_assert(*jss);
- memset(*jss, 0, sizeof(**jss));
-
- (*jss)->session = session;
- (*jss)->flags = flags;
- (*jss)->cx = cx;
- (*jss)->obj = session_obj;
- (*jss)->stack_depth = 0;
- if ((JS_SetPrivate(cx, session_obj, *jss) &&
- JS_DefineProperties(cx, session_obj, session_props) && JS_DefineFunctions(cx, session_obj, session_methods))) {
- if (switch_core_session_read_lock_hangup(session) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Read Lock Failure.\n");
- free(*jss);
- return NULL;
- }
- return session_obj;
- } else {
- free(*jss);
- }
- }
-
- return NULL;
-}
-
-/* Session Object */
-/*********************************************************************************/
-
-static JSBool session_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = NULL;
- JSObject *session_obj = NULL;
-
- jss = malloc(sizeof(*jss));
- switch_assert(jss);
- memset(jss, 0, sizeof(*jss));
- jss->cx = cx;
- jss->obj = obj;
- JS_SetPrivate(cx, obj, jss);
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
-
- if (argc > 0) {
- char *uuid = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
-
- if (!strchr(uuid, '/')) {
- jss->session = switch_core_session_locate(uuid);
- switch_set_flag(jss, S_HUP);
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- } else {
- struct js_session *old_jss = NULL;
-
- if (argc > 1) {
- if (JS_ValueToObject(cx, argv[1], &session_obj) && session_obj) {
- old_jss = JS_GetPrivate(cx, session_obj);
- }
- }
- if (switch_ivr_originate(old_jss ? old_jss->session : NULL,
- &jss->session, &jss->cause, uuid, 60, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL) == SWITCH_STATUS_SUCCESS) {
- switch_set_flag(jss, S_HUP);
- //switch_channel_set_state(switch_core_session_get_channel(jss->session), CS_SOFT_EXECUTE);
- //switch_channel_wait_for_state_timeout(switch_core_session_get_channel(jss->session), CS_SOFT_EXECUTE, 5000);
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- } else {
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_cause2str(jss->cause)));
- }
- }
- }
-
- return JS_TRUE;
-}
-
-static JSBool session_set_callerdata(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = NULL;
- jss = JS_GetPrivate(cx, obj);
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
-
- if (argc > 1) {
- 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")) {
- toset = &jss->username;
- } else if (!strcasecmp(var, "caller_id_name")) {
- toset = &jss->caller_id_name;
- } else if (!strcasecmp(var, "ani")) {
- toset = &jss->ani;
- } else if (!strcasecmp(var, "aniii")) {
- toset = &jss->aniii;
- } else if (!strcasecmp(var, "caller_id_number")) {
- toset = &jss->caller_id_number;
- } else if (!strcasecmp(var, "network_addr")) {
- toset = &jss->network_addr;
- } else if (!strcasecmp(var, "rdnis")) {
- toset = &jss->rdnis;
- } else if (!strcasecmp(var, "destination_number")) {
- toset = &jss->destination_number;
- } else if (!strcasecmp(var, "context")) {
- toset = &jss->context;
- }
-
- if (toset) {
- switch_safe_free(*toset);
- *toset = strdup(val);
- }
-
- }
-
- return JS_TRUE;
-}
-
-static JSBool session_originate(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss = NULL;
- switch_memory_pool_t *pool = NULL;
-
- jss = JS_GetPrivate(cx, obj);
- jss->cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
-
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This method is deprecated, please use new Session(\"\", a_leg) \n");
-
- if (jss->session) {
- eval_some_js("~throw new Error(\"cannot call this method on an initialized session\");", cx, obj, rval);
- return JS_FALSE;
- }
-
- if (argc > 1) {
- JSObject *session_obj;
- switch_core_session_t *session = NULL, *peer_session = NULL;
- switch_caller_profile_t *caller_profile = NULL, *orig_caller_profile = NULL;
- const char *dest = NULL;
- const char *dialplan = NULL;
- const char *cid_name = "";
- const char *cid_num = "";
- const char *network_addr = "";
- const char *ani = "";
- const char *aniii = "";
- const char *rdnis = "";
- const char *context = "";
- const char *username = NULL;
- char *to = NULL;
- char *tmp;
- jsrefcount saveDepth;
- switch_status_t status;
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
-
- if (JS_ValueToObject(cx, argv[0], &session_obj)) {
- struct js_session *old_jss = NULL;
- if (session_obj && (old_jss = JS_GetPrivate(cx, session_obj))) {
-
- if (old_jss == jss) {
- eval_some_js("~throw new Error(\"Supplied a_leg session is the same as our session\");", cx, obj, rval);
- return JS_FALSE;
-
- };
-
- if (!old_jss->session) {
- eval_some_js("~throw new Error(\"Supplied a_leg session is not initilaized!\");", cx, obj, rval);
- return JS_FALSE;
- }
-
- session = old_jss->session;
- orig_caller_profile = switch_channel_get_caller_profile(switch_core_session_get_channel(session));
- dialplan = orig_caller_profile->dialplan;
- cid_name = orig_caller_profile->caller_id_name;
- cid_num = orig_caller_profile->caller_id_number;
- ani = orig_caller_profile->ani;
- aniii = orig_caller_profile->aniii;
- rdnis = orig_caller_profile->rdnis;
- context = orig_caller_profile->context;
- username = orig_caller_profile->username;
- }
-
- }
-
- if (!zstr(jss->dialplan))
- dialplan = jss->dialplan;
- if (!zstr(jss->caller_id_name))
- cid_name = jss->caller_id_name;
- if (!zstr(jss->caller_id_number))
- cid_num = jss->caller_id_number;
- if (!zstr(jss->ani))
- ani = jss->ani;
- if (!zstr(jss->aniii))
- aniii = jss->aniii;
- if (!zstr(jss->rdnis))
- rdnis = jss->rdnis;
- if (!zstr(jss->context))
- context = jss->context;
- if (!zstr(jss->username))
- username = jss->username;
-
- dest = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
-
- if (!strchr(dest, '/')) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Channel String\n");
- goto done;
- }
-
- if (argc > 2) {
- tmp = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
- if (!zstr(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);
-
- saveDepth = JS_SuspendRequest(cx);
- status =
- switch_ivr_originate(session, &peer_session, &jss->cause, dest, to ? atoi(to) : 60, NULL, NULL, NULL, caller_profile, NULL, SOF_NONE, NULL);
- JS_ResumeRequest(cx, saveDepth);
-
- if (status != SWITCH_STATUS_SUCCESS) {
- 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);
- //switch_channel_set_state(switch_core_session_get_channel(jss->session), CS_SOFT_EXECUTE);
-
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing Args\n");
- }
-
- done:
- return JS_TRUE;
-}
-
-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);
- }
-
- switch_safe_free(jss->dialplan);
- switch_safe_free(jss->username);
- switch_safe_free(jss->caller_id_name);
- switch_safe_free(jss->ani);
- switch_safe_free(jss->aniii);
- switch_safe_free(jss->caller_id_number);
- switch_safe_free(jss->network_addr);
- switch_safe_free(jss->rdnis);
- switch_safe_free(jss->destination_number);
- switch_safe_free(jss->context);
- switch_core_session_rwunlock(session);
- }
-
- free(jss);
-
- }
- }
-
- return;
-}
-
-/* FileIO Object */
-/*********************************************************************************/
-static JSBool fileio_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- switch_memory_pool_t *pool;
- switch_file_t *fd;
- char *path, *flags_str;
- unsigned int flags = 0;
- struct fileio_obj *fio;
-
- if (argc > 1) {
- path = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- flags_str = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
-
- if (strchr(flags_str, 'r')) {
- flags |= SWITCH_FOPEN_READ;
- }
- if (strchr(flags_str, 'w')) {
- flags |= SWITCH_FOPEN_WRITE;
- }
- if (strchr(flags_str, 'c')) {
- flags |= SWITCH_FOPEN_CREATE;
- }
- if (strchr(flags_str, 'a')) {
- flags |= SWITCH_FOPEN_APPEND;
- }
- if (strchr(flags_str, 't')) {
- flags |= SWITCH_FOPEN_TRUNCATE;
- }
- if (strchr(flags_str, 'b')) {
- flags |= SWITCH_FOPEN_BINARY;
- }
- switch_core_new_memory_pool(&pool);
- if (switch_file_open(&fd, path, flags, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Open File: %s\n", path);
- switch_core_destroy_memory_pool(&pool);
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
- fio = switch_core_alloc(pool, sizeof(*fio));
- fio->fd = fd;
- fio->pool = pool;
- fio->path = switch_core_strdup(pool, path);
- fio->flags = flags;
- JS_SetPrivate(cx, obj, fio);
- return JS_TRUE;
- }
-
- return JS_TRUE;
-}
-static void fileio_destroy(JSContext * cx, JSObject * obj)
-{
- struct fileio_obj *fio = JS_GetPrivate(cx, obj);
-
- if (fio) {
- switch_memory_pool_t *pool;
- if (fio->fd) {
- switch_file_close(fio->fd);
- }
- pool = fio->pool;
- switch_core_destroy_memory_pool(&pool);
- pool = NULL;
- }
-}
-
-static JSBool fileio_read(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct fileio_obj *fio = JS_GetPrivate(cx, obj);
- int32 bytes = 0;
- switch_size_t read = 0;
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
-
- if (!fio) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (!(fio->flags & SWITCH_FOPEN_READ)) {
- return JS_TRUE;
- }
-
- if (argc > 0) {
- JS_ValueToInt32(cx, argv[0], &bytes);
- }
-
- if (bytes) {
- if (!fio->buf || fio->bufsize < bytes) {
- fio->buf = switch_core_alloc(fio->pool, bytes);
- fio->bufsize = bytes;
- }
- read = bytes;
- switch_file_read(fio->fd, fio->buf, &read);
- fio->buflen = read;
- *rval = BOOLEAN_TO_JSVAL((read > 0) ? JS_TRUE : JS_FALSE);
- }
-
- return JS_TRUE;
-}
-
-static JSBool fileio_data(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct fileio_obj *fio = JS_GetPrivate(cx, obj);
-
- if (!fio) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, fio->buf));
- return JS_TRUE;
-}
-
-static JSBool fileio_write(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct fileio_obj *fio = JS_GetPrivate(cx, obj);
- switch_size_t wrote = 0;
- char *data = NULL;
-
- if (!fio) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (!(fio->flags & SWITCH_FOPEN_WRITE)) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (argc > 0) {
- data = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- }
-
- if (data) {
- wrote = strlen(data);
- *rval = BOOLEAN_TO_JSVAL((switch_file_write(fio->fd, data, &wrote) == SWITCH_STATUS_SUCCESS) ? JS_TRUE : JS_FALSE);
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
-}
-
-enum fileio_tinyid {
- FILEIO_PATH, FILEIO_OPEN
-};
-
-static JSFunctionSpec fileio_methods[] = {
- {"read", fileio_read, 1},
- {"write", fileio_write, 1},
- {"data", fileio_data, 0},
- {0}
-};
-
-static JSPropertySpec fileio_props[] = {
- {"path", FILEIO_PATH, JSPROP_READONLY | JSPROP_PERMANENT},
- {"open", FILEIO_OPEN, JSPROP_READONLY | JSPROP_PERMANENT},
- {0}
-};
-
-static JSBool fileio_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
-{
- JSBool res = JS_TRUE;
- struct fileio_obj *fio = JS_GetPrivate(cx, obj);
- char *name;
- int param = 0;
-
- 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);
- } else {
- return JS_TRUE;
- }
-
- switch (param) {
- case FILEIO_PATH:
- if (fio) {
- *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, fio->path));
- } else {
- *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
- }
- break;
- case FILEIO_OPEN:
- *vp = BOOLEAN_TO_JSVAL(fio ? JS_TRUE : JS_FALSE);
- break;
- }
-
- return res;
-}
-
-JSClass fileio_class = {
- "FileIO", JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub, fileio_getProperty, DEFAULT_SET_PROPERTY,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, fileio_destroy, NULL, NULL, NULL,
- fileio_construct
-};
-
-/* Built-In*/
-/*********************************************************************************/
-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);
- }
- return JS_FALSE;
-}
-
-static JSBool js_log(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- char *level_str, *msg;
- switch_log_level_t level = SWITCH_LOG_DEBUG;
- JSScript *script = NULL;
- const char *file = __FILE__;
- int line = __LINE__;
- JSStackFrame *caller;
-
- caller = JS_GetScriptedCaller(cx, NULL);
- script = JS_GetFrameScript(cx, caller);
-
- if (script) {
- file = JS_GetScriptFilename(cx, script);
- line = JS_GetScriptBaseLineNumber(cx, script);
- }
-
- if (argc > 1) {
- if ((level_str = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
- level = switch_log_str2level(level_str);
- if (level == SWITCH_LOG_INVALID) {
- level = SWITCH_LOG_DEBUG;
- }
- }
-
- if ((msg = JS_GetStringBytes(JS_ValueToString(cx, argv[1])))) {
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "console_log", line, NULL, level, "%s", msg);
- return JS_TRUE;
- }
- } else if (argc > 0) {
- if ((msg = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "console_log", line, NULL, level, "%s", msg);
- return JS_TRUE;
- }
- }
-
- return JS_FALSE;
-}
-
-static JSBool js_global_set(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- char *var_name = NULL, *val = NULL, *val2 = NULL;
- JSBool tf = JS_TRUE;
- if (argc > 1) {
- var_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- val = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- if (argc == 2) {
- switch_core_set_variable(var_name, val);
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
- } else {
- val2 = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
- if (switch_core_set_var_conditional(var_name, val, val2) != SWITCH_TRUE) {
- tf = JS_FALSE;
- }
- *rval = BOOLEAN_TO_JSVAL(tf);
- return JS_TRUE;
- }
- }
- /* this is so the wrong error message to throw for this one */
- eval_some_js("~throw new Error(\"var name not supplied!\");", cx, obj, rval);
- return JS_FALSE;
-}
-
-static JSBool js_global_get(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- char *var_name = NULL, *val = NULL;
-
- if (argc > 0) {
- var_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- val = switch_core_get_variable_dup(var_name);
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val));
- free(val);
- return JS_TRUE;
- }
-
- eval_some_js("~throw new Error(\"var name not supplied!\");", cx, obj, rval);
- return JS_FALSE;
-}
-
-static JSBool js_include(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- char *code;
- if (argc > 0 && (code = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
- if (eval_some_js(code, cx, obj, rval) <= 0) {
- return JS_FALSE;
- }
- return JS_TRUE;
- }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Arguements\n");
- return JS_FALSE;
-}
-
-static JSBool js_api_sleep(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- int32 msec = 0;
-
- if (argc > 0) {
- JS_ValueToInt32(cx, argv[0], &msec);
- }
-
- if (msec) {
- int saveDepth;
- saveDepth = JS_SuspendRequest(cx);
- switch_yield(msec * 1000);
- JS_ResumeRequest(cx, saveDepth);
- } else {
- eval_some_js("~throw new Error(\"No Time specified\");", cx, obj, rval);
- }
-
- return JS_TRUE;
-
-}
-
-static JSBool js_api_use(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- char *mod_name = NULL;
-
- if (argc > 0 && (mod_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
- const sm_module_interface_t *mp;
-
- if ((mp = switch_core_hash_find(module_manager.load_hash, mod_name))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading %s\n", mod_name);
- mp->spidermonkey_load(cx, obj);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error loading %s\n", mod_name);
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Filename\n");
- }
-
- return JS_TRUE;
-}
-
-static JSBool js_api_execute(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- if (argc > 0) {
- char *cmd = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- char *arg = NULL;
- switch_core_session_t *session = NULL;
- switch_stream_handle_t stream = { 0 };
-
- if (!strcasecmp(cmd, "jsapi")) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid API Call!\n");
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
-
- if (argc > 1) {
- arg = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- }
-
- if (argc > 2) {
- JSObject *session_obj;
- struct js_session *jss;
- if (JS_ValueToObject(cx, argv[2], &session_obj)) {
- if ((jss = JS_GetPrivate(cx, session_obj))) {
- session = jss->session;
- }
- }
- }
-
- SWITCH_STANDARD_STREAM(stream);
- switch_api_execute(cmd, arg, session, &stream);
-
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_str_nil((char *) stream.data)));
- switch_safe_free(stream.data);
-
- } else {
- *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, ""));
- }
-
- return JS_TRUE;
-}
-
-static JSBool js_email(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- char *to = NULL, *from = NULL, *headers = NULL, *body = NULL, *file = NULL, *convert_cmd = NULL, *convert_ext = NULL;
-
- if (argc > 0) {
- to = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- }
-
- if (argc > 1) {
- from = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- }
-
- if (argc > 2) {
- headers = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
- }
-
- if (argc > 3) {
- body = JS_GetStringBytes(JS_ValueToString(cx, argv[3]));
- }
-
- if (argc > 4) {
- file = JS_GetStringBytes(JS_ValueToString(cx, argv[4]));
- }
-
- if (argc > 5) {
- convert_cmd = JS_GetStringBytes(JS_ValueToString(cx, argv[5]));
- }
-
- if (argc > 6) {
- convert_ext = JS_GetStringBytes(JS_ValueToString(cx, argv[6]));
- }
-
- if (to && from && headers && body && switch_simple_email(to, from, headers, body, file, convert_cmd, convert_ext) == SWITCH_TRUE) {
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- return JS_TRUE;
- }
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_FALSE;
-
-}
-
-static JSBool js_bridge(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- struct js_session *jss_a = NULL, *jss_b = NULL;
- JSObject *session_obj_a = NULL, *session_obj_b = NULL;
- void *bp = NULL;
- switch_input_callback_function_t dtmf_func = NULL;
- struct input_callback_state cb_state = { 0 };
- JSFunction *function;
-
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
-
- if (argc > 1) {
- if (JS_ValueToObject(cx, argv[0], &session_obj_a)) {
- if (!(jss_a = JS_GetPrivate(cx, session_obj_a))) {
- eval_some_js("~throw new Error(\"Cannot find session A\");", cx, obj, rval);
- return JS_FALSE;
- }
- }
- if (JS_ValueToObject(cx, argv[1], &session_obj_b)) {
- if (!(jss_b = JS_GetPrivate(cx, session_obj_b))) {
- eval_some_js("~throw new Error(\"Cannot find session B\");", cx, obj, rval);
- return JS_FALSE;
- }
- }
- }
-
- if (!(jss_a && jss_a->session)) {
- eval_some_js("~throw new Error(\"session A is not ready!\");", cx, obj, rval);
- return JS_FALSE;
- }
-
- if (!(jss_b && jss_b->session)) {
- eval_some_js("~throw new Error(\"session B is not ready!\");", cx, obj, rval);
- return JS_FALSE;
- }
-
- if (argc > 2) {
- if ((function = JS_ValueToFunction(cx, argv[2]))) {
- memset(&cb_state, 0, sizeof(cb_state));
- cb_state.function = function;
-
- if (argc > 3) {
- cb_state.arg = argv[3];
- }
-
- cb_state.cx = cx;
- cb_state.obj = obj;
- cb_state.jss_a = jss_a;
- cb_state.jss_b = jss_b;
- cb_state.session_obj_a = session_obj_a;
- cb_state.session_obj_b = session_obj_b;
- cb_state.session_state = jss_a;
- dtmf_func = js_collect_input_callback;
- bp = &cb_state;
- }
- }
-
- cb_state.saveDepth = JS_SuspendRequest(cx);
- switch_ivr_multi_threaded_bridge(jss_a->session, jss_b->session, dtmf_func, bp, bp);
- JS_ResumeRequest(cx, cb_state.saveDepth);
-
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
-
- return JS_TRUE;
-}
-
-/* Replace this with more robust version later */
-static JSBool js_system(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- char *cmd;
- int saveDepth, result;
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
-
- if (argc > 0 && (cmd = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
- saveDepth = JS_SuspendRequest(cx);
- result = switch_system(cmd, SWITCH_TRUE);
- JS_ResumeRequest(cx, saveDepth);
- *rval = INT_TO_JSVAL(result);
- return JS_TRUE;
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Arguements\n");
- return JS_FALSE;
-}
-
-static JSBool js_file_unlink(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
-{
- const char *path;
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- if (argc > 0 && (path = (const char *) JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
- if ((switch_file_remove(path, NULL)) == SWITCH_STATUS_SUCCESS) {
- *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
- }
- return JS_TRUE;
- }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Arguements\n");
- return JS_FALSE;
-}
-
-static JSFunctionSpec fs_functions[] = {
- {"console_log", js_log, 2},
- {"consoleLog", js_log, 2},
- {"getGlobalVariable", js_global_get, 2},
- {"setGlobalVariable", js_global_set, 2},
- {"exit", js_exit, 0},
- {"include", js_include, 1},
- {"bridge", js_bridge, 2},
- {"email", js_email, 3},
- {"apiExecute", js_api_execute, 2},
- {"use", js_api_use, 1},
- {"msleep", js_api_sleep, 1},
- {"fileDelete", js_file_unlink, 1},
- {"system", js_system, 1},
-#ifdef HAVE_CURL
- {"fetchURL", js_fetchurl, 1},
- {"fetchURLHash", js_fetchurl_hash, 1},
- {"fetchURLFile", js_fetchurl_file, 1},
- {"fetchUrl", js_fetchurl, 1},
- {"fetchUrlHash", js_fetchurl_hash, 1},
- {"fetchUrlFile", js_fetchurl_file, 1},
-#endif
- {0}
-};
-
-static int env_init(JSContext * cx, JSObject * javascript_object)
-{
- JS_DefineFunctions(cx, javascript_object, fs_functions);
-
- JS_InitStandardClasses(cx, javascript_object);
-
- JS_InitClass(cx, javascript_object, NULL, &session_class, session_construct, 3, session_props, session_methods, session_props, session_methods);
-
- JS_InitClass(cx, javascript_object, NULL, &fileio_class, fileio_construct, 3, fileio_props, fileio_methods, fileio_props, fileio_methods);
-
- JS_InitClass(cx, javascript_object, NULL, &event_class, event_construct, 3, event_props, event_methods, event_props, event_methods);
-
- JS_InitClass(cx, javascript_object, NULL, &dtmf_class, dtmf_construct, 3, dtmf_props, dtmf_methods, dtmf_props, dtmf_methods);
-
- JS_InitClass(cx, javascript_object, NULL, &pcre_class, pcre_construct, 3, pcre_props, pcre_methods, pcre_props, pcre_methods);
-
- return 1;
-}
-
-static void js_parse_and_execute(switch_core_session_t *session, const char *input_code, struct request_obj *ro, switch_event_t *message)
-{
- JSObject *javascript_global_object = NULL;
- char buf[1024], *arg, *argv[512];
- const char *script;
- int argc = 0, x = 0, y = 0;
- unsigned int flags = 0;
- struct js_session *jss = NULL;
- JSContext *cx = NULL;
- jsval rval;
- struct js_env env = { 0 };
-
- if (zstr(input_code)) {
- return;
- }
-
- init_js(&env);
-
- if ((cx = JS_NewContext(env.rt, env.gStackChunkSize))) {
- JS_BeginRequest(cx);
- JS_SetErrorReporter(cx, js_error);
- javascript_global_object = JS_NewObject(cx, &global_class, NULL, NULL);
- env_init(cx, javascript_global_object);
- JS_SetGlobalObject(cx, javascript_global_object);
-
- /* Emaculent conception of session object into the script if one is available */
- if (!(session && new_js_session(cx, javascript_global_object, session, &jss, "session", flags))) {
- switch_snprintf(buf, sizeof(buf), "~var session = false;");
- eval_some_js(buf, cx, javascript_global_object, &rval);
-
- if (message) {
- new_js_event(message, "message", cx, javascript_global_object);
- }
-
-
- }
- if (ro) {
- new_request(cx, javascript_global_object, ro);
- }
-
- } else {
- abort();
- }
-
- script = input_code;
-
- if (*script != '~') {
- if ((arg = strchr(script, ' '))) {
- *arg++ = '\0';
- argc = switch_separate_string(arg, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
- }
-
- if (!argc) {
- switch_snprintf(buf, sizeof(buf), "~var argv = new Array();");
- eval_some_js(buf, cx, javascript_global_object, &rval);
- } else {
- /* create a js doppleganger of this argc/argv */
- switch_snprintf(buf, sizeof(buf), "~var argv = new Array(%d);", argc);
- eval_some_js(buf, cx, javascript_global_object, &rval);
- switch_snprintf(buf, sizeof(buf), "~var argc = %d", argc);
- eval_some_js(buf, cx, javascript_global_object, &rval);
-
- for (y = 0; y < argc; y++) {
- switch_snprintf(buf, sizeof(buf), "~argv[%d] = \"%s\";", x++, argv[y]);
- eval_some_js(buf, cx, javascript_global_object, &rval);
- }
- }
- }
-
- if (cx) {
- eval_some_js(script, cx, javascript_global_object, &rval);
- JS_DestroyContext(cx);
- }
-
-
- JS_DestroyRuntime(env.rt);
-
- return;
-}
-
-SWITCH_STANDARD_APP(js_dp_function)
-{
- js_parse_and_execute(session, data, NULL, NULL);
-}
-
-SWITCH_STANDARD_CHAT_APP(js_chat_function)
-{
-
- js_parse_and_execute(NULL, data, NULL, message);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-struct js_task {
- switch_memory_pool_t *pool;
- char *code;
-};
-
-static void *SWITCH_THREAD_FUNC js_thread_run(switch_thread_t *thread, void *obj)
-{
- struct js_task *task = (struct js_task *) obj;
- switch_memory_pool_t *pool;
-
- js_parse_and_execute(NULL, task->code, NULL, NULL);
-
- if ((pool = task->pool)) {
- switch_core_destroy_memory_pool(&pool);
- }
-
- return NULL;
-}
-
-static void js_thread_launch(const char *text)
-{
- switch_thread_t *thread;
- switch_threadattr_t *thd_attr = NULL;
- struct js_task *task;
- switch_memory_pool_t *pool;
-
- if (zstr(text)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "missing required input!\n");
- return;
- }
-
- 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;
- }
-
- task = switch_core_alloc(pool, sizeof(*task));
- task->pool = pool;
- task->code = switch_core_strdup(pool, text);
-
- switch_threadattr_create(&thd_attr, pool);
- switch_threadattr_detach_set(thd_attr, 1);
- switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
- switch_thread_create(&thread, thd_attr, js_thread_run, task, pool);
-}
-
-SWITCH_STANDARD_API(jsapi_function)
-{
- struct request_obj ro = { 0 };
- char *path_info = NULL;
-
- if (stream->param_event) {
- path_info = switch_event_get_header(stream->param_event, "http-path-info");
- }
-
- if (zstr(cmd) && path_info) {
- cmd = path_info;
- }
-
- if (zstr(cmd)) {
- stream->write_function(stream, "USAGE: %s\n", jsapi_interface->syntax);
- return SWITCH_STATUS_SUCCESS;
- }
-
- ro.cmd = cmd;
- ro.session = session;
- ro.stream = stream;
-
- js_parse_and_execute(session, (char *) cmd, &ro, NULL);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_STANDARD_API(launch_async)
-{
- if (zstr(cmd)) {
- stream->write_function(stream, "USAGE: %s\n", js_run_interface->syntax);
- return SWITCH_STATUS_SUCCESS;
- }
-
- js_thread_launch(cmd);
- stream->write_function(stream, "OK\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MODULE_LOAD_FUNCTION(mod_spidermonkey_load)
-{
- switch_application_interface_t *app_interface;
- switch_chat_application_interface_t *chat_app_interface;
-
- //switch_status_t status;
-
- //if ((status = init_js()) != SWITCH_STATUS_SUCCESS) {
- // return status;
- //}
-
- if (load_modules() != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_FALSE;
- }
-
- /* connect my internal structure to the blank pointer passed to me */
- *module_interface = switch_loadable_module_create_module_interface(pool, modname);
- SWITCH_ADD_API(js_run_interface, "jsrun", "run a script", launch_async, "jsrun