From 7542843deb7cdd97a53c08500deb65e00ec48784 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 1 Mar 2006 04:47:34 +0000 Subject: [PATCH] add record to js git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@706 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_ivr.h | 1 + .../applications/mod_playback/mod_playback.c | 2 +- .../mod_spidermonkey/mod_spidermonkey.c | 159 +++++++++++++++++- src/switch_ivr.c | 31 ++-- 4 files changed, 175 insertions(+), 18 deletions(-) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 31f45a09ce..80a06ebc84 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -117,6 +117,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_play_file(switch_core_session *session, \note passing a NULL dtmf_callback nad a not NULL buf indicates to copy any dtmf to buf and stop recording. */ SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *session, + switch_file_handle *fh, char *file, switch_dtmf_callback_function dtmf_callback, void *buf, diff --git a/src/mod/applications/mod_playback/mod_playback.c b/src/mod/applications/mod_playback/mod_playback.c index e7c35de991..10089ba43e 100644 --- a/src/mod/applications/mod_playback/mod_playback.c +++ b/src/mod/applications/mod_playback/mod_playback.c @@ -77,7 +77,7 @@ static void record_function(switch_core_session *session, char *data) channel = switch_core_session_get_channel(session); assert(channel != NULL); - if (switch_ivr_record_file(session, data, on_dtmf, NULL, 0) != SWITCH_STATUS_SUCCESS) { + if (switch_ivr_record_file(session, NULL, data, on_dtmf, NULL, 0) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel); } diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index c78d902d02..6a7049c3de 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -141,7 +141,7 @@ static switch_status init_js(void) } -static switch_status js_dtmf_callback(switch_core_session *session, char *dtmf, void *buf, unsigned int buflen) +static switch_status js_stream_dtmf_callback(switch_core_session *session, char *dtmf, void *buf, unsigned int buflen) { char code[2048]; struct dtmf_callback_state *cb_state = buf; @@ -248,6 +248,158 @@ static switch_status js_dtmf_callback(switch_core_session *session, char *dtmf, return SWITCH_STATUS_FALSE; } + +static switch_status js_record_dtmf_callback(switch_core_session *session, char *dtmf, void *buf, unsigned int buflen) +{ + char code[2048]; + struct dtmf_callback_state *cb_state = buf; + struct js_session *jss = cb_state->session_state; + switch_file_handle *fh = cb_state->extra; + jsval rval; + char *ret; + + if(!jss) { + return SWITCH_STATUS_FALSE; + } + + if (cb_state->digit_count || (cb_state->code_buffer[0] > 47 && cb_state->code_buffer[0] < 58)) { + char *d; + if (!cb_state->digit_count) { + cb_state->digit_count = atoi(cb_state->code_buffer); + } + + for(d = dtmf; *d; d++) { + cb_state->ret_buffer[cb_state->ret_buffer_len++] = *d; + if ((cb_state->ret_buffer_len > cb_state->digit_count)|| + (cb_state->ret_buffer_len > sizeof(cb_state->ret_buffer))|| + (cb_state->ret_buffer_len >= cb_state->digit_count) + ) { + return SWITCH_STATUS_FALSE; + } + } + return SWITCH_STATUS_SUCCESS; + } else { + snprintf(code, sizeof(code), "~%s(\"%s\")", cb_state->code_buffer, dtmf); + eval_some_js(code, jss->cx, jss->obj, &rval); + ret = JS_GetStringBytes(JS_ValueToString(jss->cx, rval)); + + if (!strcasecmp(ret, "pause")) { + if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) { + switch_clear_flag(fh, SWITCH_FILE_PAUSE); + } else { + switch_set_flag(fh, SWITCH_FILE_PAUSE); + } + return SWITCH_STATUS_SUCCESS; + } else if (!strcasecmp(ret, "restart")) { + unsigned int pos = 0; + fh->speed = 0; + switch_core_file_seek(fh, &pos, 0, SEEK_SET); + return SWITCH_STATUS_SUCCESS; + } + + if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) { + return SWITCH_STATUS_SUCCESS; + } + + if (ret) { + switch_copy_string(cb_state->ret_buffer, ret, sizeof(cb_state->ret_buffer)); + } + } + + return SWITCH_STATUS_FALSE; +} + + +static switch_status js_speak_dtmf_callback(switch_core_session *session, char *dtmf, void *buf, unsigned int buflen) +{ + char code[2048]; + struct dtmf_callback_state *cb_state = buf; + struct js_session *jss = cb_state->session_state; + jsval rval; + char *ret; + + if(!jss) { + return SWITCH_STATUS_FALSE; + } + + if (cb_state->digit_count || (cb_state->code_buffer[0] > 47 && cb_state->code_buffer[0] < 58)) { + char *d; + if (!cb_state->digit_count) { + cb_state->digit_count = atoi(cb_state->code_buffer); + } + + for(d = dtmf; *d; d++) { + cb_state->ret_buffer[cb_state->ret_buffer_len++] = *d; + if ((cb_state->ret_buffer_len > cb_state->digit_count)|| + (cb_state->ret_buffer_len > sizeof(cb_state->ret_buffer))|| + (cb_state->ret_buffer_len >= cb_state->digit_count) + ) { + return SWITCH_STATUS_FALSE; + } + } + return SWITCH_STATUS_SUCCESS; + } else { + snprintf(code, sizeof(code), "~%s(\"%s\")", cb_state->code_buffer, dtmf); + eval_some_js(code, jss->cx, jss->obj, &rval); + ret = JS_GetStringBytes(JS_ValueToString(jss->cx, rval)); + + if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) { + return SWITCH_STATUS_SUCCESS; + } + + if (ret) { + switch_copy_string(cb_state->ret_buffer, ret, sizeof(cb_state->ret_buffer)); + } + } + + return SWITCH_STATUS_FALSE; +} + +static JSBool session_recordfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + struct js_session *jss = JS_GetPrivate(cx, obj); + switch_channel *channel; + char *file_name = NULL; + char *dtmf_callback = NULL; + void *bp = NULL; + int len = 0; + switch_dtmf_callback_function dtmf_func = NULL; + struct dtmf_callback_state cb_state = {0}; + switch_file_handle fh; + + channel = switch_core_session_get_channel(jss->session); + assert(channel != NULL); + + if (argc > 0) { + file_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); + if (switch_strlen_zero(file_name)) { + return JS_FALSE; + } + } + if (argc > 1) { + dtmf_callback = JS_GetStringBytes(JS_ValueToString(cx, argv[1])); + if (switch_strlen_zero(dtmf_callback)) { + dtmf_callback = NULL; + } else { + memset(&cb_state, 0, sizeof(cb_state)); + switch_copy_string(cb_state.code_buffer, dtmf_callback, sizeof(cb_state.code_buffer)); + cb_state.code_buffer_len = strlen(cb_state.code_buffer); + cb_state.session_state = jss; + dtmf_func = js_record_dtmf_callback; + bp = &cb_state; + len = sizeof(cb_state); + } + } + + memset(&fh, 0, sizeof(fh)); + cb_state.extra = &fh; + + switch_ivr_record_file(jss->session, &fh, file_name, dtmf_func, bp, len); + *rval = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, cb_state.ret_buffer)); + + return (switch_channel_get_state(channel) == CS_EXECUTE) ? JS_TRUE : JS_FALSE; +} + static JSBool session_streamfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { struct js_session *jss = JS_GetPrivate(cx, obj); @@ -285,7 +437,7 @@ static JSBool session_streamfile(JSContext *cx, JSObject *obj, uintN argc, jsval switch_copy_string(cb_state.code_buffer, dtmf_callback, sizeof(cb_state.code_buffer)); cb_state.code_buffer_len = strlen(cb_state.code_buffer); cb_state.session_state = jss; - dtmf_func = js_dtmf_callback; + dtmf_func = js_stream_dtmf_callback; bp = &cb_state; len = sizeof(cb_state); } @@ -335,7 +487,7 @@ static JSBool session_speak(JSContext *cx, JSObject *obj, uintN argc, jsval *arg switch_copy_string(cb_state.code_buffer, dtmf_callback, sizeof(cb_state.code_buffer)); cb_state.code_buffer_len = strlen(cb_state.code_buffer); cb_state.session_state = jss; - dtmf_func = js_dtmf_callback; + dtmf_func = js_speak_dtmf_callback; bp = &cb_state; len = sizeof(cb_state); } @@ -501,6 +653,7 @@ enum session_tinyid { static JSFunctionSpec session_methods[] = { {"streamFile", session_streamfile, 1}, + {"recordFile", session_recordfile, 1}, {"speak", session_speak, 1}, {"getDigits", session_get_digits, 1}, {"answer", session_answer, 0}, diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 81a546223e..497394dd67 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -148,6 +148,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_collect_digits_count(switch_core_sessio SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *session, + switch_file_handle *fh, char *file, switch_dtmf_callback_function dtmf_callback, void *buf, @@ -155,13 +156,16 @@ SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *sessio { switch_channel *channel; char dtmf[128]; - switch_file_handle fh; + switch_file_handle lfh; switch_frame *read_frame; switch_codec codec, *read_codec; char *codec_name; switch_status status = SWITCH_STATUS_SUCCESS; - memset(&fh, 0, sizeof(fh)); + if (!fh) { + fh = &lfh; + } + memset(fh, 0, sizeof(*fh)); channel = switch_core_session_get_channel(session); assert(channel != NULL); @@ -169,11 +173,11 @@ SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *sessio read_codec = switch_core_session_get_read_codec(session); assert(read_codec != NULL); - fh.channels = read_codec->implementation->number_of_channels; - fh.samplerate = read_codec->implementation->samples_per_second; + fh->channels = read_codec->implementation->number_of_channels; + fh->samplerate = read_codec->implementation->samples_per_second; - if (switch_core_file_open(&fh, + if (switch_core_file_open(fh, file, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { @@ -196,8 +200,8 @@ SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *sessio switch_core_session_set_read_codec(session, &codec); } else { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Raw Codec Activation Failed %s@%dhz %d channels %dms\n", - codec_name, fh.samplerate, fh.channels, read_codec->implementation->microseconds_per_frame / 1000); - switch_core_file_close(&fh); + codec_name, fh->samplerate, fh->channels, read_codec->implementation->microseconds_per_frame / 1000); + switch_core_file_close(fh); return SWITCH_STATUS_GENERR; } @@ -228,13 +232,14 @@ SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *sessio if ((status = switch_core_session_read_frame(session, &read_frame, -1, 0)) != SWITCH_STATUS_SUCCESS) { break; } - - len = (size_t) read_frame->datalen / 2; - switch_core_file_write(&fh, read_frame->data, &len); + if (!switch_test_flag(fh, SWITCH_FILE_PAUSE)) { + len = (size_t) read_frame->datalen / 2; + switch_core_file_write(fh, read_frame->data, &len); + } } switch_core_session_set_read_codec(session, read_codec); - switch_core_file_close(&fh); + switch_core_file_close(fh); return status; } @@ -755,7 +760,7 @@ static void *audio_bridge_thread(switch_thread *thread, void *obj) } } - switch_channel_hangup(chan_b); + //switch_channel_hangup(chan_b); data->running = 0; return NULL; @@ -891,8 +896,6 @@ SWITCH_DECLARE(switch_status) switch_ivr_multi_threaded_bridge(switch_core_sessi switch_yield(1000); } } - - } return SWITCH_STATUS_SUCCESS; }