]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add record to js
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 1 Mar 2006 04:47:34 +0000 (04:47 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 1 Mar 2006 04:47:34 +0000 (04:47 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@706 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_ivr.h
src/mod/applications/mod_playback/mod_playback.c
src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
src/switch_ivr.c

index 31f45a09ced336eedab5699a2ff9ab19fea81873..80a06ebc84d9b57320a14a89e9072dcbed7ae794 100644 (file)
@@ -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,
index e7c35de991395048431c2f8b76202eb2989d57f5..10089ba43effc12785b8a0ca19e24cd2cca32432 100644 (file)
@@ -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);
        }
        
index c78d902d02bebe070f67e54b8dbf9ee7de6ea453..6a7049c3def01082310322caed719fbfed3a9192 100644 (file)
@@ -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}, 
index 81a546223ea15d36730ee3a31fd64aacf6655a67..497394dd6714644d5063b5dd167da8779d8ed93e 100644 (file)
@@ -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;
 }