freeswitch/src/mod/languages/mod_v8/src/fsglobal.cpp

791 lines
23 KiB
C++

/*
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
*
* 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.
*
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Peter Olsson <peter@olssononline.se>
* Anthony Minessale II <anthm@freeswitch.org>
* William King <william.king@quentustech.com>
*
* fsglobal.cpp -- JavaScript Global functions
*
*/
#include "mod_v8.h"
#include "fsglobal.hpp"
#include "fssession.hpp"
#include <switch_curl.h>
using namespace std;
using namespace v8;
class CURLCallbackData
{
public:
Isolate *isolate;
Persistent<Array> hashObject;
int fileHandle;
switch_size_t bufferSize;
switch_size_t bufferDataLength;
char *buffer;
CURLCallbackData() {
isolate = NULL;
fileHandle = 0;
bufferSize = 0;
bufferDataLength = 0;
buffer = NULL;
}
~CURLCallbackData() {
hashObject.Reset();
}
};
size_t FSGlobal::HashCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
register size_t realsize = size * nmemb;
char *line, lineb[2048], *nextline = NULL, *val = NULL, *p = NULL;
CURLCallbackData *config_data = (CURLCallbackData *)data;
if (!config_data->hashObject.IsEmpty()) {
switch_copy_string(lineb, (char *) ptr, sizeof(lineb));
line = lineb;
HandleScope scope(config_data->isolate);
/* Get the array object to store data in */
Local<Array> args = Local<Array>::New(config_data->isolate, config_data->hashObject);
while (line) {
if ((nextline = strchr(line, '\n'))) {
*nextline = '\0';
nextline++;
}
if ((val = strchr(line, '='))) {
*val = '\0';
val++;
if (val[0] == '>') {
*val = '\0';
val++;
}
for (p = line; p && *p == ' '; p++);
line = p;
for (p = line + strlen(line) - 1; *p == ' '; p--)
*p = '\0';
for (p = val; p && *p == ' '; p++);
val = p;
for (p = val + strlen(val) - 1; *p == ' '; p--)
*p = '\0';
// Add data to hash
args->Set(String::NewFromUtf8(config_data->isolate, line), String::NewFromUtf8(config_data->isolate, js_safe_str(val)));
}
line = nextline;
}
}
return realsize;
}
size_t FSGlobal::FileCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
register unsigned int realsize = (unsigned int) (size * nmemb);
CURLCallbackData *config_data = (CURLCallbackData *)data;
if ((write(config_data->fileHandle, ptr, realsize) != (int) realsize)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to write all bytes!\n");
}
return realsize;
}
size_t FSGlobal::FetchUrlCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
register unsigned int realsize = (unsigned int) (size * nmemb);
CURLCallbackData *config_data = (CURLCallbackData *)data;
/* Too much data. Do not increase buffer, but abort fetch instead. */
if (config_data->bufferDataLength + realsize >= config_data->bufferSize) {
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->bufferDataLength, ptr, realsize);
config_data->bufferDataLength += realsize;
config_data->buffer[config_data->bufferDataLength] = 0;
return realsize;
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURLHash)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
switch_CURL *curl_handle = NULL;
CURLCallbackData config_data;
int saveDepth = 0;
if (info.Length() > 0) {
String::Utf8Value url(info[0]);
if (info.Length() > 1 && info[1]->IsString()) {
/* Cast to string */
Local<String> str = Local<String>::Cast(info[1]);
/* Try to get existing variable */
Local<Value> obj = info.GetIsolate()->GetCurrentContext()->Global()->Get(str);
if (!obj.IsEmpty() && obj->IsArray()) {
/* The existing var is an array, use it */
config_data.hashObject.Reset(info.GetIsolate(), Local<Array>::Cast(obj));
} else if (obj.IsEmpty() || obj->IsUndefined()) {
/* No existing var (or an existing that is undefined), create a new one */
Local<Array> arguments = Array::New(info.GetIsolate());
info.GetIsolate()->GetCurrentContext()->Global()->Set(str, arguments);
config_data.hashObject.Reset(info.GetIsolate(), arguments);
} else {
/* The var exists, but is wrong type - exit with error */
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Second argument is the name of an existing var of the wrong type"));
return;
}
} else if (info.Length() > 1 && info[1]->IsArray()) {
/* The var is an array, use it */
config_data.hashObject.Reset(info.GetIsolate(), Local<Array>::Cast(info[1]));
} else if (info.Length() > 1) {
/* The var exists, but is wrong type - exit with error */
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Second argument is of the wrong type"));
return;
} else {
/* Second argument doesn't exist, this is also ok. The hash will be returned as the result */
Local<Array> arguments = Array::New(info.GetIsolate());
config_data.hashObject.Reset(info.GetIsolate(), arguments);
}
curl_handle = switch_curl_easy_init();
if (!strncasecmp(js_safe_str(*url), "https", 5)) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
}
config_data.isolate = info.GetIsolate();
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, js_safe_str(*url));
switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, FSGlobal::HashCallback);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-v8/1.0");
switch_curl_easy_perform(curl_handle);
switch_curl_easy_cleanup(curl_handle);
/* Return the hash */
info.GetReturnValue().Set(config_data.hashObject);
} else {
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
}
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURLFile)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
switch_CURL *curl_handle = NULL;
CURLCallbackData config_data;
int saveDepth = 0;
if (info.Length() > 1) {
const char *url = NULL, *filename = NULL;
String::Utf8Value str1(info[0]);
String::Utf8Value str2(info[1]);
url = js_safe_str(*str1);
filename = js_safe_str(*str2);
curl_handle = switch_curl_easy_init();
if (!strncasecmp(url, "https", 5)) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
}
config_data.isolate = info.GetIsolate();
if ((config_data.fileHandle = open(filename, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, url);
switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, FSGlobal::FileCallback);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-v8/1.0");
switch_curl_easy_perform(curl_handle);
switch_curl_easy_cleanup(curl_handle);
close(config_data.fileHandle);
info.GetReturnValue().Set(true);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open file [%s]\n", filename);
info.GetReturnValue().Set(false);
}
} else {
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
}
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURL)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
switch_CURL *curl_handle = NULL;
CURLCallbackData config_data;
int32_t buffer_size = 65535;
switch_CURLcode code = (switch_CURLcode)0;
int saveDepth = 0;
if (info.Length() >= 1) {
const char *url;
String::Utf8Value str(info[0]);
url = js_safe_str(*str);
if (info.Length() > 1) {
buffer_size = info[1]->Int32Value();
}
curl_handle = switch_curl_easy_init();
if (!strncasecmp(url, "https", 5)) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
}
config_data.isolate = info.GetIsolate();
config_data.bufferSize = buffer_size;
config_data.buffer = (char *)malloc(config_data.bufferSize);
config_data.bufferDataLength = 0;
if (config_data.buffer == NULL) {
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to allocate data buffer."));
switch_curl_easy_cleanup(curl_handle);
return;
}
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, url);
switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, FSGlobal::FetchUrlCallback);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-v8/1.0");
code = switch_curl_easy_perform(curl_handle);
switch_curl_easy_cleanup(curl_handle);
if (code == CURLE_OK) {
config_data.buffer[config_data.bufferDataLength] = 0;
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(config_data.buffer)));
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Curl returned error %u\n", (unsigned) code);
info.GetReturnValue().Set(false);
}
free(config_data.buffer);
} else {
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
}
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(Exit)
{
JS_CHECK_SCRIPT_STATE();
if (info.Length() > 0) {
HandleScope handle_scope(info.GetIsolate());
String::Utf8Value str(info[0]);
if (*str) {
JSMain::ExitScript(info.GetIsolate(), *str);
return;
}
}
JSMain::ExitScript(info.GetIsolate(), NULL);
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(Log)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
char *level_str, *msg;
switch_log_level_t level = SWITCH_LOG_DEBUG;
char *file = NULL;
int line = 0;
if (info.Length() > 0) {
/* Get filename and line number from stack */
file = JSMain::GetStackInfo(info.GetIsolate(), &line);
}
if (info.Length() > 1) {
String::Utf8Value str(info[0]);
if ((level_str = *str)) {
level = switch_log_str2level(level_str);
if (level == SWITCH_LOG_INVALID) {
level = SWITCH_LOG_DEBUG;
}
}
String::Utf8Value str2(info[1]);
if ((msg = *str2) && *msg != '\0') {
const char lastchar = msg[strlen(msg)-1];
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "console_log", line, NULL, level, "%s%s", msg, lastchar != '\n' ? "\n" : "");
switch_safe_free(file);
return;
}
} else if (info.Length() > 0) {
String::Utf8Value str(info[0]);
if ((msg = *str) && *msg != '\0') {
const char lastchar = msg[strlen(msg)-1];
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "console_log", line, NULL, level, "%s%s", msg, lastchar != '\n' ? "\n" : "");
switch_safe_free(file);
return;
}
}
switch_safe_free(file);
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(GlobalSet)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
const char *var_name = NULL, *val = NULL, *val2 = NULL;
bool tf = true;
if (info.Length() > 1) {
String::Utf8Value str1(info[0]);
String::Utf8Value str2(info[1]);
var_name = js_safe_str(*str1);
val = js_safe_str(*str2);
if (info.Length() == 2) {
switch_core_set_variable(var_name, val);
info.GetReturnValue().Set(true);
return;
} else {
String::Utf8Value str3(info[2]);
val2 = js_safe_str(*str3);
if (switch_core_set_var_conditional(var_name, val, val2) != SWITCH_TRUE) {
tf = false;
}
info.GetReturnValue().Set(tf);
return;
}
}
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "var name not supplied!"));
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(GlobalGet)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
const char *var_name = NULL;
char *val = NULL;
if (info.Length() > 0) {
String::Utf8Value str(info[0]);
var_name = js_safe_str(*str);
val = switch_core_get_variable_dup(var_name);
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(val)));
switch_safe_free(val);
return;
}
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "var name not supplied!"));
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(Include)
{
JS_CHECK_SCRIPT_STATE();
if (info.Length() < 1) {
/* Bad arguments, return exception */
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
} else {
/* Try to get the current script path */
string scriptPath = "";
Handle<Value> val = info.GetIsolate()->GetCurrentContext()->Global()->Get(String::NewFromUtf8(info.GetIsolate(), "scriptPath"));
if (!val.IsEmpty() && val->IsString()) {
String::Utf8Value tmp(val);
if (*tmp) {
scriptPath = *tmp;
}
}
/* Loop all arguments until we find a valid file */
for (int i = 0; i < info.Length(); i++) {
HandleScope handle_scope(info.GetIsolate());
String::Utf8Value str(info[i]);
char *path = NULL;
const char *script_name = NULL;
if (*str) {
if (switch_is_file_path(*str)) {
script_name = *str;
} else {
/* First try to use the same path as the executing script */
if (scriptPath.length() > 0) {
path = switch_mprintf("%s%s%s", scriptPath.c_str(), SWITCH_PATH_SEPARATOR, *str);
if (path && JSMain::FileExists(path)) {
script_name = path;
} else {
switch_safe_free(path);
}
}
/* At last, use FS script directory */
if (!script_name && (path = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.script_dir, SWITCH_PATH_SEPARATOR, *str))) {
script_name = path;
}
}
}
if (script_name && JSMain::FileExists(script_name)) {
string js_file = JSMain::LoadFileToString(script_name);
if (js_file.length() > 0) {
#if defined(V8_MAJOR_VERSION) && V8_MAJOR_VERSION >=5
MaybeLocal<v8::Script> script;
LoadScript(&script, info.GetIsolate(), js_file.c_str(), script_name);
if (script.IsEmpty()) {
info.GetReturnValue().Set(false);
} else {
info.GetReturnValue().Set(script.ToLocalChecked()->Run());
}
#else
Handle<String> source = String::NewFromUtf8(info.GetIsolate(), js_file.c_str());
Handle<Script> script = Script::Compile(source, info[i]);
info.GetReturnValue().Set(script->Run());
#endif
switch_safe_free(path);
return;
}
}
switch_safe_free(path);
}
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to include javascript file"));
}
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(Sleep)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
int32_t msec = 0;
if (info.Length() > 0) {
msec = info[0]->Int32Value();
}
if (msec) {
switch_yield(msec * 1000);
} else {
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "No time specified"));
}
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(Use)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
if (info.Length() > 0) {
String::Utf8Value str(info[0]);
char *mod_name = *str;
if (mod_name) {
const v8_mod_interface_t *mp;
if ((mp = (v8_mod_interface_t *)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->v8_mod_load(info);
} else {
char *err = switch_mprintf("Error loading %s", mod_name);
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), err));
free(err);
}
}
} else {
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
}
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(ApiExecute)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
if (info.Length() > 0) {
String::Utf8Value str(info[0]);
const char *cmd = js_safe_str(*str);
string arg;
switch_core_session_t *session = NULL;
switch_stream_handle_t stream = { 0 };
if (!strcasecmp(cmd, "jsapi")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid API Call!\n");
info.GetReturnValue().Set(false);
return;
}
if (info.Length() > 1) {
String::Utf8Value str2(info[1]);
arg = js_safe_str(*str2);
}
if (info.Length() > 2) {
if (!info[2].IsEmpty() && info[2]->IsObject()) {
Handle<Object> session_obj = Handle<Object>::Cast(info[2]);
FSSession *obj = JSBase::GetInstance<FSSession>(session_obj);
if (obj) {
session = obj->GetSession();
}
}
}
SWITCH_STANDARD_STREAM(stream);
switch_api_execute(cmd, arg.c_str(), session, &stream);
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), switch_str_nil((char *) stream.data)));
switch_safe_free(stream.data);
} else {
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), ""));
}
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(Email)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
string to, from, headers, body, file, convert_cmd, convert_ext;
if (info.Length() > 0) {
String::Utf8Value str(info[0]);
to = js_safe_str(*str);
}
if (info.Length() > 1) {
String::Utf8Value str(info[1]);
from = js_safe_str(*str);
}
if (info.Length() > 2) {
String::Utf8Value str(info[2]);
headers = js_safe_str(*str);
}
if (info.Length() > 3) {
String::Utf8Value str(info[3]);
body = js_safe_str(*str);
}
if (info.Length() > 4) {
String::Utf8Value str(info[4]);
file = js_safe_str(*str);
}
if (info.Length() > 5) {
String::Utf8Value str(info[5]);
convert_cmd = js_safe_str(*str);
}
if (info.Length() > 6) {
String::Utf8Value str(info[6]);
convert_ext = js_safe_str(*str);
}
if (to.c_str() && from.c_str() && headers.c_str() && body.c_str() && switch_simple_email(to.c_str(), from.c_str(), headers.c_str(), body.c_str(), file.c_str(), convert_cmd.c_str(), convert_ext.c_str()) == SWITCH_TRUE) {
info.GetReturnValue().Set(true);
return;
}
info.GetReturnValue().Set(false);
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(Bridge)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
FSSession *jss_a = NULL, *jss_b = NULL;
Handle<Object> obj_a;
Handle<Object> obj_b;
void *bp = NULL;
switch_input_callback_function_t dtmf_func = NULL;
FSInputCallbackState cb_state;
info.GetReturnValue().Set(false);
if (info.Length() > 1) {
if (info[0]->IsObject()) {
obj_a = Handle<Object>::Cast(info[0]);
if (!(jss_a = JSBase::GetInstance<FSSession>(obj_a))) {
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Cannot find session A"));
return;
}
}
if (info[1]->IsObject()) {
obj_b = Handle<Object>::Cast(info[1]);
if (!(jss_b = JSBase::GetInstance<FSSession>(obj_b))) {
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Cannot find session B"));
return;
}
}
}
if (!(jss_a && jss_a->GetSession())) {
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "session A is not ready!"));
return;
}
if (!(jss_b && jss_b->GetSession())) {
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "session B is not ready!"));
return;
}
if (info.Length() > 2) {
Handle<Function> func = JSBase::GetFunctionFromArg(info.GetIsolate(), info[2]);
if (!func.IsEmpty()) {
cb_state.function.Reset(info.GetIsolate(), func);
if (info.Length() > 3 && !info[3].IsEmpty()) {
cb_state.arg.Reset(info.GetIsolate(), info[3]);
}
cb_state.jss_a = jss_a;
cb_state.jss_b = jss_b;
cb_state.session_obj_a.Reset(info.GetIsolate(), obj_a);
cb_state.session_obj_b.Reset(info.GetIsolate(), obj_b);
cb_state.session_state = jss_a;
cb_state.context.Reset(info.GetIsolate(), info.GetIsolate()->GetCurrentContext());
dtmf_func = FSSession::CollectInputCallback;
bp = &cb_state;
}
}
JS_EXECUTE_LONG_RUNNING_C_CALL_WITH_UNLOCKER(switch_ivr_multi_threaded_bridge(jss_a->GetSession(), jss_b->GetSession(), dtmf_func, bp, bp));
info.GetReturnValue().Set(true);
}
/* Replace this with more robust version later */
JS_GLOBAL_FUNCTION_IMPL_STATIC(System)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
char *cmd;
int result;
info.GetReturnValue().Set(false);
if (info.Length() > 0) {
String::Utf8Value str(info[0]);
cmd = *str;
if (cmd) {
result = switch_system(cmd, SWITCH_TRUE);
info.GetReturnValue().Set(Integer::New(info.GetIsolate(), result));
return;
}
}
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
}
JS_GLOBAL_FUNCTION_IMPL_STATIC(FileDelete)
{
JS_CHECK_SCRIPT_STATE();
HandleScope handle_scope(info.GetIsolate());
const char *path;
info.GetReturnValue().Set(false);
if (info.Length() > 0) {
String::Utf8Value str(info[0]);
path = *str;
if (path) {
if ((switch_file_remove(path, NULL)) == SWITCH_STATUS_SUCCESS) {
info.GetReturnValue().Set(true);
}
return;
}
}
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
}
static const js_function_t fs_proc[] = {
{"console_log", FSGlobal::Log}, // Deprecated
{"consoleLog", FSGlobal::Log},
{"log", FSGlobal::Log}, // Short version of 'consoleLog()'
{"getGlobalVariable", FSGlobal::GlobalGet},
{"setGlobalVariable", FSGlobal::GlobalSet},
{"exit", FSGlobal::Exit},
{"include", FSGlobal::Include},
{"require", FSGlobal::Include}, // Extra version of 'include()'
{"bridge", FSGlobal::Bridge},
{"email", FSGlobal::Email},
{"apiExecute", FSGlobal::ApiExecute},
{"use", FSGlobal::Use},
{"msleep", FSGlobal::Sleep},
{"fileDelete", FSGlobal::FileDelete},
{"system", FSGlobal::System},
{"fetchURL", FSGlobal::FetchURL}, // Deprecated
{"fetchURLHash", FSGlobal::FetchURLHash}, // Deprecated
{"fetchURLFile", FSGlobal::FetchURLFile}, // Deprecated
{"fetchUrl", FSGlobal::FetchURL},
{"fetchUrlHash", FSGlobal::FetchURLHash},
{"fetchUrlFile", FSGlobal::FetchURLFile},
{0}
};
const js_function_t *FSGlobal::GetFunctionDefinitions()
{
return fs_proc;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/