2006-02-26 23:10:22 +00:00
|
|
|
/*
|
|
|
|
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
|
|
|
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
*
|
|
|
|
* 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 <anthmct@yahoo.com>
|
|
|
|
* Portions created by the Initial Developer are Copyright (C)
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
* Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* mod_spidermonkey.c -- Javascript Module
|
|
|
|
*
|
|
|
|
*/
|
2006-03-01 06:25:56 +00:00
|
|
|
#ifndef HAVE_CURL
|
2006-03-01 00:58:32 +00:00
|
|
|
#define HAVE_CURL
|
2006-03-01 06:25:56 +00:00
|
|
|
#endif
|
2006-11-10 21:49:57 +00:00
|
|
|
#include "mod_spidermonkey.h"
|
|
|
|
|
2006-03-01 00:58:32 +00:00
|
|
|
#ifdef HAVE_CURL
|
|
|
|
#include <curl/curl.h>
|
|
|
|
#endif
|
2007-06-15 08:14:55 +00:00
|
|
|
static int foo = 0;
|
2008-07-14 23:22:41 +00:00
|
|
|
static jsval check_hangup_hook(struct js_session *jss, jsval *rp);
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_LOAD_FUNCTION(mod_spidermonkey_load);
|
|
|
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_spidermonkey_shutdown);
|
|
|
|
SWITCH_MODULE_DEFINITION(mod_spidermonkey, mod_spidermonkey_load, mod_spidermonkey_shutdown, NULL);
|
2006-11-10 21:49:57 +00:00
|
|
|
|
2008-05-31 16:48:54 +00:00
|
|
|
#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; \
|
2008-07-14 23:22:41 +00:00
|
|
|
} else check_hangup_hook(jss, NULL)
|
2007-06-15 08:14:55 +00:00
|
|
|
|
2007-06-22 19:59:57 +00:00
|
|
|
#define CHANNEL_SANITY_CHECK() do { \
|
2007-06-15 08:14:55 +00:00
|
|
|
if (!switch_channel_ready(channel)) { \
|
2007-06-22 19:59:57 +00:00
|
|
|
eval_some_js("~throw new Error(\"Session is not active!\");", cx, obj, rval); \
|
2007-06-15 08:14:55 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE); \
|
2007-06-22 19:59:57 +00:00
|
|
|
return JS_FALSE; \
|
2007-06-15 08:14:55 +00:00
|
|
|
} \
|
2007-06-24 21:01:55 +00:00
|
|
|
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; \
|
|
|
|
} \
|
2007-06-15 08:14:55 +00:00
|
|
|
} while (foo == 1)
|
|
|
|
|
2008-03-18 18:48:32 +00:00
|
|
|
#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)
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
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);
|
2007-06-19 05:54:16 +00:00
|
|
|
static JSBool session_set_callerdata(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval);
|
2008-08-11 16:50:45 +00:00
|
|
|
static switch_api_interface_t *js_run_interface = NULL;
|
|
|
|
static switch_api_interface_t *jsapi_interface = NULL;
|
2006-02-26 23:10:22 +00:00
|
|
|
|
|
|
|
static struct {
|
|
|
|
size_t gStackChunkSize;
|
|
|
|
jsuword gStackBase;
|
|
|
|
int gExitCode;
|
|
|
|
JSBool gQuitting;
|
|
|
|
FILE *gErrFile;
|
|
|
|
FILE *gOutFile;
|
|
|
|
int stackDummy;
|
|
|
|
JSRuntime *rt;
|
2008-07-03 23:54:35 +00:00
|
|
|
switch_event_node_t *node;
|
2006-02-26 23:10:22 +00:00
|
|
|
} globals;
|
|
|
|
|
|
|
|
static JSClass global_class = {
|
2007-03-29 22:31:56 +00:00
|
|
|
"Global", JSCLASS_HAS_PRIVATE,
|
2007-06-18 15:44:28 +00:00
|
|
|
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
2007-03-29 22:31:56 +00:00
|
|
|
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
2006-02-26 23:10:22 +00:00
|
|
|
};
|
|
|
|
|
2006-11-10 21:49:57 +00:00
|
|
|
|
|
|
|
static struct {
|
|
|
|
switch_hash_t *mod_hash;
|
|
|
|
switch_hash_t *load_hash;
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_memory_pool_t *pool;
|
2006-11-10 21:49:57 +00:00
|
|
|
} 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;
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
typedef enum {
|
2007-03-27 00:40:53 +00:00
|
|
|
S_HUP = (1 << 0),
|
2006-03-01 22:55:28 +00:00
|
|
|
} session_flag_t;
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
struct input_callback_state {
|
2006-02-28 02:08:42 +00:00
|
|
|
struct js_session *session_state;
|
|
|
|
char code_buffer[1024];
|
2006-02-28 05:55:22 +00:00
|
|
|
size_t code_buffer_len;
|
2006-02-28 02:08:42 +00:00
|
|
|
char ret_buffer[1024];
|
|
|
|
int ret_buffer_len;
|
|
|
|
int digit_count;
|
2006-11-09 05:39:04 +00:00
|
|
|
JSFunction *function;
|
|
|
|
jsval arg;
|
|
|
|
jsval ret;
|
|
|
|
JSContext *cx;
|
|
|
|
JSObject *obj;
|
2007-03-29 22:31:56 +00:00
|
|
|
jsrefcount saveDepth;
|
2006-02-28 02:08:42 +00:00
|
|
|
void *extra;
|
2007-11-29 18:41:40 +00:00
|
|
|
struct js_session *jss_a;
|
|
|
|
struct js_session *jss_b;
|
|
|
|
JSObject *session_obj_a;
|
|
|
|
JSObject *session_obj_b;
|
2006-02-28 02:08:42 +00:00
|
|
|
};
|
|
|
|
|
2006-03-02 17:36:23 +00:00
|
|
|
struct fileio_obj {
|
|
|
|
char *path;
|
|
|
|
unsigned int flags;
|
|
|
|
switch_file_t *fd;
|
2006-04-29 01:00:52 +00:00
|
|
|
switch_memory_pool_t *pool;
|
2006-03-02 17:46:15 +00:00
|
|
|
char *buf;
|
|
|
|
switch_size_t buflen;
|
2006-03-02 17:36:23 +00:00
|
|
|
int32 bufsize;
|
|
|
|
};
|
|
|
|
|
2007-05-14 03:17:38 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
static JSBool request_add_header(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2007-05-14 03:17:38 +00:00
|
|
|
{
|
|
|
|
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]));
|
2008-08-16 02:19:43 +00:00
|
|
|
switch_event_add_header_string(ro->stream->param_event, SWITCH_STACK_BOTTOM, hname, hval);
|
2007-05-14 03:17:38 +00:00
|
|
|
*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]));
|
2008-05-24 03:46:19 +00:00
|
|
|
char *val = switch_event_get_header(ro->stream->param_event, hname);
|
2007-05-14 03:17:38 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val));
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
static JSBool request_dump_env(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2007-05-14 03:17:38 +00:00
|
|
|
{
|
|
|
|
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;
|
2008-05-24 03:46:19 +00:00
|
|
|
if ((xml = switch_event_xmlize(ro->stream->param_event, SWITCH_VA_NONE))) {
|
2008-05-27 04:54:52 +00:00
|
|
|
xmlstr = switch_xml_toxml(xml, SWITCH_FALSE);
|
2007-05-14 03:17:38 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, xmlstr));
|
|
|
|
return JS_TRUE;
|
2008-05-27 04:54:52 +00:00
|
|
|
}
|
2007-05-14 03:17:38 +00:00
|
|
|
} else {
|
|
|
|
char *buf;
|
2008-05-24 03:46:19 +00:00
|
|
|
switch_event_serialize(ro->stream->param_event, &buf, SWITCH_TRUE);
|
2007-05-14 03:17:38 +00:00
|
|
|
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)
|
|
|
|
{
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-05-14 03:17:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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}
|
|
|
|
};
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
static JSBool request_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
|
2007-05-14 03:17:38 +00:00
|
|
|
{
|
|
|
|
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,
|
2007-06-15 17:05:20 +00:00
|
|
|
JS_PropertyStub, JS_PropertyStub, request_getProperty, DEFAULT_SET_PROPERTY,
|
2007-05-14 03:17:38 +00:00
|
|
|
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, request_destroy, NULL, NULL, NULL, NULL
|
|
|
|
};
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
static JSObject *new_request(JSContext * cx, JSObject * obj, struct request_obj *ro)
|
2007-05-14 03:17:38 +00:00
|
|
|
{
|
|
|
|
JSObject *Request;
|
|
|
|
if ((Request = JS_DefineObject(cx, obj, "request", &request_class, NULL, 0))) {
|
2008-05-27 04:54:52 +00:00
|
|
|
if ((JS_SetPrivate(cx, Request, ro) && JS_DefineProperties(cx, Request, request_props) && JS_DefineFunctions(cx, Request, request_methods))) {
|
2007-05-14 03:17:38 +00:00
|
|
|
return Request;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-09-11 17:33:06 +00:00
|
|
|
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;
|
|
|
|
|
2007-09-11 23:49:28 +00:00
|
|
|
if (!((pcre_obj = malloc(sizeof(*pcre_obj))))) {
|
|
|
|
abort();
|
2007-09-11 17:33:06 +00:00
|
|
|
}
|
2007-09-11 23:49:28 +00:00
|
|
|
memset(pcre_obj, 0, sizeof(*pcre_obj));
|
|
|
|
JS_SetPrivate(cx, obj, pcre_obj);
|
|
|
|
return JS_TRUE;
|
2007-09-11 17:33:06 +00:00
|
|
|
|
|
|
|
}
|
2007-05-14 03:17:38 +00:00
|
|
|
|
2007-09-11 17:33:06 +00:00
|
|
|
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) {
|
2008-05-27 04:54:52 +00:00
|
|
|
string = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
regex_string = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
2007-09-11 17:33:06 +00:00
|
|
|
switch_regex_safe_free(pcre_obj->re);
|
|
|
|
switch_safe_free(pcre_obj->string);
|
|
|
|
pcre_obj->string = strdup(string);
|
2008-05-27 04:54:52 +00:00
|
|
|
pcre_obj->proceed = switch_regex_perform(pcre_obj->string, regex_string, &pcre_obj->re, pcre_obj->ovector,
|
2007-09-11 17:33:06 +00:00
|
|
|
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;
|
|
|
|
}
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-09-11 17:33:06 +00:00
|
|
|
if (argc > 0) {
|
|
|
|
uint32_t len;
|
2008-05-27 04:54:52 +00:00
|
|
|
subst_string = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
2007-09-11 17:33:06 +00:00
|
|
|
len = (uint32_t) (strlen(pcre_obj->string) + strlen(subst_string) + 10);
|
|
|
|
substituted = malloc(len);
|
2007-12-12 22:49:02 +00:00
|
|
|
switch_assert(substituted != NULL);
|
2007-09-11 17:33:06 +00:00
|
|
|
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
|
|
|
|
};
|
2007-05-14 03:17:38 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj {
|
|
|
|
switch_event_t *event;
|
|
|
|
int freed;
|
|
|
|
};
|
|
|
|
|
2006-08-18 01:28:50 +00:00
|
|
|
/* Event Object */
|
|
|
|
/*********************************************************************************/
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool event_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
|
|
|
if (argc > 0) {
|
|
|
|
switch_event_t *event;
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo;
|
2006-08-18 01:28:50 +00:00
|
|
|
switch_event_types_t etype;
|
|
|
|
char *ename = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if ((eo = malloc(sizeof(*eo)))) {
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (switch_name_event(ename, &etype) != SWITCH_STATUS_SUCCESS) {
|
2007-04-02 20:20:46 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown event %s\n", ename);
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (etype == SWITCH_EVENT_CUSTOM) {
|
|
|
|
char *subclass_name;
|
2007-07-24 21:26:04 +00:00
|
|
|
if (argc > 1) {
|
|
|
|
subclass_name = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
|
|
|
} else {
|
|
|
|
subclass_name = "none";
|
2006-11-09 05:39:04 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (switch_event_create_subclass(&event, etype, subclass_name) != SWITCH_STATUS_SUCCESS) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-11-09 05:39:04 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2007-04-02 20:20:46 +00:00
|
|
|
if (switch_event_create(&event, etype) != SWITCH_STATUS_SUCCESS) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-11-09 05:39:04 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2006-08-18 01:28:50 +00:00
|
|
|
}
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
eo->event = event;
|
|
|
|
eo->freed = 0;
|
|
|
|
|
|
|
|
JS_SetPrivate(cx, obj, eo);
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2006-08-18 01:28:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static void event_destroy(JSContext * cx, JSObject * obj)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo = JS_GetPrivate(cx, obj);
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (eo) {
|
|
|
|
if (!eo->freed && eo->event) {
|
|
|
|
switch_event_destroy(&eo->event);
|
|
|
|
}
|
|
|
|
switch_safe_free(eo);
|
2006-08-18 01:28:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool event_add_header(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo = JS_GetPrivate(cx, obj);
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (!eo || eo->freed) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argc > 1) {
|
|
|
|
char *hname = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
char *hval = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
2008-08-16 02:19:43 +00:00
|
|
|
switch_event_add_header_string(eo->event, SWITCH_STACK_BOTTOM, hname, hval);
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool event_get_header(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo = JS_GetPrivate(cx, obj);
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (!eo) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argc > 0) {
|
|
|
|
char *hname = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
2006-11-09 05:39:04 +00:00
|
|
|
char *val = switch_event_get_header(eo->event, hname);
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val));
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool event_add_body(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo = JS_GetPrivate(cx, obj);
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (!eo || eo->freed) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argc > 0) {
|
|
|
|
char *body = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
2007-02-14 03:32:13 +00:00
|
|
|
switch_event_add_body(eo->event, "%s", body);
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool event_get_body(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo = JS_GetPrivate(cx, obj);
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (!eo) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_event_get_body(eo->event)));
|
2006-11-09 05:39:04 +00:00
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool event_get_type(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-11-09 05:39:04 +00:00
|
|
|
{
|
|
|
|
struct event_obj *eo = JS_GetPrivate(cx, obj);
|
|
|
|
|
|
|
|
if (!eo) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-11-09 05:39:04 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_event_name(eo->event->event_id)));
|
|
|
|
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool event_serialize(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo = JS_GetPrivate(cx, obj);
|
2006-11-11 19:32:45 +00:00
|
|
|
char *buf;
|
2006-08-18 01:28:50 +00:00
|
|
|
uint8_t isxml = 0;
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (!eo) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argc > 0) {
|
|
|
|
char *arg = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
if (!strcasecmp(arg, "xml")) {
|
|
|
|
isxml++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isxml) {
|
|
|
|
switch_xml_t xml;
|
|
|
|
char *xmlstr;
|
2007-03-29 22:31:56 +00:00
|
|
|
if ((xml = switch_event_xmlize(eo->event, SWITCH_VA_NONE))) {
|
2007-11-30 23:45:27 +00:00
|
|
|
xmlstr = switch_xml_toxml(xml, SWITCH_FALSE);
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, xmlstr));
|
2006-08-18 01:28:50 +00:00
|
|
|
switch_xml_free(xml);
|
2007-03-29 22:31:56 +00:00
|
|
|
free(xmlstr);
|
2006-08-18 01:28:50 +00:00
|
|
|
} else {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
}
|
|
|
|
} else {
|
2007-12-11 22:19:49 +00:00
|
|
|
if (switch_event_serialize(eo->event, &buf, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
|
2006-11-11 19:32:45 +00:00
|
|
|
switch_safe_free(buf);
|
|
|
|
}
|
2006-08-18 01:28:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool event_fire(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo = JS_GetPrivate(cx, obj);
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (eo) {
|
|
|
|
switch_event_fire(&eo->event);
|
2006-08-18 01:28:50 +00:00
|
|
|
JS_SetPrivate(cx, obj, NULL);
|
2006-11-09 05:39:04 +00:00
|
|
|
switch_safe_free(eo);
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool event_destroy_(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo = JS_GetPrivate(cx, obj);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (eo) {
|
|
|
|
if (!eo->freed) {
|
|
|
|
switch_event_destroy(&eo->event);
|
|
|
|
}
|
2006-08-18 01:28:50 +00:00
|
|
|
JS_SetPrivate(cx, obj, NULL);
|
2006-11-09 05:39:04 +00:00
|
|
|
switch_safe_free(eo);
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
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},
|
2006-11-09 05:39:04 +00:00
|
|
|
{"getType", event_get_type, 1},
|
2006-08-18 01:28:50 +00:00
|
|
|
{"serialize", event_serialize, 0},
|
|
|
|
{"fire", event_fire, 0},
|
|
|
|
{"destroy", event_destroy_, 0},
|
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
|
|
|
static JSPropertySpec event_props[] = {
|
2007-03-29 22:31:56 +00:00
|
|
|
{"ready", EVENT_READY, JSPROP_READONLY | JSPROP_PERMANENT},
|
2006-08-18 01:28:50 +00:00
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool event_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
|
|
|
JSBool res = JS_TRUE;
|
|
|
|
switch_event_t *event = JS_GetPrivate(cx, obj);
|
|
|
|
char *name;
|
|
|
|
int param = 0;
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (!event) {
|
|
|
|
*vp = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
|
|
|
|
2006-08-18 01:28:50 +00:00
|
|
|
name = JS_GetStringBytes(JS_ValueToString(cx, id));
|
2007-03-29 22:31:56 +00:00
|
|
|
/* 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) {
|
2006-08-18 01:28:50 +00:00
|
|
|
case EVENT_READY:
|
2007-03-29 22:31:56 +00:00
|
|
|
*vp = BOOLEAN_TO_JSVAL(JS_TRUE);
|
2006-08-18 01:28:50 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
JSClass event_class = {
|
2007-03-29 22:31:56 +00:00
|
|
|
"Event", JSCLASS_HAS_PRIVATE,
|
2007-06-15 17:05:20 +00:00
|
|
|
JS_PropertyStub, JS_PropertyStub, event_getProperty, DEFAULT_SET_PROPERTY,
|
2007-03-29 22:31:56 +00:00
|
|
|
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, event_destroy, NULL, NULL, NULL,
|
2006-08-18 01:28:50 +00:00
|
|
|
event_construct
|
|
|
|
};
|
|
|
|
|
2007-12-27 20:45:26 +00:00
|
|
|
/* Dtmf Object */
|
|
|
|
/*********************************************************************************/
|
|
|
|
static JSBool dtmf_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
|
|
|
{
|
2007-12-28 20:52:48 +00:00
|
|
|
switch_dtmf_t *dtmf;
|
2008-04-18 17:03:34 +00:00
|
|
|
int32 duration = switch_core_default_dtmf_duration(0);
|
2007-12-28 20:52:48 +00:00
|
|
|
char *ename;
|
2007-12-27 20:45:26 +00:00
|
|
|
|
2007-12-28 20:52:48 +00:00
|
|
|
if (argc > 0) {
|
|
|
|
ename = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
} else {
|
|
|
|
eval_some_js("~throw new Error(\"Invalid Args\");", cx, obj, rval);
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
2007-12-27 20:45:26 +00:00
|
|
|
|
2007-12-28 20:52:48 +00:00
|
|
|
if (argc > 1) {
|
|
|
|
JS_ValueToInt32(cx, argv[1], &duration);
|
|
|
|
if (duration <= 0) {
|
2008-04-18 17:03:34 +00:00
|
|
|
duration = switch_core_default_dtmf_duration(0);
|
2007-12-27 20:45:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-28 20:52:48 +00:00
|
|
|
if ((dtmf = malloc(sizeof(*dtmf)))) {
|
|
|
|
JS_SetPrivate(cx, obj, dtmf);
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-12-27 20:45:26 +00:00
|
|
|
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:
|
|
|
|
{
|
2008-05-27 04:54:52 +00:00
|
|
|
*vp = INT_TO_JSVAL((int) dtmf->duration);
|
2007-12-27 20:45:26 +00:00
|
|
|
}
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static void js_error(JSContext * cx, const char *message, JSErrorReport * report)
|
2006-02-26 23:10:22 +00:00
|
|
|
{
|
2007-03-29 22:31:56 +00:00
|
|
|
const char *filename = __FILE__;
|
|
|
|
int line = __LINE__;
|
|
|
|
const char *text = "";
|
|
|
|
char *ex = "";
|
|
|
|
|
2007-01-19 21:56:31 +00:00
|
|
|
if (message && report) {
|
2007-03-29 22:31:56 +00:00
|
|
|
if (report->filename) {
|
|
|
|
filename = report->filename;
|
|
|
|
}
|
|
|
|
line = report->lineno;
|
|
|
|
if (report->linebuf) {
|
|
|
|
text = report->linebuf;
|
|
|
|
ex = "near ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!message) {
|
|
|
|
message = "(N/A)";
|
|
|
|
}
|
|
|
|
|
2007-06-20 10:50:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, filename, modname, line, NULL, SWITCH_LOG_ERROR, "%s %s%s\n", ex, message, text);
|
2006-02-26 23:10:22 +00:00
|
|
|
}
|
|
|
|
|
2006-11-28 20:52:04 +00:00
|
|
|
static switch_status_t sm_load_file(char *filename)
|
2006-11-10 21:49:57 +00:00
|
|
|
{
|
|
|
|
sm_loadable_module_t *module = NULL;
|
2007-03-09 20:44:13 +00:00
|
|
|
switch_dso_handle_t *dso = NULL;
|
|
|
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
|
|
|
switch_dso_handle_sym_t function_handle = NULL;
|
2006-11-12 00:42:51 +00:00
|
|
|
spidermonkey_init_t spidermonkey_init = NULL;
|
2006-11-15 03:59:40 +00:00
|
|
|
const sm_module_interface_t *module_interface = NULL, *mp;
|
2006-11-10 21:49:57 +00:00
|
|
|
|
|
|
|
int loading = 1;
|
|
|
|
const char *err = NULL;
|
|
|
|
char derr[512] = "";
|
|
|
|
|
2007-12-12 22:49:02 +00:00
|
|
|
switch_assert(filename != NULL);
|
2006-11-10 21:49:57 +00:00
|
|
|
|
2007-03-09 20:44:13 +00:00
|
|
|
status = switch_dso_load(&dso, filename, module_manager.pool);
|
2006-11-10 21:49:57 +00:00
|
|
|
|
|
|
|
while (loading) {
|
2007-03-09 20:44:13 +00:00
|
|
|
if (status != SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_dso_error(dso, derr, sizeof(derr));
|
2006-11-10 21:49:57 +00:00
|
|
|
err = derr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-03-09 20:44:13 +00:00
|
|
|
status = switch_dso_sym(&function_handle, dso, "spidermonkey_init");
|
2007-03-29 22:31:56 +00:00
|
|
|
spidermonkey_init = (spidermonkey_init_t) (intptr_t) function_handle;
|
|
|
|
|
2006-11-10 21:49:57 +00:00
|
|
|
if (spidermonkey_init == NULL) {
|
|
|
|
err = "Cannot Load";
|
|
|
|
break;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-10 21:49:57 +00:00
|
|
|
if (spidermonkey_init(&module_interface) != SWITCH_STATUS_SUCCESS) {
|
|
|
|
err = "Module load routine returned an error";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-11-28 20:52:04 +00:00
|
|
|
if (!(module = (sm_loadable_module_t *) switch_core_permanent_alloc(sizeof(*module)))) {
|
2006-11-10 21:49:57 +00:00
|
|
|
err = "Could not allocate memory\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
loading = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err) {
|
2007-08-06 21:25:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Loading module %s\n**%s**\n", filename, err);
|
2006-11-10 21:49:57 +00:00
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
module->filename = switch_core_permanent_strdup(filename);
|
|
|
|
module->spidermonkey_init = spidermonkey_init;
|
|
|
|
module->module_interface = module_interface;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-10 21:49:57 +00:00
|
|
|
module->lib = dso;
|
|
|
|
|
|
|
|
switch_core_hash_insert(module_manager.mod_hash, (char *) module->filename, (void *) module);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-28 20:52:04 +00:00
|
|
|
for (mp = module->module_interface; mp; mp = mp->next) {
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_core_hash_insert(module_manager.load_hash, (char *) mp->name, (void *) mp);
|
2006-11-10 21:49:57 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-10 21:49:57 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module->filename);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-10 21:49:57 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-08-03 21:29:01 +00:00
|
|
|
static switch_status_t sm_load_module(const char *dir, const char *fname)
|
2006-11-10 21:49:57 +00:00
|
|
|
{
|
|
|
|
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);
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(path, len, "%s%s%s", dir, SWITCH_PATH_SEPARATOR, file);
|
2006-11-10 21:49:57 +00:00
|
|
|
} else {
|
|
|
|
len = strlen(dir);
|
|
|
|
len += strlen(file);
|
|
|
|
len += 8;
|
|
|
|
path = (char *) switch_core_alloc(module_manager.pool, len);
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(path, len, "%s%s%s%s", dir, SWITCH_PATH_SEPARATOR, file, ext);
|
2006-11-10 21:49:57 +00:00
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-28 20:52:04 +00:00
|
|
|
return sm_load_file(path);
|
2006-11-10 21:49:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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, module_manager.pool);
|
|
|
|
switch_core_hash_init(&module_manager.load_hash, module_manager.pool);
|
|
|
|
|
|
|
|
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");
|
2007-12-30 00:22:51 +00:00
|
|
|
if (!switch_strlen_zero(val) && strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT)) {
|
2006-11-10 21:49:57 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
|
|
|
|
continue;
|
|
|
|
}
|
2007-08-03 21:29:01 +00:00
|
|
|
sm_load_module(SWITCH_GLOBAL_dirs.mod_dir, val);
|
2006-11-10 21:49:57 +00:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch_xml_free(xml);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-10 21:49:57 +00:00
|
|
|
} else {
|
2008-10-11 06:19:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Open of %s failed\n", cf);
|
2006-11-10 21:49:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t init_js(void)
|
2006-02-26 23:10:22 +00:00
|
|
|
{
|
|
|
|
memset(&globals, 0, sizeof(globals));
|
|
|
|
globals.gQuitting = JS_FALSE;
|
|
|
|
globals.gErrFile = NULL;
|
|
|
|
globals.gOutFile = NULL;
|
|
|
|
globals.gStackChunkSize = 8192;
|
2007-03-29 22:31:56 +00:00
|
|
|
globals.gStackBase = (jsuword) & globals.stackDummy;
|
2006-02-26 23:10:22 +00:00
|
|
|
globals.gErrFile = stderr;
|
|
|
|
globals.gOutFile = stdout;
|
|
|
|
|
2006-03-02 14:52:51 +00:00
|
|
|
if (!(globals.rt = JS_NewRuntime(64L * 1024L * 1024L))) {
|
2006-02-26 23:10:22 +00:00
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-10 21:49:57 +00:00
|
|
|
if (load_modules() != SWITCH_STATUS_SUCCESS) {
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
2006-02-26 23:10:22 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
JSObject *new_js_event(switch_event_t *event, char *name, JSContext * cx, JSObject * obj)
|
2006-02-26 23:10:22 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
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))) {
|
2007-03-30 00:13:31 +00:00
|
|
|
if ((JS_SetPrivate(cx, Event, eo) && JS_DefineProperties(cx, Event, event_props) && JS_DefineFunctions(cx, Event, event_methods))) {
|
2006-11-09 05:39:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Event;
|
|
|
|
}
|
|
|
|
|
2007-12-27 20:45:26 +00:00
|
|
|
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 {
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return DTMF;
|
|
|
|
}
|
|
|
|
|
2007-04-28 14:48:18 +00:00
|
|
|
#define MAX_STACK_DEPTH 2
|
2006-11-09 05:39:04 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static switch_status_t js_common_callback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
|
2006-11-09 05:39:04 +00:00
|
|
|
{
|
|
|
|
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;
|
2008-07-29 16:57:38 +00:00
|
|
|
jsval ret, nval, *rval = &nval;
|
2007-06-22 19:59:57 +00:00
|
|
|
JSContext *cx = cb_state->cx;
|
|
|
|
JSObject *obj = cb_state->obj;
|
2008-07-29 16:57:38 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2006-11-09 05:39:04 +00:00
|
|
|
|
2007-04-26 23:09:26 +00:00
|
|
|
jss->stack_depth++;
|
|
|
|
|
2007-12-27 20:45:26 +00:00
|
|
|
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 {
|
2007-12-28 22:04:56 +00:00
|
|
|
argv[argc++] = OBJECT_TO_JSVAL(cb_state->session_state->obj);
|
2007-12-27 20:45:26 +00:00
|
|
|
}
|
|
|
|
|
2006-07-12 18:39:19 +00:00
|
|
|
switch (itype) {
|
2006-11-09 05:39:04 +00:00
|
|
|
case SWITCH_INPUT_TYPE_EVENT:
|
|
|
|
if ((event = (switch_event_t *) input)) {
|
|
|
|
if ((Event = new_js_event(event, "_XX_EVENT_XX_", cb_state->cx, cb_state->obj))) {
|
2007-03-29 22:31:56 +00:00
|
|
|
argv[argc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(cb_state->cx, "event"));
|
2006-11-09 05:39:04 +00:00
|
|
|
argv[argc++] = OBJECT_TO_JSVAL(Event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!Event) {
|
2007-04-26 23:09:26 +00:00
|
|
|
jss->stack_depth--;
|
2006-07-12 18:39:19 +00:00
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
2006-11-09 05:39:04 +00:00
|
|
|
break;
|
2008-05-27 04:54:52 +00:00
|
|
|
case SWITCH_INPUT_TYPE_DTMF:
|
2007-12-22 00:32:20 +00:00
|
|
|
{
|
2007-12-27 20:45:26 +00:00
|
|
|
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-12-27 20:45:26 +00:00
|
|
|
if (dtmf) {
|
|
|
|
if ((Event = new_js_dtmf(dtmf, "_XX_DTMF_XX_", cb_state->cx, cb_state->obj))) {
|
|
|
|
argv[argc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(cb_state->cx, "dtmf"));
|
|
|
|
argv[argc++] = OBJECT_TO_JSVAL(Event);
|
|
|
|
}
|
|
|
|
}
|
2007-12-22 00:32:20 +00:00
|
|
|
}
|
2006-11-09 05:39:04 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-02-28 02:08:42 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (cb_state->arg) {
|
|
|
|
argv[argc++] = cb_state->arg;
|
|
|
|
}
|
|
|
|
|
2007-04-26 23:09:26 +00:00
|
|
|
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;
|
|
|
|
}
|
2008-07-14 23:22:41 +00:00
|
|
|
|
2008-07-29 16:57:38 +00:00
|
|
|
JS_ResumeRequest(cb_state->cx, cb_state->saveDepth);
|
|
|
|
check_hangup_hook(jss, &ret);
|
|
|
|
cb_state->saveDepth = JS_SuspendRequest(cb_state->cx);
|
|
|
|
|
|
|
|
if (ret == JS_TRUE) {
|
2008-07-14 23:22:41 +00:00
|
|
|
JS_ResumeRequest(cb_state->cx, cb_state->saveDepth);
|
|
|
|
JS_CallFunction(cb_state->cx, cb_state->obj, cb_state->function, argc, argv, &cb_state->ret);
|
|
|
|
cb_state->saveDepth = JS_SuspendRequest(cb_state->cx);
|
|
|
|
jss->stack_depth--;
|
|
|
|
}
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
2006-07-12 18:39:19 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
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)
|
2006-11-09 05:39:04 +00:00
|
|
|
{
|
|
|
|
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 ((status = js_common_callback(session, input, itype, buf, buflen)) != SWITCH_STATUS_SUCCESS) {
|
|
|
|
return status;
|
|
|
|
}
|
2006-11-10 01:40:22 +00:00
|
|
|
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if ((ret = JS_GetStringBytes(JS_ValueToString(cb_state->cx, cb_state->ret)))) {
|
|
|
|
if (!strncasecmp(ret, "speed", 4)) {
|
|
|
|
char *p;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if ((p = strchr(ret, ':'))) {
|
|
|
|
p++;
|
|
|
|
if (*p == '+' || *p == '-') {
|
|
|
|
int step;
|
|
|
|
if (!(step = atoi(p))) {
|
|
|
|
step = 1;
|
2006-02-28 21:21:48 +00:00
|
|
|
}
|
2006-11-09 05:39:04 +00:00
|
|
|
fh->speed += step;
|
2006-02-28 21:21:48 +00:00
|
|
|
} else {
|
2006-11-09 05:39:04 +00:00
|
|
|
int speed = atoi(p);
|
|
|
|
fh->speed = speed;
|
2006-02-28 21:21:48 +00:00
|
|
|
}
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2006-11-09 05:39:04 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-07-05 17:03:14 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
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, "restart")) {
|
2007-10-23 18:25:58 +00:00
|
|
|
uint32_t pos = 0;
|
2006-11-09 05:39:04 +00:00
|
|
|
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;
|
2007-10-23 18:25:58 +00:00
|
|
|
uint32_t samps = 0;
|
|
|
|
uint32_t pos = 0;
|
2006-11-09 05:39:04 +00:00
|
|
|
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) {
|
2007-10-19 15:31:02 +00:00
|
|
|
samps = step * (codec->implementation->actual_samples_per_second / 1000);
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_core_file_seek(fh, &pos, samps, SEEK_CUR);
|
2006-02-28 21:21:48 +00:00
|
|
|
} else {
|
2007-10-23 18:25:58 +00:00
|
|
|
samps = abs(step) * (codec->implementation->actual_samples_per_second / 1000);
|
2006-11-09 05:39:04 +00:00
|
|
|
switch_core_file_seek(fh, &pos, fh->pos - samps, SEEK_SET);
|
2006-02-28 21:21:48 +00:00
|
|
|
}
|
2006-11-09 05:39:04 +00:00
|
|
|
} else {
|
2007-10-19 15:31:02 +00:00
|
|
|
samps = atoi(p) * (codec->implementation->actual_samples_per_second / 1000);
|
2006-11-09 05:39:04 +00:00
|
|
|
switch_core_file_seek(fh, &pos, samps, SEEK_SET);
|
2006-03-02 14:52:51 +00:00
|
|
|
}
|
2006-07-12 18:39:19 +00:00
|
|
|
}
|
2006-02-28 02:08:42 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2006-02-28 02:08:42 +00:00
|
|
|
}
|
2006-07-12 18:39:19 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
|
2007-03-29 22:31:56 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
2006-11-09 05:39:04 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_BREAK;
|
2006-11-10 01:40:22 +00:00
|
|
|
|
2006-02-28 02:08:42 +00:00
|
|
|
}
|
2006-07-12 18:39:19 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2006-02-28 02:08:42 +00:00
|
|
|
}
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
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)
|
2006-03-01 04:47:34 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
char *ret;
|
|
|
|
switch_status_t status;
|
|
|
|
struct input_callback_state *cb_state = buf;
|
|
|
|
switch_file_handle_t *fh = cb_state->extra;
|
2006-03-01 04:47:34 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if ((status = js_common_callback(session, input, itype, buf, buflen)) != SWITCH_STATUS_SUCCESS) {
|
|
|
|
return status;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
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);
|
2006-03-01 04:47:34 +00:00
|
|
|
}
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2006-11-09 05:39:04 +00:00
|
|
|
} 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;
|
|
|
|
}
|
2006-07-12 18:39:19 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
|
2007-03-29 22:31:56 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
2006-11-10 01:40:22 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
return SWITCH_STATUS_BREAK;
|
2006-11-10 01:40:22 +00:00
|
|
|
|
2006-03-01 04:47:34 +00:00
|
|
|
}
|
|
|
|
|
2006-07-12 18:39:19 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2006-03-01 04:47:34 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
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)
|
2006-03-01 04:47:34 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
char *ret;
|
|
|
|
switch_status_t status;
|
|
|
|
struct input_callback_state *cb_state = buf;
|
2006-03-01 04:47:34 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if ((status = js_common_callback(session, input, itype, buf, buflen)) != SWITCH_STATUS_SUCCESS) {
|
|
|
|
return status;
|
|
|
|
}
|
2006-07-12 18:39:19 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if ((ret = JS_GetStringBytes(JS_ValueToString(cb_state->cx, cb_state->ret)))) {
|
|
|
|
if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2006-03-01 04:47:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-10 01:40:22 +00:00
|
|
|
return SWITCH_STATUS_BREAK;
|
2006-03-01 04:47:34 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_flush_digits(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 21:18:41 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2008-03-18 18:48:32 +00:00
|
|
|
switch_channel_t *channel;
|
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2008-03-18 18:48:32 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
|
|
|
CHANNEL_MEDIA_SANITY_CHECK();
|
2007-03-27 00:40:53 +00:00
|
|
|
|
2008-01-28 07:26:10 +00:00
|
|
|
switch_channel_flush_dtmf(switch_core_session_get_channel(jss->session));
|
2006-08-18 21:18:41 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
|
|
|
return JS_TRUE;
|
2006-08-18 21:18:41 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_flush_events(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 21:18:41 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
|
|
|
switch_event_t *event;
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2007-03-27 00:40:53 +00:00
|
|
|
if (!jss || !jss->session) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2007-03-27 00:40:53 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2006-08-18 21:18:41 +00:00
|
|
|
while (switch_core_session_dequeue_event(jss->session, &event) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_destroy(&event);
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
|
|
|
return JS_TRUE;
|
|
|
|
|
2006-08-18 21:18:41 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_recordfile(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-01 04:47:34 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-03-01 04:47:34 +00:00
|
|
|
char *file_name = NULL;
|
|
|
|
void *bp = NULL;
|
|
|
|
int len = 0;
|
2006-07-12 18:39:19 +00:00
|
|
|
switch_input_callback_function_t dtmf_func = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
struct input_callback_state cb_state = { 0 };
|
|
|
|
switch_file_handle_t fh = { 0 };
|
2006-11-09 05:39:04 +00:00
|
|
|
JSFunction *function;
|
2007-03-29 22:31:56 +00:00
|
|
|
int32 limit = 0;
|
|
|
|
switch_input_args_t args = { 0 };
|
2008-07-14 23:22:41 +00:00
|
|
|
jsval ret = JS_TRUE;
|
2006-03-01 04:47:34 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2006-03-01 04:47:34 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2007-06-15 08:14:55 +00:00
|
|
|
CHANNEL_SANITY_CHECK();
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2008-03-18 18:48:32 +00:00
|
|
|
CHANNEL_MEDIA_SANITY_CHECK();
|
|
|
|
|
2006-03-01 04:47:34 +00:00
|
|
|
if (argc > 0) {
|
|
|
|
file_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
if (switch_strlen_zero(file_name)) {
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (argc > 1) {
|
2006-11-09 05:39:04 +00:00
|
|
|
if ((function = JS_ValueToFunction(cx, argv[1]))) {
|
2006-03-01 04:47:34 +00:00
|
|
|
memset(&cb_state, 0, sizeof(cb_state));
|
|
|
|
cb_state.session_state = jss;
|
2006-11-09 05:39:04 +00:00
|
|
|
cb_state.function = function;
|
|
|
|
cb_state.cx = cx;
|
2007-03-29 22:31:56 +00:00
|
|
|
cb_state.obj = obj;
|
2006-11-09 05:39:04 +00:00
|
|
|
if (argc > 2) {
|
2007-03-29 22:31:56 +00:00
|
|
|
cb_state.arg = argv[2];
|
|
|
|
}
|
2006-11-09 05:39:04 +00:00
|
|
|
|
|
|
|
dtmf_func = js_record_input_callback;
|
2006-03-01 04:47:34 +00:00
|
|
|
bp = &cb_state;
|
|
|
|
len = sizeof(cb_state);
|
|
|
|
}
|
2006-11-28 21:46:29 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (argc > 3) {
|
|
|
|
JS_ValueToInt32(cx, argv[3], &limit);
|
|
|
|
}
|
2006-11-29 17:10:40 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (argc > 4) {
|
|
|
|
int32 thresh;
|
|
|
|
JS_ValueToInt32(cx, argv[4], &thresh);
|
|
|
|
fh.thresh = thresh;
|
|
|
|
}
|
2006-11-29 17:10:40 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (argc > 5) {
|
|
|
|
int32 silence_hits;
|
|
|
|
JS_ValueToInt32(cx, argv[5], &silence_hits);
|
|
|
|
fh.silence_hits = silence_hits;
|
|
|
|
}
|
2006-03-01 04:47:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cb_state.extra = &fh;
|
2007-03-29 22:31:56 +00:00
|
|
|
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;
|
2008-07-29 16:57:38 +00:00
|
|
|
|
2006-12-23 16:40:37 +00:00
|
|
|
switch_ivr_record_file(jss->session, &fh, file_name, &args, limit);
|
2007-03-29 22:31:56 +00:00
|
|
|
JS_ResumeRequest(cx, cb_state.saveDepth);
|
2008-07-29 16:57:38 +00:00
|
|
|
check_hangup_hook(jss, &ret);
|
2006-11-09 05:39:04 +00:00
|
|
|
*rval = cb_state.ret;
|
|
|
|
|
2008-07-14 23:22:41 +00:00
|
|
|
return ret;
|
2006-11-09 05:39:04 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_collect_input(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-11-09 05:39:04 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
|
|
|
switch_channel_t *channel;
|
|
|
|
void *bp = NULL;
|
|
|
|
int len = 0;
|
|
|
|
int32 to = 0;
|
|
|
|
switch_input_callback_function_t dtmf_func = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
struct input_callback_state cb_state = { 0 };
|
2006-11-09 05:39:04 +00:00
|
|
|
JSFunction *function;
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_input_args_t args = { 0 };
|
2008-07-14 23:22:41 +00:00
|
|
|
jsval ret = JS_TRUE;
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2006-11-09 05:39:04 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2007-06-15 08:14:55 +00:00
|
|
|
CHANNEL_SANITY_CHECK();
|
2008-03-18 18:48:32 +00:00
|
|
|
CHANNEL_MEDIA_SANITY_CHECK();
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (argc > 0) {
|
|
|
|
if ((function = JS_ValueToFunction(cx, argv[0]))) {
|
|
|
|
memset(&cb_state, 0, sizeof(cb_state));
|
|
|
|
cb_state.function = function;
|
|
|
|
|
|
|
|
if (argc > 1) {
|
2007-03-29 22:31:56 +00:00
|
|
|
cb_state.arg = argv[1];
|
|
|
|
}
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
cb_state.session_state = jss;
|
|
|
|
cb_state.cx = cx;
|
2007-03-29 22:31:56 +00:00
|
|
|
cb_state.obj = obj;
|
2006-11-09 05:39:04 +00:00
|
|
|
dtmf_func = js_collect_input_callback;
|
|
|
|
bp = &cb_state;
|
|
|
|
len = sizeof(cb_state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argc > 2) {
|
|
|
|
JS_ValueToInt32(jss->cx, argv[2], &to);
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
cb_state.saveDepth = JS_SuspendRequest(cx);
|
|
|
|
args.input_callback = dtmf_func;
|
|
|
|
args.buf = bp;
|
|
|
|
args.buflen = len;
|
2008-07-14 23:22:41 +00:00
|
|
|
|
2006-12-23 16:40:37 +00:00
|
|
|
switch_ivr_collect_digits_callback(jss->session, &args, to);
|
2007-03-29 22:31:56 +00:00
|
|
|
JS_ResumeRequest(cx, cb_state.saveDepth);
|
2008-07-29 16:57:38 +00:00
|
|
|
check_hangup_hook(jss, &ret);
|
2006-11-10 01:40:22 +00:00
|
|
|
*rval = cb_state.ret;
|
2006-03-01 04:47:34 +00:00
|
|
|
|
2008-07-14 23:22:41 +00:00
|
|
|
return ret;
|
2006-03-01 04:47:34 +00:00
|
|
|
}
|
|
|
|
|
2007-02-09 21:56:44 +00:00
|
|
|
/* session.sayphrase(phrase_name, phrase_data, language, dtmf_callback, dtmf_callback_args)*/
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_sayphrase(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2007-02-09 21:56:44 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
|
|
|
switch_channel_t *channel;
|
|
|
|
char *phrase_name = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
char *phrase_data = NULL;
|
|
|
|
char *phrase_lang = NULL;
|
2007-08-21 19:00:06 +00:00
|
|
|
char *tmp = NULL;
|
2007-02-09 21:56:44 +00:00
|
|
|
//char *input_callback = NULL;
|
|
|
|
void *bp = NULL;
|
|
|
|
int len = 0;
|
|
|
|
switch_input_callback_function_t dtmf_func = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
struct input_callback_state cb_state = { 0 };
|
2007-02-09 21:56:44 +00:00
|
|
|
JSFunction *function;
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_input_args_t args = { 0 };
|
2008-07-14 23:22:41 +00:00
|
|
|
jsval ret = JS_TRUE;
|
2007-02-09 21:56:44 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2007-02-09 21:56:44 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2007-06-15 08:14:55 +00:00
|
|
|
CHANNEL_SANITY_CHECK();
|
2008-03-18 18:48:32 +00:00
|
|
|
CHANNEL_MEDIA_SANITY_CHECK();
|
2007-02-09 21:56:44 +00:00
|
|
|
|
|
|
|
if (argc > 0) {
|
|
|
|
phrase_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
if (switch_strlen_zero(phrase_name)) {
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
2007-02-09 22:55:48 +00:00
|
|
|
} else {
|
|
|
|
return JS_FALSE;
|
2007-02-09 21:56:44 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (argc > 1) {
|
2007-08-23 18:34:50 +00:00
|
|
|
phrase_data = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2007-02-09 21:56:44 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (argc > 2) {
|
2007-08-21 19:00:06 +00:00
|
|
|
tmp = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
|
|
|
|
if (!switch_strlen_zero(tmp)) {
|
|
|
|
phrase_lang = tmp;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2007-02-09 21:56:44 +00:00
|
|
|
|
|
|
|
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;
|
2007-02-10 01:00:02 +00:00
|
|
|
dtmf_func = js_collect_input_callback;
|
2007-02-09 21:56:44 +00:00
|
|
|
bp = &cb_state;
|
|
|
|
len = sizeof(cb_state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
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;
|
2008-07-29 16:57:38 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_ivr_phrase_macro(jss->session, phrase_name, phrase_data, phrase_lang, &args);
|
|
|
|
JS_ResumeRequest(cx, cb_state.saveDepth);
|
2008-07-29 16:57:38 +00:00
|
|
|
check_hangup_hook(jss, &ret);
|
2007-02-09 21:56:44 +00:00
|
|
|
*rval = cb_state.ret;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2008-07-14 23:22:41 +00:00
|
|
|
return ret;
|
2007-02-09 21:56:44 +00:00
|
|
|
}
|
|
|
|
|
2008-07-14 23:22:41 +00:00
|
|
|
static jsval check_hangup_hook(struct js_session *jss, jsval *rp)
|
2007-03-27 00:40:53 +00:00
|
|
|
{
|
2007-04-23 20:11:28 +00:00
|
|
|
jsval argv[3] = { 0 };
|
2007-03-27 00:40:53 +00:00
|
|
|
int argc = 0;
|
2008-07-14 23:22:41 +00:00
|
|
|
jsval ret = JS_TRUE;
|
|
|
|
char *resp;
|
2007-04-23 20:11:28 +00:00
|
|
|
|
2008-05-31 16:48:54 +00:00
|
|
|
if (!jss->check_state && jss->on_hangup && (jss->hook_state == CS_HANGUP || jss->hook_state == CS_ROUTING)) {
|
|
|
|
jss->check_state++;
|
2007-03-29 22:31:56 +00:00
|
|
|
argv[argc++] = OBJECT_TO_JSVAL(jss->obj);
|
2007-04-23 20:11:28 +00:00
|
|
|
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"));
|
|
|
|
}
|
2007-03-27 00:40:53 +00:00
|
|
|
JS_CallFunction(jss->cx, jss->obj, jss->on_hangup, argc, argv, &ret);
|
2008-07-14 23:22:41 +00:00
|
|
|
resp = JS_GetStringBytes(JS_ValueToString(jss->cx, ret));
|
2008-07-14 23:24:39 +00:00
|
|
|
if (!switch_strlen_zero(resp)) {
|
|
|
|
ret = !strcasecmp(resp, "exit") ? JS_FALSE : JS_TRUE;
|
|
|
|
}
|
2008-07-14 23:22:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (rp) {
|
|
|
|
*rp = ret;
|
2007-03-27 00:40:53 +00:00
|
|
|
}
|
2008-07-14 23:22:41 +00:00
|
|
|
|
|
|
|
return ret;
|
2007-03-27 00:40:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static switch_status_t hanguphook(switch_core_session_t *session)
|
|
|
|
{
|
2008-01-28 07:26:10 +00:00
|
|
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
2007-03-27 00:40:53 +00:00
|
|
|
struct js_session *jss = NULL;
|
2007-04-23 20:11:28 +00:00
|
|
|
|
|
|
|
if ((jss = switch_channel_get_private(channel, "jss"))) {
|
2008-01-28 07:26:10 +00:00
|
|
|
switch_channel_state_t state = switch_channel_get_state(channel);
|
2007-04-23 20:11:28 +00:00
|
|
|
if (jss->hook_state != state) {
|
|
|
|
jss->hook_state = state;
|
2008-05-31 16:48:54 +00:00
|
|
|
jss->check_state = 0;
|
2007-03-27 00:40:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_hanguphook(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2007-03-27 00:40:53 +00:00
|
|
|
{
|
|
|
|
JSFunction *function;
|
|
|
|
struct js_session *jss;
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2007-03-27 00:40:53 +00:00
|
|
|
|
|
|
|
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;
|
2007-04-23 20:11:28 +00:00
|
|
|
jss->hook_state = switch_channel_get_state(channel);
|
2007-03-27 00:40:53 +00:00
|
|
|
switch_channel_set_private(channel, "jss", jss);
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_core_event_hook_add_state_change(jss->session, hanguphook);
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2007-03-27 00:40:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_streamfile(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-02-28 02:08:42 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-02-28 02:08:42 +00:00
|
|
|
char *file_name = NULL;
|
2006-11-09 05:39:04 +00:00
|
|
|
//char *input_callback = NULL;
|
2006-02-28 02:08:42 +00:00
|
|
|
void *bp = NULL;
|
|
|
|
int len = 0;
|
2006-07-12 18:39:19 +00:00
|
|
|
switch_input_callback_function_t dtmf_func = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
struct input_callback_state cb_state = { 0 };
|
|
|
|
switch_file_handle_t fh = { 0 };
|
2006-11-09 05:39:04 +00:00
|
|
|
JSFunction *function;
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_input_args_t args = { 0 };
|
2007-11-01 11:28:26 +00:00
|
|
|
const char *prebuf;
|
|
|
|
char posbuf[35] = "";
|
2008-07-14 23:22:41 +00:00
|
|
|
jsval ret = JS_TRUE;
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2006-02-28 02:08:42 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2007-06-15 08:14:55 +00:00
|
|
|
CHANNEL_SANITY_CHECK();
|
2008-03-18 18:48:32 +00:00
|
|
|
CHANNEL_MEDIA_SANITY_CHECK();
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-02-26 23:10:22 +00:00
|
|
|
if (argc > 0) {
|
2006-02-28 02:08:42 +00:00
|
|
|
file_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
if (switch_strlen_zero(file_name)) {
|
|
|
|
return JS_FALSE;
|
2006-02-26 23:10:22 +00:00
|
|
|
}
|
|
|
|
}
|
2006-12-23 16:40:37 +00:00
|
|
|
|
2006-02-28 02:08:42 +00:00
|
|
|
if (argc > 1) {
|
2006-12-23 16:40:37 +00:00
|
|
|
if ((function = JS_ValueToFunction(cx, argv[1]))) {
|
2006-02-28 02:08:42 +00:00
|
|
|
memset(&cb_state, 0, sizeof(cb_state));
|
2006-11-09 05:39:04 +00:00
|
|
|
cb_state.function = function;
|
|
|
|
|
2006-12-23 16:40:37 +00:00
|
|
|
if (argc > 2) {
|
|
|
|
cb_state.arg = argv[2];
|
2006-11-09 05:39:04 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 02:08:42 +00:00
|
|
|
cb_state.session_state = jss;
|
2006-11-09 05:39:04 +00:00
|
|
|
cb_state.cx = cx;
|
|
|
|
cb_state.obj = obj;
|
|
|
|
dtmf_func = js_stream_input_callback;
|
2006-02-28 02:08:42 +00:00
|
|
|
bp = &cb_state;
|
|
|
|
len = sizeof(cb_state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (argc > 3) {
|
|
|
|
int32 samps;
|
|
|
|
JS_ValueToInt32(cx, argv[3], &samps);
|
|
|
|
fh.samples = samps;
|
|
|
|
}
|
2008-05-27 04:54:52 +00:00
|
|
|
|
|
|
|
if ((prebuf = switch_channel_get_variable(channel, "stream_prebuffer"))) {
|
|
|
|
int maybe = atoi(prebuf);
|
|
|
|
if (maybe > 0) {
|
|
|
|
fh.prebuf = maybe;
|
|
|
|
}
|
|
|
|
}
|
2007-06-09 23:07:00 +00:00
|
|
|
|
2006-02-28 02:08:42 +00:00
|
|
|
cb_state.extra = &fh;
|
2007-03-29 22:31:56 +00:00
|
|
|
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;
|
2006-12-23 16:40:37 +00:00
|
|
|
switch_ivr_play_file(jss->session, &fh, file_name, &args);
|
2007-03-29 22:31:56 +00:00
|
|
|
JS_ResumeRequest(cx, cb_state.saveDepth);
|
2008-07-29 16:57:38 +00:00
|
|
|
check_hangup_hook(jss, &ret);
|
2006-11-09 05:39:04 +00:00
|
|
|
*rval = cb_state.ret;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(posbuf, sizeof(posbuf), "%u", fh.offset_pos);
|
2007-07-05 17:03:14 +00:00
|
|
|
switch_channel_set_variable(channel, "last_file_position", posbuf);
|
|
|
|
|
2008-07-14 23:22:41 +00:00
|
|
|
return ret;
|
2006-02-26 23:10:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-08 17:27:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
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 };
|
2008-07-08 23:17:58 +00:00
|
|
|
int32 ms = 0;
|
2008-07-14 23:22:41 +00:00
|
|
|
jsval ret = JS_TRUE;
|
2008-12-14 16:37:38 +00:00
|
|
|
int32 sync = 0;
|
2008-12-10 00:48:24 +00:00
|
|
|
|
2008-07-08 17:27:02 +00:00
|
|
|
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);
|
2008-07-08 23:18:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ms <= 0) {
|
|
|
|
return JS_FALSE;
|
2008-07-08 17:27:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-10 00:48:24 +00:00
|
|
|
if (argc > 2) {
|
|
|
|
JS_ValueToInt32(cx, argv[2], &sync);
|
|
|
|
}
|
|
|
|
|
2008-07-08 17:27:02 +00:00
|
|
|
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;
|
2008-12-10 00:48:24 +00:00
|
|
|
switch_ivr_sleep(jss->session, ms, sync, &args);
|
2008-07-08 17:27:02 +00:00
|
|
|
JS_ResumeRequest(cx, cb_state.saveDepth);
|
2008-07-29 16:57:38 +00:00
|
|
|
check_hangup_hook(jss, &ret);
|
2008-07-08 17:27:02 +00:00
|
|
|
*rval = cb_state.ret;
|
|
|
|
|
2008-07-14 23:22:41 +00:00
|
|
|
return ret;
|
2008-07-08 17:27:02 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_set_variable(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-21 20:16:28 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_channel_t *channel;
|
2006-08-21 20:16:28 +00:00
|
|
|
|
2008-12-17 15:35:40 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
|
|
|
|
2006-08-21 20:16:28 +00:00
|
|
|
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(channel, var, val);
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
2006-08-21 20:16:28 +00:00
|
|
|
} else {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-21 20:16:28 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-08-21 20:16:28 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_get_variable(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-21 20:16:28 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_channel_t *channel;
|
2006-08-21 20:16:28 +00:00
|
|
|
|
2008-12-17 15:35:40 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2007-03-27 00:40:53 +00:00
|
|
|
|
2006-08-21 20:16:28 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
|
|
|
|
|
|
|
if (argc > 0) {
|
2007-11-01 11:28:26 +00:00
|
|
|
const char *var, *val;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-08-21 20:16:28 +00:00
|
|
|
var = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
val = switch_channel_get_variable(channel, var);
|
|
|
|
|
|
|
|
if (val) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val));
|
2006-08-21 20:16:28 +00:00
|
|
|
} else {
|
2008-08-20 15:19:39 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, ""));
|
2006-08-21 20:16:28 +00:00
|
|
|
}
|
|
|
|
} else {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-21 20:16:28 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-08-21 20:16:28 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-08-25 21:33:26 +00:00
|
|
|
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;
|
|
|
|
int interval = 0;
|
|
|
|
|
|
|
|
read_codec = switch_core_session_get_read_codec(jss->session);
|
2007-10-19 03:42:02 +00:00
|
|
|
rate = read_codec->implementation->actual_samples_per_second;
|
2008-10-20 17:48:42 +00:00
|
|
|
interval = read_codec->implementation->microseconds_per_packet / 1000;
|
2007-08-25 21:33:26 +00:00
|
|
|
|
|
|
|
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,
|
|
|
|
&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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_speak(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-02-26 23:10:22 +00:00
|
|
|
{
|
2006-02-28 02:08:42 +00:00
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-02-26 23:10:22 +00:00
|
|
|
char *tts_name = NULL;
|
|
|
|
char *voice_name = NULL;
|
|
|
|
char *text = NULL;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_codec_t *codec;
|
2006-02-28 02:08:42 +00:00
|
|
|
void *bp = NULL;
|
|
|
|
int len = 0;
|
2007-03-29 22:31:56 +00:00
|
|
|
struct input_callback_state cb_state = { 0 };
|
2006-07-12 18:39:19 +00:00
|
|
|
switch_input_callback_function_t dtmf_func = NULL;
|
2006-11-09 05:39:04 +00:00
|
|
|
JSFunction *function;
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_input_args_t args = { 0 };
|
2008-07-14 23:22:41 +00:00
|
|
|
jsval ret = JS_TRUE;
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2007-03-27 00:40:53 +00:00
|
|
|
|
2008-03-18 18:48:32 +00:00
|
|
|
|
2007-08-25 21:33:26 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-02-28 02:08:42 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2007-06-15 08:14:55 +00:00
|
|
|
CHANNEL_SANITY_CHECK();
|
2008-03-18 18:48:32 +00:00
|
|
|
CHANNEL_MEDIA_SANITY_CHECK();
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2007-08-03 16:13:32 +00:00
|
|
|
if (argc < 3) {
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
2007-08-03 04:06:58 +00:00
|
|
|
|
|
|
|
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]));
|
|
|
|
|
2007-08-25 21:33:26 +00:00
|
|
|
if (switch_strlen_zero(tts_name)) {
|
|
|
|
eval_some_js("~throw new Error(\"Invalid TTS Name\");", cx, obj, rval);
|
2007-09-11 21:19:16 +00:00
|
|
|
return JS_FALSE;
|
2007-08-25 21:33:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (switch_strlen_zero(text)) {
|
|
|
|
eval_some_js("~throw new Error(\"Invalid Text\");", cx, obj, rval);
|
2007-09-11 21:19:16 +00:00
|
|
|
return JS_FALSE;
|
2007-08-25 21:33:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (jss->speech && strcasecmp(jss->speech->sh.name, tts_name)) {
|
|
|
|
destroy_speech_engine(jss);
|
|
|
|
}
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-08-25 21:33:26 +00:00
|
|
|
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));
|
2007-12-12 22:49:02 +00:00
|
|
|
switch_assert(jss->speech != NULL);
|
2007-08-25 21:33:26 +00:00
|
|
|
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;
|
2007-09-11 21:19:16 +00:00
|
|
|
return JS_FALSE;
|
2007-08-25 21:33:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-28 02:08:42 +00:00
|
|
|
if (argc > 3) {
|
2006-11-09 05:39:04 +00:00
|
|
|
if ((function = JS_ValueToFunction(cx, argv[3]))) {
|
2006-03-01 00:58:32 +00:00
|
|
|
memset(&cb_state, 0, sizeof(cb_state));
|
2006-11-09 05:39:04 +00:00
|
|
|
cb_state.function = function;
|
|
|
|
if (argc > 4) {
|
2007-03-29 22:31:56 +00:00
|
|
|
cb_state.arg = argv[4];
|
|
|
|
}
|
2006-11-09 05:39:04 +00:00
|
|
|
|
|
|
|
cb_state.cx = cx;
|
2007-03-29 22:31:56 +00:00
|
|
|
cb_state.obj = obj;
|
2006-03-01 00:58:32 +00:00
|
|
|
cb_state.session_state = jss;
|
2006-11-09 05:39:04 +00:00
|
|
|
dtmf_func = js_collect_input_callback;
|
2006-03-01 00:58:32 +00:00
|
|
|
bp = &cb_state;
|
|
|
|
len = sizeof(cb_state);
|
|
|
|
}
|
2006-02-28 02:08:42 +00:00
|
|
|
}
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2006-02-28 02:08:42 +00:00
|
|
|
codec = switch_core_session_get_read_codec(jss->session);
|
2007-03-29 22:31:56 +00:00
|
|
|
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;
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-08-25 21:33:26 +00:00
|
|
|
switch_core_speech_flush_tts(&jss->speech->sh);
|
|
|
|
switch_ivr_speak_text_handle(jss->session, &jss->speech->sh, &jss->speech->codec, NULL, text, &args);
|
2007-03-29 22:31:56 +00:00
|
|
|
JS_ResumeRequest(cx, cb_state.saveDepth);
|
2008-07-29 16:57:38 +00:00
|
|
|
check_hangup_hook(jss, &ret);
|
2006-11-09 05:39:04 +00:00
|
|
|
*rval = cb_state.ret;
|
2006-03-01 00:58:32 +00:00
|
|
|
|
2008-07-14 23:22:41 +00:00
|
|
|
return ret;
|
2006-02-26 23:10:22 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_get_digits(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-02-26 23:10:22 +00:00
|
|
|
{
|
2006-02-28 02:08:42 +00:00
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2006-02-26 23:10:22 +00:00
|
|
|
char *terminators = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
char buf[513] = { 0 };
|
2008-01-07 16:49:46 +00:00
|
|
|
int32 digits = 0, timeout = 5000, digit_timeout = 0, abs_timeout = 0;
|
2006-12-14 01:23:03 +00:00
|
|
|
switch_channel_t *channel;
|
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2006-12-14 01:23:03 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2007-06-15 08:14:55 +00:00
|
|
|
CHANNEL_SANITY_CHECK();
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2006-02-26 23:10:22 +00:00
|
|
|
if (argc > 0) {
|
|
|
|
char term;
|
2007-02-11 00:39:46 +00:00
|
|
|
JS_ValueToInt32(cx, argv[0], &digits);
|
|
|
|
|
|
|
|
if (digits > sizeof(buf) - 1) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exceeded max digits of %" SWITCH_SIZE_T_FMT "\n", sizeof(buf) - 1);
|
2007-02-11 00:39:46 +00:00
|
|
|
return JS_FALSE;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-02-26 23:10:22 +00:00
|
|
|
if (argc > 1) {
|
|
|
|
terminators = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
|
|
|
}
|
2008-01-07 16:49:46 +00:00
|
|
|
|
2006-03-01 00:58:32 +00:00
|
|
|
if (argc > 2) {
|
|
|
|
JS_ValueToInt32(cx, argv[2], &timeout);
|
|
|
|
}
|
2006-06-09 22:59:13 +00:00
|
|
|
|
2008-01-07 16:49:46 +00:00
|
|
|
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);
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
|
2006-02-26 23:10:22 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_autohangup(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2007-03-27 00:40:53 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-03-27 00:40:53 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_answer(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-02-26 23:10:22 +00:00
|
|
|
{
|
2006-02-28 02:08:42 +00:00
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2006-02-28 02:08:42 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2007-06-24 21:01:55 +00:00
|
|
|
CHANNEL_SANITY_CHECK_ANSWER();
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2006-02-26 23:10:22 +00:00
|
|
|
switch_channel_answer(channel);
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-06-24 21:01:55 +00:00
|
|
|
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;
|
|
|
|
}
|
2007-02-14 15:19:01 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_cdr(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2007-02-14 15:19:01 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
|
|
|
switch_xml_t cdr;
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
/*Always a pessimist... sheesh! */
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2007-02-14 15:19:01 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (switch_ivr_generate_xml_cdr(jss->session, &cdr) == SWITCH_STATUS_SUCCESS) {
|
2007-02-14 15:19:01 +00:00
|
|
|
char *xml_text;
|
2007-11-30 23:45:27 +00:00
|
|
|
if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, xml_text));
|
2007-02-14 15:19:01 +00:00
|
|
|
}
|
|
|
|
switch_safe_free(xml_text);
|
|
|
|
switch_xml_free(cdr);
|
|
|
|
}
|
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_ready(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-01 22:55:28 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
|
|
|
|
2008-03-12 07:03:11 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL((jss && jss->session && switch_channel_ready(switch_core_session_get_channel(jss->session))) ? JS_TRUE : JS_FALSE);
|
2006-03-01 22:55:28 +00:00
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2008-06-02 23:38:33 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-06-02 23:32:15 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_wait_for_media(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-01 22:55:28 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-03-01 22:55:28 +00:00
|
|
|
switch_time_t started;
|
|
|
|
unsigned int elapsed;
|
2008-11-26 18:19:59 +00:00
|
|
|
int32 timeout = 60000;
|
2008-01-24 14:05:52 +00:00
|
|
|
jsrefcount saveDepth;
|
2008-07-14 23:22:41 +00:00
|
|
|
jsval ret = JS_TRUE;
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2007-03-27 00:40:53 +00:00
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2008-03-18 18:48:32 +00:00
|
|
|
CHANNEL_MEDIA_SANITY_CHECK();
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2008-01-11 00:43:49 +00:00
|
|
|
started = switch_timestamp_now();
|
2006-03-01 22:55:28 +00:00
|
|
|
|
|
|
|
if (argc > 0) {
|
|
|
|
JS_ValueToInt32(cx, argv[0], &timeout);
|
2008-11-26 18:19:59 +00:00
|
|
|
if (timeout < 1000) {
|
|
|
|
timeout = 1000;
|
|
|
|
}
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
2008-11-26 18:19:59 +00:00
|
|
|
|
2008-07-14 23:22:41 +00:00
|
|
|
if (check_hangup_hook(jss, NULL) != JS_TRUE) {
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
2008-01-24 14:05:52 +00:00
|
|
|
saveDepth = JS_SuspendRequest(cx);
|
2007-03-29 22:31:56 +00:00
|
|
|
for (;;) {
|
2008-01-11 00:43:49 +00:00
|
|
|
if (((elapsed = (unsigned int) ((switch_timestamp_now() - started) / 1000)) > (switch_time_t) timeout)
|
2007-03-29 22:31:56 +00:00
|
|
|
|| switch_channel_get_state(channel) >= CS_HANGUP) {
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
|
|
|
break;
|
2006-11-09 05:39:04 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
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);
|
2006-03-01 22:55:28 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2008-11-14 23:31:21 +00:00
|
|
|
switch_cond_next();
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
2008-01-24 14:05:52 +00:00
|
|
|
JS_ResumeRequest(cx, saveDepth);
|
2008-07-14 23:22:41 +00:00
|
|
|
check_hangup_hook(jss, &ret);
|
|
|
|
|
|
|
|
return ret;
|
2006-11-09 05:39:04 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_wait_for_answer(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-11-09 05:39:04 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
|
|
|
switch_channel_t *channel;
|
|
|
|
switch_time_t started;
|
|
|
|
unsigned int elapsed;
|
2008-11-26 18:19:59 +00:00
|
|
|
int32 timeout = 60000;
|
2008-01-24 14:05:52 +00:00
|
|
|
jsrefcount saveDepth;
|
2008-07-14 23:22:41 +00:00
|
|
|
jsval ret = JS_TRUE;
|
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2006-11-09 05:39:04 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2008-01-11 00:43:49 +00:00
|
|
|
started = switch_timestamp_now();
|
2006-11-09 05:39:04 +00:00
|
|
|
|
|
|
|
if (argc > 0) {
|
|
|
|
JS_ValueToInt32(cx, argv[0], &timeout);
|
2008-11-26 18:19:59 +00:00
|
|
|
if (timeout < 1000) {
|
|
|
|
timeout = 1000;
|
|
|
|
}
|
2006-11-09 05:39:04 +00:00
|
|
|
}
|
2008-07-14 23:22:41 +00:00
|
|
|
|
|
|
|
if (check_hangup_hook(jss, NULL) != JS_TRUE) {
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2008-01-24 14:05:52 +00:00
|
|
|
saveDepth = JS_SuspendRequest(cx);
|
2007-03-29 22:31:56 +00:00
|
|
|
for (;;) {
|
2008-01-11 00:43:49 +00:00
|
|
|
if (((elapsed = (unsigned int) ((switch_timestamp_now() - started) / 1000)) > (switch_time_t) timeout)
|
2007-03-29 22:31:56 +00:00
|
|
|
|| switch_channel_get_state(channel) >= CS_HANGUP) {
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
|
|
|
break;
|
2006-11-09 05:39:04 +00:00
|
|
|
}
|
2006-03-01 22:55:28 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_ANSWERED)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
2006-11-09 05:39:04 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2008-11-14 23:31:21 +00:00
|
|
|
switch_cond_next();
|
2006-11-09 05:39:04 +00:00
|
|
|
}
|
2008-01-24 14:05:52 +00:00
|
|
|
JS_ResumeRequest(cx, saveDepth);
|
2008-07-14 23:22:41 +00:00
|
|
|
check_hangup_hook(jss, &ret);
|
|
|
|
return ret;
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_execute(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-07 15:24:57 +00:00
|
|
|
{
|
|
|
|
JSBool retval = JS_FALSE;
|
2006-12-14 01:23:03 +00:00
|
|
|
switch_channel_t *channel;
|
2007-03-29 22:31:56 +00:00
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2008-07-14 23:22:41 +00:00
|
|
|
jsval ret = JS_TRUE;
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2007-03-27 00:40:53 +00:00
|
|
|
|
2006-12-14 01:23:03 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2008-01-28 07:26:10 +00:00
|
|
|
/* you can execute some apps before you answer CHANNEL_SANITY_CHECK(); */
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2007-07-05 17:03:14 +00:00
|
|
|
if (argc > 0) {
|
2008-11-13 17:40:25 +00:00
|
|
|
switch_application_interface_t *application_interface;
|
2006-03-07 15:24:57 +00:00
|
|
|
char *app_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
2007-07-05 17:03:14 +00:00
|
|
|
char *app_arg = NULL;
|
2006-12-02 05:40:58 +00:00
|
|
|
jsrefcount saveDepth;
|
2006-03-07 15:24:57 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2007-03-27 00:40:53 +00:00
|
|
|
|
2007-07-05 17:03:14 +00:00
|
|
|
if (argc > 1) {
|
|
|
|
app_arg = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
|
|
|
}
|
|
|
|
|
2006-03-07 15:24:57 +00:00
|
|
|
if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
|
|
|
|
if (application_interface->application_function) {
|
2008-07-14 23:22:41 +00:00
|
|
|
if (check_hangup_hook(jss, NULL) != JS_TRUE) {
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2006-12-02 05:40:58 +00:00
|
|
|
saveDepth = JS_SuspendRequest(cx);
|
2007-04-21 01:03:58 +00:00
|
|
|
switch_core_session_exec(jss->session, application_interface, app_arg);
|
2006-12-02 05:40:58 +00:00
|
|
|
JS_ResumeRequest(cx, saveDepth);
|
2008-07-29 16:57:38 +00:00
|
|
|
check_hangup_hook(jss, &ret);
|
2006-03-07 15:24:57 +00:00
|
|
|
retval = JS_TRUE;
|
|
|
|
}
|
2008-11-12 19:28:05 +00:00
|
|
|
UNPROTECT_INTERFACE(application_interface);
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-03-07 15:24:57 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(retval);
|
2008-07-14 23:22:41 +00:00
|
|
|
return ret;
|
2006-03-07 15:24:57 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_get_event(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
|
|
|
switch_event_t *event;
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2006-08-18 01:28:50 +00:00
|
|
|
|
|
|
|
if (switch_core_session_dequeue_event(jss->session, &event) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
JSObject *Event;
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if ((eo = malloc(sizeof(*eo)))) {
|
|
|
|
eo->event = event;
|
|
|
|
eo->freed = 0;
|
|
|
|
|
|
|
|
if ((Event = JS_DefineObject(cx, obj, "__event__", &event_class, NULL, 0))) {
|
2007-03-30 00:13:31 +00:00
|
|
|
if ((JS_SetPrivate(cx, Event, eo) && JS_DefineProperties(cx, Event, event_props) && JS_DefineFunctions(cx, Event, event_methods))) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = OBJECT_TO_JSVAL(Event);
|
2006-11-09 05:39:04 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2006-08-18 01:28:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
|
|
|
return JS_TRUE;
|
2006-08-18 01:28:50 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_send_event(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-18 01:28:50 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
|
|
|
JSObject *Event;
|
2006-11-09 05:39:04 +00:00
|
|
|
struct event_obj *eo;
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2007-03-27 00:40:53 +00:00
|
|
|
|
2006-08-18 01:28:50 +00:00
|
|
|
if (argc > 0) {
|
|
|
|
if (JS_ValueToObject(cx, argv[0], &Event)) {
|
2006-11-09 05:39:04 +00:00
|
|
|
if ((eo = JS_GetPrivate(cx, Event))) {
|
|
|
|
if (switch_core_session_receive_event(jss->session, &eo->event) != SWITCH_STATUS_SUCCESS) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-18 01:28:50 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
JS_SetPrivate(cx, Event, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
|
|
|
return JS_TRUE;
|
2006-08-18 01:28:50 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_hangup(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-01 22:55:28 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-05-12 15:33:49 +00:00
|
|
|
char *cause_name = NULL;
|
|
|
|
switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
|
|
|
|
|
2007-06-15 08:14:55 +00:00
|
|
|
METHOD_SANITY_CHECK();
|
2006-12-14 01:23:03 +00:00
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
2007-06-15 08:14:55 +00:00
|
|
|
CHANNEL_SANITY_CHECK();
|
2006-12-14 01:23:03 +00:00
|
|
|
|
2006-05-12 15:33:49 +00:00
|
|
|
if (argc > 1) {
|
2008-05-27 04:54:52 +00:00
|
|
|
if (JSVAL_IS_INT(argv[0])) {
|
2008-05-26 00:18:57 +00:00
|
|
|
int32 i = 0;
|
|
|
|
JS_ValueToInt32(cx, argv[0], &i);
|
|
|
|
cause = i;
|
2008-05-27 04:54:52 +00:00
|
|
|
} else {
|
2008-05-26 00:18:57 +00:00
|
|
|
cause_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
cause = switch_channel_str2cause(cause_name);
|
|
|
|
}
|
2006-05-12 15:33:49 +00:00
|
|
|
}
|
2006-03-01 22:55:28 +00:00
|
|
|
|
2006-05-12 15:33:49 +00:00
|
|
|
switch_channel_hangup(channel, cause);
|
2006-03-01 22:55:28 +00:00
|
|
|
switch_core_session_kill_channel(jss->session, SWITCH_SIG_KILL);
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2006-03-01 00:58:32 +00:00
|
|
|
#ifdef HAVE_CURL
|
|
|
|
|
|
|
|
struct config_data {
|
|
|
|
JSContext *cx;
|
|
|
|
JSObject *obj;
|
|
|
|
char *name;
|
2006-03-07 15:47:34 +00:00
|
|
|
int fd;
|
2006-03-01 00:58:32 +00:00
|
|
|
};
|
|
|
|
|
2007-11-20 04:30:09 +00:00
|
|
|
struct fetch_url_data {
|
|
|
|
JSContext *cx;
|
|
|
|
JSObject *obj;
|
|
|
|
switch_size_t buffer_size;
|
|
|
|
switch_size_t data_len;
|
2008-05-27 04:54:52 +00:00
|
|
|
char *buffer;
|
2007-11-20 04:30:09 +00:00
|
|
|
};
|
|
|
|
|
2006-03-07 15:47:34 +00:00
|
|
|
static size_t hash_callback(void *ptr, size_t size, size_t nmemb, void *data)
|
2006-03-01 00:58:32 +00:00
|
|
|
{
|
2006-03-02 14:52:51 +00:00
|
|
|
register size_t realsize = size * nmemb;
|
2006-03-01 00:58:32 +00:00
|
|
|
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++;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-01 00:58:32 +00:00
|
|
|
if ((val = strchr(line, '='))) {
|
2006-03-02 14:52:51 +00:00
|
|
|
*val = '\0';
|
|
|
|
val++;
|
|
|
|
if (val[0] == '>') {
|
|
|
|
*val = '\0';
|
|
|
|
val++;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-02 14:52:51 +00:00
|
|
|
for (p = line; p && *p == ' '; p++);
|
|
|
|
line = p;
|
2007-03-29 22:31:56 +00:00
|
|
|
for (p = line + strlen(line) - 1; *p == ' '; p--)
|
2006-03-02 14:52:51 +00:00
|
|
|
*p = '\0';
|
|
|
|
for (p = val; p && *p == ' '; p++);
|
|
|
|
val = p;
|
2007-03-29 22:31:56 +00:00
|
|
|
for (p = val + strlen(val) - 1; *p == ' '; p--)
|
2006-03-02 14:52:51 +00:00
|
|
|
*p = '\0';
|
2006-03-01 00:58:32 +00:00
|
|
|
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(code, sizeof(code), "~%s[\"%s\"] = \"%s\"", config_data->name, line, val);
|
2006-03-01 00:58:32 +00:00
|
|
|
eval_some_js(code, config_data->cx, config_data->obj, &rval);
|
|
|
|
|
2006-03-02 14:52:51 +00:00
|
|
|
}
|
2006-03-01 00:58:32 +00:00
|
|
|
|
|
|
|
line = nextline;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-03-01 00:58:32 +00:00
|
|
|
return realsize;
|
|
|
|
}
|
|
|
|
|
2006-03-07 15:47:34 +00:00
|
|
|
static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
|
|
|
|
{
|
2007-03-29 22:31:56 +00:00
|
|
|
register unsigned int realsize = (unsigned int) (size * nmemb);
|
2006-03-07 15:47:34 +00:00
|
|
|
struct config_data *config_data = data;
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
if ((write(config_data->fd, ptr, realsize) != (int) realsize)) {
|
2007-08-03 21:29:01 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to write all bytes!\n");
|
|
|
|
}
|
2006-03-07 15:47:34 +00:00
|
|
|
return realsize;
|
|
|
|
}
|
|
|
|
|
2007-11-20 04:30:09 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2006-03-07 15:47:34 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool js_fetchurl_hash(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-01 00:58:32 +00:00
|
|
|
{
|
|
|
|
char *url = NULL, *name = NULL;
|
|
|
|
CURL *curl_handle = NULL;
|
|
|
|
struct config_data config_data;
|
2007-11-20 04:30:09 +00:00
|
|
|
int saveDepth = 0;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
if (argc > 1) {
|
2006-03-07 15:47:34 +00:00
|
|
|
url = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
name = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
2006-05-12 15:33:49 +00:00
|
|
|
|
2006-03-01 00:58:32 +00:00
|
|
|
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;
|
2006-03-07 15:47:34 +00:00
|
|
|
if (name) {
|
2006-03-01 00:58:32 +00:00
|
|
|
config_data.name = name;
|
2006-03-07 15:47:34 +00:00
|
|
|
}
|
2006-03-01 00:58:32 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
|
2008-07-29 14:40:23 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
|
2006-03-07 15:47:34 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, hash_callback);
|
2007-03-29 22:31:56 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
|
2006-03-07 15:47:34 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-js/1.0");
|
2007-11-20 04:30:09 +00:00
|
|
|
|
2008-04-21 20:15:50 +00:00
|
|
|
saveDepth = JS_SuspendRequest(cx);
|
|
|
|
curl_easy_perform(curl_handle);
|
|
|
|
JS_ResumeRequest(cx, saveDepth);
|
2007-11-20 04:30:09 +00:00
|
|
|
|
2006-03-01 00:58:32 +00:00
|
|
|
curl_easy_cleanup(curl_handle);
|
2006-03-02 14:52:51 +00:00
|
|
|
} else {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
|
2006-03-01 00:58:32 +00:00
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2006-03-07 15:47:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool js_fetchurl_file(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-07 15:47:34 +00:00
|
|
|
{
|
|
|
|
char *url = NULL, *filename = NULL;
|
|
|
|
CURL *curl_handle = NULL;
|
|
|
|
struct config_data config_data;
|
2007-11-20 04:30:09 +00:00
|
|
|
int saveDepth = 0;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
if (argc > 1) {
|
2006-03-07 15:47:34 +00:00
|
|
|
url = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
filename = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
|
|
|
|
|
|
|
curl_global_init(CURL_GLOBAL_ALL);
|
|
|
|
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;
|
2008-01-24 21:38:07 +00:00
|
|
|
if ((config_data.fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
|
2006-03-07 15:47:34 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
|
2008-07-29 14:40:23 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
|
2006-03-07 15:47:34 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, file_callback);
|
2007-03-29 22:31:56 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
|
2006-03-07 15:47:34 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-js/1.0");
|
2007-11-20 04:30:09 +00:00
|
|
|
|
2008-04-21 20:15:50 +00:00
|
|
|
saveDepth = JS_SuspendRequest(cx);
|
|
|
|
curl_easy_perform(curl_handle);
|
|
|
|
JS_ResumeRequest(cx, saveDepth);
|
2007-11-20 04:30:09 +00:00
|
|
|
|
2006-03-07 15:47:34 +00:00
|
|
|
curl_easy_cleanup(curl_handle);
|
|
|
|
close(config_data.fd);
|
|
|
|
} else {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
|
2006-03-07 15:47:34 +00:00
|
|
|
}
|
|
|
|
} else {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
|
2006-03-07 15:47:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2007-11-20 04:30:09 +00:00
|
|
|
|
|
|
|
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_global_init(CURL_GLOBAL_ALL);
|
|
|
|
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);
|
2008-07-29 14:40:23 +00:00
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
|
2007-11-20 04:30:09 +00:00
|
|
|
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");
|
|
|
|
|
2008-04-21 20:15:50 +00:00
|
|
|
saveDepth = JS_SuspendRequest(cx);
|
|
|
|
code = curl_easy_perform(curl_handle);
|
|
|
|
JS_ResumeRequest(cx, saveDepth);
|
2007-11-20 04:30:09 +00:00
|
|
|
|
|
|
|
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];
|
2008-05-27 04:54:52 +00:00
|
|
|
switch_snprintf(errmsg, 256, "~throw new Error(\"Curl returned error %u.\");", (unsigned) code);
|
2007-11-20 04:30:09 +00:00
|
|
|
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;
|
|
|
|
}
|
2006-03-01 00:58:32 +00:00
|
|
|
#endif
|
|
|
|
|
2006-02-28 21:21:48 +00:00
|
|
|
/* Session Object */
|
|
|
|
/*********************************************************************************/
|
|
|
|
enum session_tinyid {
|
2006-03-02 14:52:51 +00:00
|
|
|
SESSION_NAME, SESSION_STATE,
|
2007-03-29 22:31:56 +00:00
|
|
|
PROFILE_DIALPLAN, PROFILE_CID_NAME, PROFILE_CID_NUM, PROFILE_IP, PROFILE_ANI, PROFILE_ANI_II, PROFILE_DEST,
|
2008-05-26 00:18:57 +00:00
|
|
|
SESSION_UUID, SESSION_CAUSE, SESSION_CAUSECODE
|
2006-02-26 23:10:22 +00:00
|
|
|
};
|
|
|
|
|
2006-02-28 21:21:48 +00:00
|
|
|
static JSFunctionSpec session_methods[] = {
|
2007-03-29 22:31:56 +00:00
|
|
|
{"originate", session_originate, 2},
|
2007-06-19 05:54:16 +00:00
|
|
|
{"setCallerData", session_set_callerdata, 2},
|
2007-03-29 22:31:56 +00:00
|
|
|
{"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},
|
2006-03-02 14:52:51 +00:00
|
|
|
{"getDigits", session_get_digits, 1},
|
2007-03-29 22:31:56 +00:00
|
|
|
{"answer", session_answer, 0},
|
2007-06-24 21:01:55 +00:00
|
|
|
{"preAnswer", session_pre_answer, 0},
|
2007-03-29 22:31:56 +00:00
|
|
|
{"generateXmlCdr", session_cdr, 0},
|
|
|
|
{"ready", session_ready, 0},
|
2008-06-02 23:32:15 +00:00
|
|
|
{"answered", session_answered, 0},
|
2008-06-02 23:38:33 +00:00
|
|
|
{"mediaReady", session_media_ready, 0},
|
2007-03-29 22:31:56 +00:00
|
|
|
{"waitForAnswer", session_wait_for_answer, 0},
|
|
|
|
{"waitForMedia", session_wait_for_media, 0},
|
2006-08-18 01:28:50 +00:00
|
|
|
{"getEvent", session_get_event, 0},
|
|
|
|
{"sendEvent", session_send_event, 0},
|
2007-03-29 22:31:56 +00:00
|
|
|
{"hangup", session_hangup, 0},
|
|
|
|
{"execute", session_execute, 0},
|
2008-07-08 17:27:02 +00:00
|
|
|
{"sleep", session_sleep, 1},
|
2006-02-26 23:10:22 +00:00
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
2006-02-28 21:21:48 +00:00
|
|
|
static JSPropertySpec session_props[] = {
|
2007-03-29 22:31:56 +00:00
|
|
|
{"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},
|
2007-06-08 14:39:09 +00:00
|
|
|
{"caller_id_number", PROFILE_CID_NUM, JSPROP_READONLY | JSPROP_PERMANENT},
|
2007-03-29 22:31:56 +00:00
|
|
|
{"network_addr", PROFILE_IP, JSPROP_READONLY | JSPROP_PERMANENT},
|
2007-06-08 14:39:09 +00:00
|
|
|
{"network_address", PROFILE_IP, JSPROP_READONLY | JSPROP_PERMANENT},
|
2007-03-29 22:31:56 +00:00
|
|
|
{"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},
|
2008-05-26 00:18:57 +00:00
|
|
|
{"causecode", SESSION_CAUSECODE, JSPROP_READONLY | JSPROP_PERMANENT},
|
2006-03-02 14:52:51 +00:00
|
|
|
{0}
|
2006-02-26 23:10:22 +00:00
|
|
|
};
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
|
2006-02-26 23:10:22 +00:00
|
|
|
{
|
2006-02-28 02:08:42 +00:00
|
|
|
struct js_session *jss = JS_GetPrivate(cx, obj);
|
2006-02-26 23:10:22 +00:00
|
|
|
int param = 0;
|
2007-03-27 00:40:53 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
|
|
|
switch_caller_profile_t *caller_profile = NULL;
|
|
|
|
char *name = NULL;
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2007-03-27 00:40:53 +00:00
|
|
|
if (jss && jss->session) {
|
|
|
|
channel = switch_core_session_get_channel(jss->session);
|
|
|
|
caller_profile = switch_channel_get_caller_profile(channel);
|
|
|
|
}
|
2006-03-01 22:55:28 +00:00
|
|
|
|
2006-02-27 04:01:38 +00:00
|
|
|
name = JS_GetStringBytes(JS_ValueToString(cx, id));
|
2007-03-27 00:40:53 +00:00
|
|
|
|
2006-02-26 23:10:22 +00:00
|
|
|
/* numbers are our props anything else is a method */
|
|
|
|
if (name[0] >= 48 && name[0] <= 57) {
|
|
|
|
param = atoi(name);
|
|
|
|
} else {
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2007-03-27 00:40:53 +00:00
|
|
|
|
|
|
|
if (!channel) {
|
2007-03-29 22:31:56 +00:00
|
|
|
switch (param) {
|
2007-03-27 00:40:53 +00:00
|
|
|
case SESSION_CAUSE:
|
2007-12-12 22:49:02 +00:00
|
|
|
if (jss) {
|
|
|
|
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_cause2str(jss->cause)));
|
|
|
|
}
|
2007-03-27 00:40:53 +00:00
|
|
|
break;
|
2008-05-26 00:18:57 +00:00
|
|
|
case SESSION_CAUSECODE:
|
|
|
|
if (jss) {
|
|
|
|
*vp = INT_TO_JSVAL(jss->cause);
|
|
|
|
}
|
|
|
|
break;
|
2007-03-27 00:40:53 +00:00
|
|
|
default:
|
|
|
|
*vp = BOOLEAN_TO_JSVAL(JS_FALSE);
|
|
|
|
}
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
switch (param) {
|
2007-03-27 00:40:53 +00:00
|
|
|
case SESSION_CAUSE:
|
2007-03-29 22:31:56 +00:00
|
|
|
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_cause2str(switch_channel_get_cause(channel))));
|
2007-03-27 00:40:53 +00:00
|
|
|
break;
|
2008-05-26 00:18:57 +00:00
|
|
|
case SESSION_CAUSECODE:
|
|
|
|
*vp = INT_TO_JSVAL(switch_channel_get_cause(channel));
|
|
|
|
break;
|
2006-02-28 21:21:48 +00:00
|
|
|
case SESSION_NAME:
|
2006-02-26 23:10:22 +00:00
|
|
|
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_get_name(channel)));
|
|
|
|
break;
|
2006-12-22 19:25:38 +00:00
|
|
|
case SESSION_UUID:
|
|
|
|
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_get_uuid(channel)));
|
|
|
|
break;
|
2006-02-28 21:21:48 +00:00
|
|
|
case SESSION_STATE:
|
2006-03-01 22:55:28 +00:00
|
|
|
*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;
|
2006-10-17 23:33:32 +00:00
|
|
|
case PROFILE_ANI_II:
|
2006-03-01 22:55:28 +00:00
|
|
|
if (caller_profile) {
|
2006-10-17 23:33:32 +00:00
|
|
|
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->aniii));
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PROFILE_DEST:
|
|
|
|
if (caller_profile) {
|
|
|
|
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, caller_profile->destination_number));
|
|
|
|
}
|
2006-02-26 23:10:22 +00:00
|
|
|
break;
|
|
|
|
default:
|
2007-03-27 00:40:53 +00:00
|
|
|
*vp = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-02-26 23:10:22 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-03-27 00:40:53 +00:00
|
|
|
return JS_TRUE;
|
2006-02-26 23:10:22 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 02:08:42 +00:00
|
|
|
JSClass session_class = {
|
2007-03-29 22:31:56 +00:00
|
|
|
"Session", JSCLASS_HAS_PRIVATE,
|
2007-06-15 17:05:20 +00:00
|
|
|
JS_PropertyStub, JS_PropertyStub, session_getProperty, DEFAULT_SET_PROPERTY,
|
2007-03-29 22:31:56 +00:00
|
|
|
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, session_destroy, NULL, NULL, NULL,
|
2006-03-01 22:55:28 +00:00
|
|
|
session_construct
|
2006-02-26 23:10:22 +00:00
|
|
|
};
|
|
|
|
|
2007-11-30 15:39:55 +00:00
|
|
|
static JSObject *new_js_session(JSContext * cx, JSObject * obj, switch_core_session_t *session, struct js_session **jss, char *name, int flags)
|
2006-02-28 21:21:48 +00:00
|
|
|
{
|
|
|
|
JSObject *session_obj;
|
|
|
|
if ((session_obj = JS_DefineObject(cx, obj, name, &session_class, NULL, 0))) {
|
2007-11-30 15:39:55 +00:00
|
|
|
*jss = malloc(sizeof(**jss));
|
2007-12-12 22:49:02 +00:00
|
|
|
switch_assert(*jss);
|
2007-11-30 15:39:55 +00:00
|
|
|
memset(*jss, 0, sizeof(**jss));
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-11-30 15:39:55 +00:00
|
|
|
(*jss)->session = session;
|
|
|
|
(*jss)->flags = flags;
|
|
|
|
(*jss)->cx = cx;
|
|
|
|
(*jss)->obj = session_obj;
|
|
|
|
(*jss)->stack_depth = 0;
|
|
|
|
if ((JS_SetPrivate(cx, session_obj, *jss) &&
|
2007-03-30 00:13:31 +00:00
|
|
|
JS_DefineProperties(cx, session_obj, session_props) && JS_DefineFunctions(cx, session_obj, session_methods))) {
|
2008-11-20 02:27:59 +00:00
|
|
|
if (switch_core_session_read_lock_hangup(session) != SWITCH_STATUS_SUCCESS) {
|
2007-11-30 15:39:55 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Read Lock Failure.\n");
|
|
|
|
free(*jss);
|
|
|
|
return NULL;
|
|
|
|
}
|
2006-02-28 21:21:48 +00:00
|
|
|
return session_obj;
|
2007-11-30 15:39:55 +00:00
|
|
|
} else {
|
|
|
|
free(*jss);
|
2006-02-28 21:21:48 +00:00
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-02-28 21:21:48 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
/* Session Object */
|
|
|
|
/*********************************************************************************/
|
2007-03-27 00:40:53 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-01 22:55:28 +00:00
|
|
|
{
|
2007-03-27 00:40:53 +00:00
|
|
|
struct js_session *jss = NULL;
|
2008-05-30 17:27:32 +00:00
|
|
|
JSObject *session_obj = NULL;
|
|
|
|
|
2007-10-19 00:44:27 +00:00
|
|
|
jss = malloc(sizeof(*jss));
|
2007-12-12 22:49:02 +00:00
|
|
|
switch_assert(jss);
|
2007-03-27 00:40:53 +00:00
|
|
|
memset(jss, 0, sizeof(*jss));
|
|
|
|
jss->cx = cx;
|
|
|
|
jss->obj = obj;
|
|
|
|
JS_SetPrivate(cx, obj, jss);
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2008-05-30 17:27:32 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
|
|
|
|
2008-03-18 18:22:13 +00:00
|
|
|
if (argc > 0) {
|
|
|
|
char *uuid = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
2008-05-30 17:27:32 +00:00
|
|
|
|
|
|
|
if (!strchr(uuid, '/')) {
|
2008-03-18 18:22:13 +00:00
|
|
|
jss->session = switch_core_session_locate(uuid);
|
2008-05-30 17:27:32 +00:00
|
|
|
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,
|
2008-12-05 14:59:24 +00:00
|
|
|
&jss->session, &jss->cause, uuid, 60, NULL, NULL, NULL, NULL, NULL, SOF_NONE) == SWITCH_STATUS_SUCCESS) {
|
2008-05-30 17:27:32 +00:00
|
|
|
switch_set_flag(jss, S_HUP);
|
|
|
|
switch_channel_set_state(switch_core_session_get_channel(jss->session), CS_SOFT_EXECUTE);
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
|
|
|
} else {
|
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_cause2str(jss->cause)));
|
|
|
|
}
|
2008-03-18 18:22:13 +00:00
|
|
|
}
|
|
|
|
}
|
2007-03-27 00:40:53 +00:00
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-06-19 05:54:16 +00:00
|
|
|
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]));
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-06-19 05:54:16 +00:00
|
|
|
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;
|
2008-05-27 04:54:52 +00:00
|
|
|
}
|
|
|
|
|
2007-06-19 05:54:16 +00:00
|
|
|
if (toset) {
|
|
|
|
switch_safe_free(*toset);
|
|
|
|
*toset = strdup(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-06-19 05:54:16 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool session_originate(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2007-03-27 00:40:53 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss = NULL;
|
2006-04-29 01:00:52 +00:00
|
|
|
switch_memory_pool_t *pool = NULL;
|
2007-03-27 00:40:53 +00:00
|
|
|
|
|
|
|
jss = JS_GetPrivate(cx, obj);
|
|
|
|
jss->cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
|
|
|
|
2006-08-21 19:14:51 +00:00
|
|
|
if (argc > 1) {
|
2006-03-01 22:55:28 +00:00
|
|
|
JSObject *session_obj;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_core_session_t *session = NULL, *peer_session = NULL;
|
2007-03-27 00:40:53 +00:00
|
|
|
switch_caller_profile_t *caller_profile = NULL, *orig_caller_profile = NULL;
|
2007-11-01 11:28:26 +00:00
|
|
|
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;
|
2006-08-21 19:14:51 +00:00
|
|
|
char *to = NULL;
|
2007-06-18 15:44:28 +00:00
|
|
|
char *tmp;
|
2008-01-24 14:05:52 +00:00
|
|
|
jsrefcount saveDepth;
|
|
|
|
switch_status_t status;
|
|
|
|
|
2007-03-27 00:40:53 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-03-23 19:22:06 +00:00
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
if (JS_ValueToObject(cx, argv[0], &session_obj)) {
|
|
|
|
struct js_session *old_jss = NULL;
|
2008-04-21 19:26:32 +00:00
|
|
|
if (session_obj && (old_jss = JS_GetPrivate(cx, session_obj)) && old_jss->session) {
|
2006-03-01 22:55:28 +00:00
|
|
|
session = old_jss->session;
|
2007-03-27 00:40:53 +00:00
|
|
|
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;
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
if (!switch_strlen_zero(jss->dialplan))
|
|
|
|
dialplan = jss->dialplan;
|
|
|
|
if (!switch_strlen_zero(jss->caller_id_name))
|
|
|
|
cid_name = jss->caller_id_name;
|
|
|
|
if (!switch_strlen_zero(jss->caller_id_number))
|
|
|
|
cid_num = jss->caller_id_number;
|
|
|
|
if (!switch_strlen_zero(jss->ani))
|
|
|
|
ani = jss->ani;
|
|
|
|
if (!switch_strlen_zero(jss->aniii))
|
|
|
|
aniii = jss->aniii;
|
|
|
|
if (!switch_strlen_zero(jss->rdnis))
|
|
|
|
rdnis = jss->rdnis;
|
|
|
|
if (!switch_strlen_zero(jss->context))
|
|
|
|
context = jss->context;
|
|
|
|
if (!switch_strlen_zero(jss->username))
|
|
|
|
username = jss->username;
|
2007-06-19 05:54:16 +00:00
|
|
|
|
2006-08-21 19:14:51 +00:00
|
|
|
dest = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
2006-03-01 22:55:28 +00:00
|
|
|
|
2006-09-03 04:29:42 +00:00
|
|
|
if (!strchr(dest, '/')) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Channel String\n");
|
2007-03-27 00:40:53 +00:00
|
|
|
goto done;
|
2006-09-03 04:29:42 +00:00
|
|
|
}
|
|
|
|
|
2006-08-21 19:14:51 +00:00
|
|
|
if (argc > 2) {
|
2007-06-18 15:44:28 +00:00
|
|
|
tmp = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
|
|
|
|
if (!switch_strlen_zero(tmp)) {
|
|
|
|
to = tmp;
|
2008-05-27 04:54:52 +00:00
|
|
|
}
|
2006-05-26 16:00:08 +00:00
|
|
|
}
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2006-03-22 23:55:53 +00:00
|
|
|
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
|
2006-03-22 23:55:53 +00:00
|
|
|
return JS_FALSE;
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
caller_profile = switch_caller_profile_new(pool, username, dialplan, cid_name, cid_num, network_addr, ani, aniii, rdnis, modname, context, dest);
|
2007-03-30 00:13:31 +00:00
|
|
|
|
2008-01-24 14:05:52 +00:00
|
|
|
saveDepth = JS_SuspendRequest(cx);
|
2008-12-05 14:59:24 +00:00
|
|
|
status = switch_ivr_originate(session, &peer_session, &jss->cause, dest, to ? atoi(to) : 60, NULL, NULL, NULL, caller_profile, NULL, SOF_NONE);
|
2008-01-24 14:05:52 +00:00
|
|
|
JS_ResumeRequest(cx, saveDepth);
|
|
|
|
|
|
|
|
if (status != SWITCH_STATUS_SUCCESS) {
|
2006-08-21 19:14:51 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot Create Outgoing Channel! [%s]\n", dest);
|
2007-03-27 00:40:53 +00:00
|
|
|
goto done;
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2006-08-21 19:14:51 +00:00
|
|
|
jss->session = peer_session;
|
2008-04-23 14:57:03 +00:00
|
|
|
switch_set_flag(jss, S_HUP);
|
2007-03-27 00:40:53 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
2008-05-05 15:30:55 +00:00
|
|
|
switch_channel_set_state(switch_core_session_get_channel(jss->session), CS_SOFT_EXECUTE);
|
2006-08-21 19:14:51 +00:00
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
} else {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing Args\n");
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
done:
|
2006-03-23 19:22:06 +00:00
|
|
|
return JS_TRUE;
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static void session_destroy(JSContext * cx, JSObject * obj)
|
2006-03-01 22:55:28 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss;
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
if (cx && obj) {
|
|
|
|
if ((jss = JS_GetPrivate(cx, obj))) {
|
2007-11-30 15:39:55 +00:00
|
|
|
JS_SetPrivate(cx, obj, NULL);
|
|
|
|
if (jss->speech && *jss->speech->sh.name) {
|
|
|
|
destroy_speech_engine(jss);
|
|
|
|
}
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-03-27 00:40:53 +00:00
|
|
|
if (jss->session) {
|
2007-11-30 15:39:55 +00:00
|
|
|
switch_core_session_t *session = jss->session;
|
|
|
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-03-27 00:40:53 +00:00
|
|
|
switch_channel_set_private(channel, "jss", NULL);
|
2007-11-30 15:39:55 +00:00
|
|
|
switch_core_event_hook_remove_state_change(session, hanguphook);
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2008-04-23 14:57:03 +00:00
|
|
|
if (switch_test_flag(jss, S_HUP)) {
|
2007-06-18 15:44:28 +00:00
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
|
|
|
}
|
|
|
|
|
2007-06-19 05:54:16 +00:00
|
|
|
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);
|
2007-11-30 15:39:55 +00:00
|
|
|
switch_core_session_rwunlock(session);
|
2007-04-13 22:15:58 +00:00
|
|
|
}
|
2007-06-19 05:54:16 +00:00
|
|
|
|
2007-11-30 15:39:55 +00:00
|
|
|
free(jss);
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-03-02 17:36:23 +00:00
|
|
|
/* FileIO Object */
|
|
|
|
/*********************************************************************************/
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool fileio_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-02 17:36:23 +00:00
|
|
|
{
|
2006-04-29 01:00:52 +00:00
|
|
|
switch_memory_pool_t *pool;
|
2006-03-02 17:36:23 +00:00
|
|
|
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]));
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-02 17:36:23 +00:00
|
|
|
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);
|
2007-03-29 22:31:56 +00:00
|
|
|
if (switch_file_open(&fd, path, flags, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) != SWITCH_STATUS_SUCCESS) {
|
2006-08-22 17:19:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Open File: %s\n", path);
|
2006-03-02 17:36:23 +00:00
|
|
|
switch_core_destroy_memory_pool(&pool);
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-22 17:19:31 +00:00
|
|
|
return JS_TRUE;
|
2006-03-02 17:36:23 +00:00
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2006-08-22 17:19:31 +00:00
|
|
|
return JS_TRUE;
|
2006-03-02 17:36:23 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
static void fileio_destroy(JSContext * cx, JSObject * obj)
|
2006-03-02 17:36:23 +00:00
|
|
|
{
|
|
|
|
struct fileio_obj *fio = JS_GetPrivate(cx, obj);
|
|
|
|
|
|
|
|
if (fio) {
|
2006-08-21 22:48:01 +00:00
|
|
|
switch_memory_pool_t *pool;
|
2007-03-29 22:31:56 +00:00
|
|
|
if (fio->fd) {
|
2006-08-21 19:14:51 +00:00
|
|
|
switch_file_close(fio->fd);
|
|
|
|
}
|
2006-08-21 22:48:01 +00:00
|
|
|
pool = fio->pool;
|
2006-03-02 17:36:23 +00:00
|
|
|
switch_core_destroy_memory_pool(&pool);
|
|
|
|
pool = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool fileio_read(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-02 17:36:23 +00:00
|
|
|
{
|
|
|
|
struct fileio_obj *fio = JS_GetPrivate(cx, obj);
|
|
|
|
int32 bytes = 0;
|
|
|
|
switch_size_t read = 0;
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
|
|
|
|
2007-03-27 00:40:53 +00:00
|
|
|
if (!fio) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-22 17:19:31 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2006-03-02 17:36:23 +00:00
|
|
|
if (!(fio->flags & SWITCH_FOPEN_READ)) {
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-02 17:36:23 +00:00
|
|
|
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;
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL((read > 0) ? JS_TRUE : JS_FALSE);
|
|
|
|
}
|
2006-03-02 17:36:23 +00:00
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool fileio_data(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-02 17:36:23 +00:00
|
|
|
{
|
|
|
|
struct fileio_obj *fio = JS_GetPrivate(cx, obj);
|
2006-08-22 17:19:31 +00:00
|
|
|
|
|
|
|
if (!fio) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-22 17:19:31 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, fio->buf));
|
2006-03-02 17:36:23 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool fileio_write(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-02 17:36:23 +00:00
|
|
|
{
|
|
|
|
struct fileio_obj *fio = JS_GetPrivate(cx, obj);
|
|
|
|
switch_size_t wrote = 0;
|
|
|
|
char *data = NULL;
|
|
|
|
|
2006-08-22 17:19:31 +00:00
|
|
|
if (!fio) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-22 17:19:31 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2006-03-02 17:36:23 +00:00
|
|
|
if (!(fio->flags & SWITCH_FOPEN_WRITE)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-03-02 17:36:23 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-02 17:36:23 +00:00
|
|
|
if (argc > 0) {
|
|
|
|
data = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data) {
|
2006-08-22 00:03:47 +00:00
|
|
|
wrote = strlen(data);
|
2007-03-30 00:13:31 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL((switch_file_write(fio->fd, data, &wrote) == SWITCH_STATUS_SUCCESS) ? JS_TRUE : JS_FALSE);
|
2006-03-02 17:36:23 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-03-02 17:36:23 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum fileio_tinyid {
|
2006-08-22 17:19:31 +00:00
|
|
|
FILEIO_PATH, FILEIO_OPEN
|
2006-03-02 17:36:23 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static JSFunctionSpec fileio_methods[] = {
|
|
|
|
{"read", fileio_read, 1},
|
|
|
|
{"write", fileio_write, 1},
|
|
|
|
{"data", fileio_data, 0},
|
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
|
|
|
static JSPropertySpec fileio_props[] = {
|
2007-03-29 22:31:56 +00:00
|
|
|
{"path", FILEIO_PATH, JSPROP_READONLY | JSPROP_PERMANENT},
|
|
|
|
{"open", FILEIO_OPEN, JSPROP_READONLY | JSPROP_PERMANENT},
|
2006-03-02 17:36:23 +00:00
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool fileio_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
|
2006-03-02 17:36:23 +00:00
|
|
|
{
|
|
|
|
JSBool res = JS_TRUE;
|
|
|
|
struct fileio_obj *fio = JS_GetPrivate(cx, obj);
|
|
|
|
char *name;
|
|
|
|
int param = 0;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-02 17:36:23 +00:00
|
|
|
name = JS_GetStringBytes(JS_ValueToString(cx, id));
|
2007-03-29 22:31:56 +00:00
|
|
|
/* 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) {
|
2006-03-02 17:36:23 +00:00
|
|
|
case FILEIO_PATH:
|
2006-08-22 17:19:31 +00:00
|
|
|
if (fio) {
|
|
|
|
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, fio->path));
|
|
|
|
} else {
|
2007-03-29 22:31:56 +00:00
|
|
|
*vp = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-08-22 17:19:31 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case FILEIO_OPEN:
|
2007-03-29 22:31:56 +00:00
|
|
|
*vp = BOOLEAN_TO_JSVAL(fio ? JS_TRUE : JS_FALSE);
|
2006-03-02 17:36:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
JSClass fileio_class = {
|
2007-03-29 22:31:56 +00:00
|
|
|
"FileIO", JSCLASS_HAS_PRIVATE,
|
2007-06-15 17:05:20 +00:00
|
|
|
JS_PropertyStub, JS_PropertyStub, fileio_getProperty, DEFAULT_SET_PROPERTY,
|
2007-03-29 22:31:56 +00:00
|
|
|
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, fileio_destroy, NULL, NULL, NULL,
|
2006-03-02 17:36:23 +00:00
|
|
|
fileio_construct
|
|
|
|
};
|
|
|
|
|
2006-02-28 21:21:48 +00:00
|
|
|
/* Built-In*/
|
|
|
|
/*********************************************************************************/
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool js_exit(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-08-22 17:19:31 +00:00
|
|
|
{
|
2007-06-22 19:59:57 +00:00
|
|
|
char *supplied_error, code_buf[256] = "";
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-06-22 19:59:57 +00:00
|
|
|
if (argc > 0 && (supplied_error = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(code_buf, sizeof(code_buf), "~throw new Error(\"%s\");", supplied_error);
|
2007-06-22 19:59:57 +00:00
|
|
|
eval_some_js(code_buf, cx, obj, rval);
|
|
|
|
}
|
2006-08-22 17:19:31 +00:00
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool js_log(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-02-26 23:10:22 +00:00
|
|
|
{
|
2006-07-12 21:23:22 +00:00
|
|
|
char *level_str, *msg;
|
|
|
|
switch_log_level_t level = SWITCH_LOG_DEBUG;
|
2006-11-09 05:39:04 +00:00
|
|
|
JSScript *script = NULL;
|
|
|
|
const char *file = __FILE__;
|
|
|
|
int line = __LINE__;
|
|
|
|
JSStackFrame *caller;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
caller = JS_GetScriptedCaller(cx, NULL);
|
|
|
|
script = JS_GetFrameScript(cx, caller);
|
|
|
|
|
|
|
|
if (script) {
|
|
|
|
file = JS_GetScriptFilename(cx, script);
|
|
|
|
line = JS_GetScriptBaseLineNumber(cx, script);
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-11-09 05:39:04 +00:00
|
|
|
|
2006-07-12 21:23:22 +00:00
|
|
|
if (argc > 1) {
|
|
|
|
if ((level_str = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
|
|
|
|
level = switch_log_str2level(level_str);
|
2007-12-10 19:16:50 +00:00
|
|
|
if (level == SWITCH_LOG_INVALID) {
|
|
|
|
level = SWITCH_LOG_DEBUG;
|
|
|
|
}
|
2006-07-12 21:23:22 +00:00
|
|
|
}
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2006-07-12 21:23:22 +00:00
|
|
|
if ((msg = JS_GetStringBytes(JS_ValueToString(cx, argv[1])))) {
|
2007-06-20 10:50:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "console_log", line, NULL, level, "%s", msg);
|
2006-07-12 21:23:22 +00:00
|
|
|
return JS_TRUE;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-07-12 21:23:22 +00:00
|
|
|
} else if (argc > 0) {
|
|
|
|
if ((msg = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
|
2007-06-20 10:50:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "console_log", line, NULL, level, "%s", msg);
|
2006-07-12 21:23:22 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
}
|
2006-02-26 23:10:22 +00:00
|
|
|
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2008-02-01 21:19:33 +00:00
|
|
|
static JSBool js_global_set(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
|
|
|
{
|
|
|
|
char *var_name = NULL, *val = NULL;
|
|
|
|
if (argc > 1) {
|
|
|
|
var_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
2008-05-27 04:54:52 +00:00
|
|
|
val = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
2008-02-01 21:19:33 +00:00
|
|
|
switch_core_set_variable(var_name, val);
|
|
|
|
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;
|
|
|
|
}
|
2007-09-11 21:19:16 +00:00
|
|
|
|
2008-02-01 21:19:33 +00:00
|
|
|
static JSBool js_global_get(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2007-09-11 21:19:16 +00:00
|
|
|
{
|
|
|
|
char *var_name = NULL, *val = NULL;
|
|
|
|
|
|
|
|
if (argc > 0) {
|
|
|
|
var_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
|
|
|
val = switch_core_get_variable(var_name);
|
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val));
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
eval_some_js("~throw new Error(\"var name not supplied!\");", cx, obj, rval);
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool js_include(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-01 00:58:32 +00:00
|
|
|
{
|
|
|
|
char *code;
|
2007-03-29 22:31:56 +00:00
|
|
|
if (argc > 0 && (code = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
|
2007-10-23 19:02:47 +00:00
|
|
|
if (eval_some_js(code, cx, obj, rval) <= 0) {
|
2007-03-07 22:17:02 +00:00
|
|
|
return JS_FALSE;
|
|
|
|
}
|
2006-03-01 00:58:32 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Arguements\n");
|
2006-03-01 00:58:32 +00:00
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2008-06-02 23:32:15 +00:00
|
|
|
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) {
|
|
|
|
switch_yield(msec * 1000);
|
|
|
|
} else {
|
|
|
|
eval_some_js("~throw new Error(\"No Time specified\");", cx, obj, rval);
|
|
|
|
}
|
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool js_api_use(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-11-10 21:49:57 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool js_api_execute(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-07 02:06:40 +00:00
|
|
|
{
|
2007-05-15 14:22:23 +00:00
|
|
|
if (argc > 0) {
|
2006-03-07 02:06:40 +00:00
|
|
|
char *cmd = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
2007-05-15 14:22:23 +00:00
|
|
|
char *arg = NULL;
|
2006-07-26 20:12:49 +00:00
|
|
|
switch_core_session_t *session = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_stream_handle_t stream = { 0 };
|
2006-07-26 20:12:49 +00:00
|
|
|
|
2008-01-19 23:23:12 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-05-15 14:22:23 +00:00
|
|
|
if (argc > 1) {
|
|
|
|
arg = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
|
|
|
|
}
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2006-07-26 20:12:49 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2008-11-15 01:30:15 +00:00
|
|
|
SWITCH_STANDARD_STREAM(stream);
|
2007-02-23 22:43:11 +00:00
|
|
|
switch_api_execute(cmd, arg, session, &stream);
|
2006-07-12 18:39:19 +00:00
|
|
|
|
2008-11-15 01:30:15 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_str_nil((char *)stream.data)));
|
|
|
|
switch_safe_free(stream.data);
|
|
|
|
|
2006-03-07 02:06:40 +00:00
|
|
|
} else {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, ""));
|
2006-03-07 02:06:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool js_bridge(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-03-01 22:55:28 +00:00
|
|
|
{
|
|
|
|
struct js_session *jss_a = NULL, *jss_b = NULL;
|
|
|
|
JSObject *session_obj_a = NULL, *session_obj_b = NULL;
|
2006-11-09 05:39:04 +00:00
|
|
|
void *bp = NULL;
|
|
|
|
int len = 0;
|
|
|
|
switch_input_callback_function_t dtmf_func = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
struct input_callback_state cb_state = { 0 };
|
2006-11-09 05:39:04 +00:00
|
|
|
JSFunction *function;
|
2006-03-01 22:55:28 +00:00
|
|
|
|
2007-08-20 16:04:02 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
if (argc > 1) {
|
|
|
|
if (JS_ValueToObject(cx, argv[0], &session_obj_a)) {
|
|
|
|
if (!(jss_a = JS_GetPrivate(cx, session_obj_a))) {
|
2007-08-20 16:04:02 +00:00
|
|
|
eval_some_js("~throw new Error(\"Cannot find session A\");", cx, obj, rval);
|
2007-09-11 21:19:16 +00:00
|
|
|
return JS_FALSE;
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-03-01 22:55:28 +00:00
|
|
|
if (JS_ValueToObject(cx, argv[1], &session_obj_b)) {
|
|
|
|
if (!(jss_b = JS_GetPrivate(cx, session_obj_b))) {
|
2007-08-20 16:04:02 +00:00
|
|
|
eval_some_js("~throw new Error(\"Cannot find session B\");", cx, obj, rval);
|
2007-09-11 21:19:16 +00:00
|
|
|
return JS_FALSE;
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-08-20 16:04:02 +00:00
|
|
|
if (!(jss_a && jss_a->session)) {
|
|
|
|
eval_some_js("~throw new Error(\"session A is not ready!\");", cx, obj, rval);
|
2007-09-11 21:19:16 +00:00
|
|
|
return JS_FALSE;
|
2007-08-20 16:04:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!(jss_b && jss_b->session)) {
|
|
|
|
eval_some_js("~throw new Error(\"session B is not ready!\");", cx, obj, rval);
|
2007-09-11 21:19:16 +00:00
|
|
|
return JS_FALSE;
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (argc > 2) {
|
|
|
|
if ((function = JS_ValueToFunction(cx, argv[2]))) {
|
|
|
|
memset(&cb_state, 0, sizeof(cb_state));
|
|
|
|
cb_state.function = function;
|
|
|
|
|
|
|
|
if (argc > 3) {
|
2007-03-29 22:31:56 +00:00
|
|
|
cb_state.arg = argv[3];
|
|
|
|
}
|
2006-11-09 05:39:04 +00:00
|
|
|
|
|
|
|
cb_state.cx = cx;
|
2007-03-29 22:31:56 +00:00
|
|
|
cb_state.obj = obj;
|
2007-11-29 18:41:40 +00:00
|
|
|
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;
|
2006-11-09 05:39:04 +00:00
|
|
|
cb_state.session_state = jss_a;
|
|
|
|
dtmf_func = js_collect_input_callback;
|
|
|
|
bp = &cb_state;
|
|
|
|
len = sizeof(cb_state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
cb_state.saveDepth = JS_SuspendRequest(cx);
|
2006-11-09 05:39:04 +00:00
|
|
|
switch_ivr_multi_threaded_bridge(jss_a->session, jss_b->session, dtmf_func, bp, bp);
|
2007-03-29 22:31:56 +00:00
|
|
|
JS_ResumeRequest(cx, cb_state.saveDepth);
|
2006-12-02 05:40:58 +00:00
|
|
|
|
2007-08-20 16:04:02 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
2006-11-09 05:39:04 +00:00
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2006-12-29 20:42:16 +00:00
|
|
|
/* Replace this with more robust version later */
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool js_system(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-12-29 20:42:16 +00:00
|
|
|
{
|
2007-03-29 22:31:56 +00:00
|
|
|
char *cmd;
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
2006-12-29 20:42:16 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (argc > 0 && (cmd = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
|
2008-09-26 15:50:12 +00:00
|
|
|
*rval = INT_TO_JSVAL(switch_system(cmd, SWITCH_TRUE));
|
2007-03-29 22:31:56 +00:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2006-12-29 20:42:16 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Arguements\n");
|
|
|
|
return JS_FALSE;
|
2006-12-29 20:42:16 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static JSBool js_file_unlink(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
|
2006-12-27 22:47:46 +00:00
|
|
|
{
|
|
|
|
const char *path;
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
|
|
|
|
if (argc > 0 && (path = (const char *) JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
|
2006-12-27 22:47:46 +00:00
|
|
|
if ((switch_file_remove(path, NULL)) == SWITCH_STATUS_SUCCESS) {
|
2007-03-29 22:31:56 +00:00
|
|
|
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
|
2006-12-27 22:47:46 +00:00
|
|
|
}
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Arguements\n");
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2006-02-26 23:10:22 +00:00
|
|
|
static JSFunctionSpec fs_functions[] = {
|
2007-03-29 22:31:56 +00:00
|
|
|
{"console_log", js_log, 2},
|
2007-05-15 14:22:23 +00:00
|
|
|
{"consoleLog", js_log, 2},
|
2008-02-01 21:19:33 +00:00
|
|
|
{"getGlobalVariable", js_global_get, 2},
|
|
|
|
{"setGlobalVariable", js_global_set, 2},
|
2007-03-29 22:31:56 +00:00
|
|
|
{"exit", js_exit, 0},
|
|
|
|
{"include", js_include, 1},
|
2006-03-01 22:55:28 +00:00
|
|
|
{"bridge", js_bridge, 2},
|
2006-03-07 02:06:40 +00:00
|
|
|
{"apiExecute", js_api_execute, 2},
|
2006-11-10 21:49:57 +00:00
|
|
|
{"use", js_api_use, 1},
|
2008-06-02 23:32:15 +00:00
|
|
|
{"msleep", js_api_sleep, 1},
|
2006-12-27 23:03:54 +00:00
|
|
|
{"fileDelete", js_file_unlink, 1},
|
2006-12-29 20:42:16 +00:00
|
|
|
{"system", js_system, 1},
|
2006-03-01 00:58:32 +00:00
|
|
|
#ifdef HAVE_CURL
|
2007-11-20 04:30:09 +00:00
|
|
|
{"fetchURL", js_fetchurl, 1},
|
2007-03-29 22:31:56 +00:00
|
|
|
{"fetchURLHash", js_fetchurl_hash, 1},
|
|
|
|
{"fetchURLFile", js_fetchurl_file, 1},
|
2007-11-20 04:30:09 +00:00
|
|
|
{"fetchUrl", js_fetchurl, 1},
|
|
|
|
{"fetchUrlHash", js_fetchurl_hash, 1},
|
|
|
|
{"fetchUrlFile", js_fetchurl_file, 1},
|
2007-03-29 22:31:56 +00:00
|
|
|
#endif
|
2006-02-26 23:10:22 +00:00
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static int env_init(JSContext * cx, JSObject * javascript_object)
|
2006-03-01 22:55:28 +00:00
|
|
|
{
|
|
|
|
JS_DefineFunctions(cx, javascript_object, fs_functions);
|
|
|
|
|
|
|
|
JS_InitStandardClasses(cx, javascript_object);
|
2006-12-23 01:39:27 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
JS_InitClass(cx, javascript_object, NULL, &session_class, session_construct, 3, session_props, session_methods, session_props, session_methods);
|
2006-03-01 22:55:28 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
JS_InitClass(cx, javascript_object, NULL, &fileio_class, fileio_construct, 3, fileio_props, fileio_methods, fileio_props, fileio_methods);
|
2006-03-02 17:36:23 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
JS_InitClass(cx, javascript_object, NULL, &event_class, event_construct, 3, event_props, event_methods, event_props, event_methods);
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2007-12-27 20:45:26 +00:00
|
|
|
JS_InitClass(cx, javascript_object, NULL, &dtmf_class, dtmf_construct, 3, dtmf_props, dtmf_methods, dtmf_props, dtmf_methods);
|
|
|
|
|
2007-09-11 17:33:06 +00:00
|
|
|
JS_InitClass(cx, javascript_object, NULL, &pcre_class, pcre_construct, 3, pcre_props, pcre_methods, pcre_props, pcre_methods);
|
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-11-01 11:28:26 +00:00
|
|
|
static void js_parse_and_execute(switch_core_session_t *session, const char *input_code, struct request_obj *ro)
|
2006-02-26 23:10:22 +00:00
|
|
|
{
|
2006-03-30 23:02:50 +00:00
|
|
|
JSObject *javascript_global_object = NULL;
|
2007-11-01 11:28:26 +00:00
|
|
|
char buf[1024], *arg, *argv[512];
|
|
|
|
const char *script;
|
2006-03-02 15:22:39 +00:00
|
|
|
int argc = 0, x = 0, y = 0;
|
|
|
|
unsigned int flags = 0;
|
2007-11-30 15:39:55 +00:00
|
|
|
struct js_session *jss;
|
2006-03-02 15:22:39 +00:00
|
|
|
JSContext *cx = NULL;
|
|
|
|
jsval rval;
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2006-03-02 15:22:39 +00:00
|
|
|
if ((cx = JS_NewContext(globals.rt, globals.gStackChunkSize))) {
|
2006-11-10 21:49:57 +00:00
|
|
|
JS_BeginRequest(cx);
|
2006-03-02 15:22:39 +00:00
|
|
|
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);
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2006-03-02 15:22:39 +00:00
|
|
|
/* Emaculent conception of session object into the script if one is available */
|
2007-11-30 15:39:55 +00:00
|
|
|
if (!(session && new_js_session(cx, javascript_global_object, session, &jss, "session", flags))) {
|
2008-11-20 03:56:27 +00:00
|
|
|
switch_snprintf(buf, sizeof(buf), "~var session = false;");
|
2007-05-15 14:22:23 +00:00
|
|
|
eval_some_js(buf, cx, javascript_global_object, &rval);
|
2006-03-02 15:22:39 +00:00
|
|
|
}
|
2007-05-14 03:17:38 +00:00
|
|
|
if (ro) {
|
|
|
|
new_request(cx, javascript_global_object, ro);
|
|
|
|
}
|
|
|
|
|
2006-03-02 15:22:39 +00:00
|
|
|
} else {
|
2008-01-19 23:23:12 +00:00
|
|
|
abort();
|
2006-02-26 23:10:22 +00:00
|
|
|
}
|
|
|
|
|
2006-03-02 15:22:39 +00:00
|
|
|
script = input_code;
|
|
|
|
|
|
|
|
if ((arg = strchr(script, ' '))) {
|
|
|
|
*arg++ = '\0';
|
2007-04-02 21:31:03 +00:00
|
|
|
argc = switch_separate_string(arg, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
2006-02-26 23:10:22 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-05-14 03:17:38 +00:00
|
|
|
if (!argc) {
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(buf, sizeof(buf), "~var argv = new Array();");
|
2007-05-14 03:17:38 +00:00
|
|
|
eval_some_js(buf, cx, javascript_global_object, &rval);
|
|
|
|
} else {
|
|
|
|
/* create a js doppleganger of this argc/argv */
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(buf, sizeof(buf), "~var argv = new Array(%d);", argc);
|
2006-03-02 15:22:39 +00:00
|
|
|
eval_some_js(buf, cx, javascript_global_object, &rval);
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(buf, sizeof(buf), "~var argc = %d", argc);
|
2006-03-02 15:22:39 +00:00
|
|
|
eval_some_js(buf, cx, javascript_global_object, &rval);
|
|
|
|
|
|
|
|
for (y = 0; y < argc; y++) {
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(buf, sizeof(buf), "~argv[%d] = \"%s\";", x++, argv[y]);
|
2006-03-02 15:22:39 +00:00
|
|
|
eval_some_js(buf, cx, javascript_global_object, &rval);
|
2006-02-26 23:10:22 +00:00
|
|
|
}
|
|
|
|
}
|
2008-01-19 23:23:12 +00:00
|
|
|
|
2006-02-26 23:10:22 +00:00
|
|
|
if (cx) {
|
2006-03-02 15:22:39 +00:00
|
|
|
eval_some_js(script, cx, javascript_global_object, &rval);
|
2006-02-26 23:10:22 +00:00
|
|
|
JS_DestroyContext(cx);
|
|
|
|
}
|
2008-01-15 00:06:15 +00:00
|
|
|
|
|
|
|
return;
|
2006-02-26 23:10:22 +00:00
|
|
|
}
|
|
|
|
|
2007-11-01 11:28:26 +00:00
|
|
|
SWITCH_STANDARD_APP(js_dp_function)
|
2007-05-14 03:17:38 +00:00
|
|
|
{
|
2007-11-01 11:28:26 +00:00
|
|
|
js_parse_and_execute(session, data, NULL);
|
2007-05-14 03:17:38 +00:00
|
|
|
}
|
2006-03-02 15:22:39 +00:00
|
|
|
|
2008-08-11 16:50:45 +00:00
|
|
|
struct js_task {
|
|
|
|
switch_memory_pool_t *pool;
|
|
|
|
char *code;
|
|
|
|
};
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
static void *SWITCH_THREAD_FUNC js_thread_run(switch_thread_t *thread, void *obj)
|
2006-03-01 22:55:28 +00:00
|
|
|
{
|
2008-08-11 16:50:45 +00:00
|
|
|
struct js_task *task = (struct js_task *) obj;
|
|
|
|
switch_memory_pool_t *pool;
|
2006-03-01 22:55:28 +00:00
|
|
|
|
2008-08-11 16:50:45 +00:00
|
|
|
js_parse_and_execute(NULL, task->code, NULL);
|
2006-03-01 22:55:28 +00:00
|
|
|
|
2008-08-11 16:50:45 +00:00
|
|
|
if ((pool = task->pool)) {
|
|
|
|
switch_core_destroy_memory_pool(&pool);
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
2006-03-02 15:22:39 +00:00
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-05-12 14:48:14 +00:00
|
|
|
static void js_thread_launch(const char *text)
|
2006-03-01 22:55:28 +00:00
|
|
|
{
|
2006-04-29 01:00:52 +00:00
|
|
|
switch_thread_t *thread;
|
2006-03-01 22:55:28 +00:00
|
|
|
switch_threadattr_t *thd_attr = NULL;
|
2008-08-11 16:50:45 +00:00
|
|
|
struct js_task *task;
|
|
|
|
switch_memory_pool_t *pool;
|
2006-03-01 22:55:28 +00:00
|
|
|
|
2008-08-11 16:50:45 +00:00
|
|
|
if (switch_strlen_zero(text)) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "missing required input!\n");
|
|
|
|
return;
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2008-08-11 16:50:45 +00:00
|
|
|
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);
|
2006-03-01 22:55:28 +00:00
|
|
|
switch_threadattr_detach_set(thd_attr, 1);
|
2006-04-26 17:18:33 +00:00
|
|
|
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
|
2008-08-11 16:50:45 +00:00
|
|
|
switch_thread_create(&thread, thd_attr, js_thread_run, task, pool);
|
2006-03-01 22:55:28 +00:00
|
|
|
}
|
|
|
|
|
2007-05-14 03:17:38 +00:00
|
|
|
SWITCH_STANDARD_API(jsapi_function)
|
|
|
|
{
|
2008-05-27 04:54:52 +00:00
|
|
|
struct request_obj ro = { 0 };
|
2007-11-28 19:56:25 +00:00
|
|
|
char *path_info = NULL;
|
2007-05-14 03:17:38 +00:00
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
if (stream->param_event) {
|
2008-05-24 03:46:19 +00:00
|
|
|
path_info = switch_event_get_header(stream->param_event, "http-path-info");
|
2007-11-28 19:56:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (switch_strlen_zero(cmd) && path_info) {
|
|
|
|
cmd = path_info;
|
|
|
|
}
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-05-14 03:17:38 +00:00
|
|
|
if (switch_strlen_zero(cmd)) {
|
2008-08-11 16:50:45 +00:00
|
|
|
stream->write_function(stream, "USAGE: %s\n", jsapi_interface->syntax);
|
2007-05-14 03:17:38 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
ro.cmd = cmd;
|
|
|
|
ro.session = session;
|
|
|
|
ro.stream = stream;
|
2008-01-19 23:23:12 +00:00
|
|
|
|
2007-05-14 03:17:38 +00:00
|
|
|
js_parse_and_execute(session, (char *) cmd, &ro);
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
SWITCH_STANDARD_API(launch_async)
|
2006-03-01 22:55:28 +00:00
|
|
|
{
|
2007-05-12 21:36:15 +00:00
|
|
|
if (switch_strlen_zero(cmd)) {
|
2008-08-11 16:50:45 +00:00
|
|
|
stream->write_function(stream, "USAGE: %s\n", js_run_interface->syntax);
|
2006-03-29 19:11:20 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
js_thread_launch(cmd);
|
2006-10-08 07:11:42 +00:00
|
|
|
stream->write_function(stream, "OK\n");
|
2006-03-01 22:55:28 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
static void message_query_handler(switch_event_t *event)
|
2007-04-02 21:31:03 +00:00
|
|
|
{
|
|
|
|
char *account = switch_event_get_header(event, "message-account");
|
|
|
|
|
|
|
|
if (account) {
|
2007-04-04 03:08:17 +00:00
|
|
|
char *path, *cmd;
|
2007-04-02 21:31:03 +00:00
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
path = switch_mprintf("%s%smwi.js", SWITCH_GLOBAL_dirs.script_dir, SWITCH_PATH_SEPARATOR);
|
2007-12-12 22:49:02 +00:00
|
|
|
switch_assert(path != NULL);
|
2007-04-02 21:31:03 +00:00
|
|
|
|
2007-04-23 15:33:25 +00:00
|
|
|
if (switch_file_exists(path, NULL) == SWITCH_STATUS_SUCCESS) {
|
2007-04-04 03:08:17 +00:00
|
|
|
cmd = switch_mprintf("%s %s", path, account);
|
2007-12-12 22:49:02 +00:00
|
|
|
switch_assert(cmd != NULL);
|
2007-04-04 03:08:17 +00:00
|
|
|
js_thread_launch(cmd);
|
|
|
|
switch_safe_free(cmd);
|
2007-04-02 23:34:58 +00:00
|
|
|
}
|
|
|
|
|
2007-04-04 03:08:17 +00:00
|
|
|
switch_safe_free(path);
|
2007-04-02 21:31:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_LOAD_FUNCTION(mod_spidermonkey_load)
|
2006-02-26 23:10:22 +00:00
|
|
|
{
|
2007-06-20 08:18:18 +00:00
|
|
|
switch_application_interface_t *app_interface;
|
2006-04-29 23:43:28 +00:00
|
|
|
switch_status_t status;
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2006-03-02 14:52:51 +00:00
|
|
|
if ((status = init_js()) != SWITCH_STATUS_SUCCESS) {
|
2006-02-26 23:10:22 +00:00
|
|
|
return status;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2008-07-03 23:54:35 +00:00
|
|
|
if (switch_event_bind_removable(modname, SWITCH_EVENT_MESSAGE_QUERY, SWITCH_EVENT_SUBCLASS_ANY, message_query_handler, NULL, &globals.node)
|
2007-04-02 21:31:03 +00:00
|
|
|
!= SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
|
2006-02-26 23:10:22 +00:00
|
|
|
/* connect my internal structure to the blank pointer passed to me */
|
2007-06-20 08:18:18 +00:00
|
|
|
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
2008-08-11 16:50:45 +00:00
|
|
|
SWITCH_ADD_API(js_run_interface, "jsrun", "run a script", launch_async, "jsrun <script> [additional_vars [...]]");
|
|
|
|
SWITCH_ADD_API(jsapi_interface, "jsapi", "execute an api call", jsapi_function, "jsapi <script> [additional_vars [...]]");
|
2008-05-27 04:54:52 +00:00
|
|
|
SWITCH_ADD_APP(app_interface, "javascript", "Launch JS ivr", "Run a javascript ivr on a channel", js_dp_function, "<script> [additional_vars [...]]",
|
|
|
|
SAF_SUPPORT_NOMEDIA);
|
2006-02-26 23:10:22 +00:00
|
|
|
|
2006-05-12 15:33:49 +00:00
|
|
|
curl_global_init(CURL_GLOBAL_ALL);
|
|
|
|
|
2006-02-26 23:10:22 +00:00
|
|
|
/* indicate that the module should continue to be loaded */
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
2006-05-12 15:33:49 +00:00
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_spidermonkey_shutdown)
|
2006-05-12 15:33:49 +00:00
|
|
|
{
|
|
|
|
curl_global_cleanup();
|
2008-07-03 23:54:35 +00:00
|
|
|
switch_event_unbind(&globals.node);
|
2007-09-29 01:06:08 +00:00
|
|
|
switch_core_hash_destroy(&module_manager.mod_hash);
|
|
|
|
switch_core_hash_destroy(&module_manager.load_hash);
|
2006-05-12 15:33:49 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
2006-11-27 22:30:48 +00:00
|
|
|
|
|
|
|
/* For Emacs:
|
|
|
|
* Local Variables:
|
|
|
|
* mode:c
|
2008-02-03 22:14:57 +00:00
|
|
|
* indent-tabs-mode:t
|
2006-11-27 22:30:48 +00:00
|
|
|
* tab-width:4
|
|
|
|
* c-basic-offset:4
|
|
|
|
* End:
|
|
|
|
* For VIM:
|
2008-07-03 19:12:26 +00:00
|
|
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
2006-11-27 22:30:48 +00:00
|
|
|
*/
|