From 7e6ba429e7064101752a0e0fc0d7d9fc18f300fe Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 6 Jan 2017 21:57:20 +0300 Subject: [PATCH] FS-9928 [mod_v8] Implement Event Hooks in JavaScript --- conf/curl/autoload_configs/v8.conf.xml | 2 + conf/insideout/autoload_configs/v8.conf.xml | 2 + conf/vanilla/autoload_configs/v8.conf.xml | 2 + .../mod_v8/conf/autoload_configs/v8.conf.xml | 2 + src/mod/languages/mod_v8/mod_v8.cpp | 66 +++++++++++++++++-- src/mod/languages/mod_v8/mod_v8.h | 9 +++ 6 files changed, 78 insertions(+), 5 deletions(-) diff --git a/conf/curl/autoload_configs/v8.conf.xml b/conf/curl/autoload_configs/v8.conf.xml index df0fddd5a3..4f1e5f64f7 100644 --- a/conf/curl/autoload_configs/v8.conf.xml +++ b/conf/curl/autoload_configs/v8.conf.xml @@ -2,6 +2,8 @@ + + diff --git a/conf/insideout/autoload_configs/v8.conf.xml b/conf/insideout/autoload_configs/v8.conf.xml index df0fddd5a3..4f1e5f64f7 100644 --- a/conf/insideout/autoload_configs/v8.conf.xml +++ b/conf/insideout/autoload_configs/v8.conf.xml @@ -2,6 +2,8 @@ + + diff --git a/conf/vanilla/autoload_configs/v8.conf.xml b/conf/vanilla/autoload_configs/v8.conf.xml index df0fddd5a3..4f1e5f64f7 100644 --- a/conf/vanilla/autoload_configs/v8.conf.xml +++ b/conf/vanilla/autoload_configs/v8.conf.xml @@ -2,6 +2,8 @@ + + diff --git a/src/mod/languages/mod_v8/conf/autoload_configs/v8.conf.xml b/src/mod/languages/mod_v8/conf/autoload_configs/v8.conf.xml index df0fddd5a3..4f1e5f64f7 100644 --- a/src/mod/languages/mod_v8/conf/autoload_configs/v8.conf.xml +++ b/src/mod/languages/mod_v8/conf/autoload_configs/v8.conf.xml @@ -2,6 +2,8 @@ + + diff --git a/src/mod/languages/mod_v8/mod_v8.cpp b/src/mod/languages/mod_v8/mod_v8.cpp index b9cc9b8a5d..bdbee6fcdc 100644 --- a/src/mod/languages/mod_v8/mod_v8.cpp +++ b/src/mod/languages/mod_v8/mod_v8.cpp @@ -276,7 +276,7 @@ static switch_status_t load_modules(void) switch_core_hash_init(&module_manager.load_hash); if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - switch_xml_t mods, ld, settings, param; + switch_xml_t mods, ld, settings, param, hook; if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { @@ -293,6 +293,37 @@ static switch_status_t load_modules(void) } } } + + for (hook = switch_xml_child(settings, "hook"); hook; hook = hook->next) { + char *event = (char *)switch_xml_attr_soft(hook, "event"); + char *subclass = (char *)switch_xml_attr_soft(hook, "subclass"); + char *script = (char *)switch_xml_attr_soft(hook, "script"); + switch_event_types_t evtype; + + if (!zstr(script)) { + script = switch_core_strdup(globals.pool, script); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "hook params: '%s' | '%s' | '%s'\n", event, subclass, script); + + if (switch_name_event(event, &evtype) == SWITCH_STATUS_SUCCESS) { + if (!zstr(script)) { + if (switch_event_bind(modname, evtype, !zstr(subclass) ? subclass : SWITCH_EVENT_SUBCLASS_ANY, + v8_event_handler, script) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "event handler for '%s' set to '%s'\n", switch_event_name(evtype), script); + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cannot set event handler: unsuccessful bind\n"); + } + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cannot set event handler: no script name for event type '%s'\n", event); + } + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cannot set event handler: unknown event type '%s'\n", event); + } + } } if ((mods = switch_xml_child(cfg, "modules"))) { @@ -403,7 +434,7 @@ static char *v8_get_script_path(const char *script_file) } } -static int v8_parse_and_execute(switch_core_session_t *session, const char *input_code, switch_stream_handle_t *api_stream, switch_event_t *message, v8_xml_handler_t* xml_handler) +static int v8_parse_and_execute(switch_core_session_t *session, const char *input_code, switch_stream_handle_t *api_stream, v8_event_t *v8_event, v8_xml_handler_t* xml_handler) { string res; JSMain *js; @@ -509,8 +540,9 @@ static int v8_parse_and_execute(switch_core_session_t *session, const char *inpu context->Global()->Set(String::NewFromUtf8(isolate, "session"), Boolean::New(isolate, false)); } - if (message) { - FSEvent::New(message, "message", js); + if (v8_event) { + if (v8_event->event && v8_event->var_name) + FSEvent::New(v8_event->event, v8_event->var_name, js); } if (api_stream) { @@ -724,6 +756,25 @@ static switch_xml_t v8_fetch(const char *section, return xml; } +static void v8_event_handler(switch_event_t *event) +{ + char *script = NULL; + + if (event->bind_user_data) { + script = strdup((char *)event->bind_user_data); + } + + v8_event_t v8_event; + + v8_event.event = event; + v8_event.var_name = "event"; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "v8 event hook: execute '%s'\n", (char *)script); + v8_parse_and_execute(NULL, script, NULL, &v8_event, NULL); + + switch_safe_free(script); +} + SWITCH_BEGIN_EXTERN_C SWITCH_STANDARD_APP(v8_dp_function) @@ -733,7 +784,12 @@ SWITCH_STANDARD_APP(v8_dp_function) SWITCH_STANDARD_CHAT_APP(v8_chat_function) { - v8_parse_and_execute(NULL, data, NULL, message, NULL); + v8_event_t v8_event; + + v8_event.event = message; + v8_event.var_name = "message"; + + v8_parse_and_execute(NULL, data, NULL, &v8_event, NULL); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/languages/mod_v8/mod_v8.h b/src/mod/languages/mod_v8/mod_v8.h index 1f97795036..6d5c75c881 100644 --- a/src/mod/languages/mod_v8/mod_v8.h +++ b/src/mod/languages/mod_v8/mod_v8.h @@ -24,6 +24,7 @@ * Contributor(s): * Peter Olsson * Anthony Minessale II + * Andrey Volk * * mod_v8.h -- JavaScript FreeSWITCH module header file * @@ -71,12 +72,20 @@ typedef struct { char* XML_STRING; } v8_xml_handler_t; +/* Struct that stores a javascript variable's name for an event */ +typedef struct { + const char* var_name; + switch_event_t *event; +} +v8_event_t; + SWITCH_END_EXTERN_C void v8_add_event_handler(void *event_handler); void v8_remove_event_handler(void *event_handler); static switch_xml_t v8_fetch(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data); +static void v8_event_handler(switch_event_t *event); #endif /* MOD_V8_H */