]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
core framework for reverse media bugs
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 31 Jan 2007 23:09:33 +0000 (23:09 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 31 Jan 2007 23:09:33 +0000 (23:09 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4105 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_core.h
src/include/switch_types.h
src/mod/applications/mod_ivrtest/mod_ivrtest.c
src/switch_core.c
src/switch_ivr.c

index cb07dd2ebb188de39fc71d6b00e7ae83d05b9268..826b88ebd1174208ff8aed5ca9a043775671818c 100644 (file)
@@ -136,6 +136,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t
 */
 SWITCH_DECLARE(void *) switch_core_media_bug_get_user_data(switch_media_bug_t *bug);
 
+/*!
+  \brief Obtain a replace frame from a media bug
+  \param bug the bug to get the data from
+*/
+SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_replace_frame(switch_media_bug_t *bug);
+
+/*!
+  \brief Set a return replace frame
+  \param bug the bug to set the frame on
+  \param frame the frame to set
+*/
+SWITCH_DECLARE(void) switch_core_media_bug_set_replace_frame(switch_media_bug_t *bug, switch_frame_t *frame);
+
 /*!
   \brief Remove a media bug from the session
   \param session the session to remove the bug from
index b49d74cbc34e8ad81f4daf4eb2006feccdb865b6..9264e2a4378f80466c08feb07097db195f5d4c8d 100644 (file)
@@ -140,6 +140,7 @@ typedef enum {
        SWITCH_ABC_TYPE_INIT,
        SWITCH_ABC_TYPE_READ,
        SWITCH_ABC_TYPE_WRITE,
+       SWITCH_ABC_TYPE_WRITE_REPLACE,
        SWITCH_ABC_TYPE_CLOSE,
 } switch_abc_type_t;
 
@@ -654,12 +655,14 @@ typedef enum {
 <pre>
 SMBF_READ_STREAM - Include the Read Stream
 SMBF_WRITE_STREAM - Include the Write Stream
+SMBF_WRITE_STREAM - Replace the Write Stream
 </pre>
 */
 typedef enum {
        SMBF_BOTH = 0,
        SMBF_READ_STREAM = (1 << 0),
-       SMBF_WRITE_STREAM = (1 << 1)
+       SMBF_WRITE_STREAM = (1 << 1),
+       SMBF_WRITE_REPLACE = (1 << 2)
 } switch_media_bug_flag_t;
 
 /*!
index 688eacfebd0a942faa53d6692acc488efca98980..4f9496467e6c7162ea66baf43969ac0224df29f6 100644 (file)
@@ -231,6 +231,39 @@ static void tts_function(switch_core_session_t *session, char *data)
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Done\n");
 }
 
+static void bug_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
+{
+    switch_frame_t *frame;
+
+    switch(type) {
+       case SWITCH_ABC_TYPE_WRITE_REPLACE:
+        frame = switch_core_media_bug_get_replace_frame(bug);
+        switch_core_media_bug_set_replace_frame(bug, frame);
+        printf("W00t\n");
+        break;
+    default:
+        break;
+    }
+
+}
+
+static void bugtest_function(switch_core_session_t *session, char *data)
+{
+       switch_media_bug_t *bug;
+       switch_channel_t *channel = switch_core_session_get_channel(session);
+    switch_status_t status;
+
+       if ((status = switch_core_media_bug_add(session,
+                                                                                       bug_callback,
+                                                                                       NULL,
+                                                                                       SMBF_WRITE_REPLACE,
+                                                                                       &bug)) != SWITCH_STATUS_SUCCESS) {
+               switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+        return;
+       }
+    switch_ivr_play_file(session, NULL, data, NULL);
+}
+
 #if 1
 static void asrtest_function(switch_core_session_t *session, char *data)
 {
@@ -423,11 +456,18 @@ static const switch_state_handler_table_t state_handlers = {
 
 
 
+static const switch_application_interface_t bug_application_interface = {
+       /*.interface_name */ "bugtest",
+       /*.application_function */ bugtest_function,
+       NULL, NULL, NULL,
+       /*.next*/ NULL
+};
+
 static const switch_application_interface_t ivr_application_interface = {
        /*.interface_name */ "ivrmenu",
        /*.application_function */ ivr_application_function,
        NULL, NULL, NULL,
-       /*.next*/ NULL
+       /*.next*/ &bug_application_interface
 };
 
 static const switch_application_interface_t xml_application_interface = {
index 16dd598247bb106cda3956694a5df2a02d004f49..f57648086f77ee1e1ab0bf94075e3618a44cd432 100644 (file)
@@ -59,6 +59,8 @@
 struct switch_media_bug {
        switch_buffer_t *raw_write_buffer;
        switch_buffer_t *raw_read_buffer;
+    switch_frame_t *replace_frame_in;
+    switch_frame_t *replace_frame_out;
        switch_media_bug_callback_t callback;
        switch_mutex_t *read_mutex;
        switch_mutex_t *write_mutex;
@@ -176,6 +178,17 @@ static void switch_core_media_bug_destroy(switch_media_bug_t *bug)
        switch_buffer_destroy(&bug->raw_write_buffer);
 }
 
+
+SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_replace_frame(switch_media_bug_t *bug)
+{
+    return bug->replace_frame_in;
+}
+
+SWITCH_DECLARE(void) switch_core_media_bug_set_replace_frame(switch_media_bug_t *bug, switch_frame_t *frame)
+{
+    bug->replace_frame_out = frame;
+}
+
 SWITCH_DECLARE(void *) switch_core_media_bug_get_user_data(switch_media_bug_t *bug)
 {
        return bug->user_data;
@@ -277,9 +290,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t
                                                                                                                  switch_media_bug_t **new_bug)
 
 {
-       switch_media_bug_t *bug;
+       switch_media_bug_t *bug, *bp;
        switch_size_t bytes;
 
+    if (flags & SMBF_WRITE_REPLACE) {
+        switch_thread_rwlock_wrlock(session->bug_rwlock);
+        for (bp = session->bugs; bp; bp = bp->next) {
+            if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
+                switch_thread_rwlock_unlock(session->bug_rwlock);
+                return SWITCH_STATUS_GENERR;
+            }
+        }
+        switch_thread_rwlock_unlock(session->bug_rwlock);
+    }
+
        if (!(bug = switch_core_session_alloc(session, sizeof(*bug)))) {
                return SWITCH_STATUS_MEMERR;
        }
@@ -2087,6 +2112,7 @@ static switch_status_t perform_write(switch_core_session_t *session, switch_fram
        switch_status_t status = SWITCH_STATUS_FALSE;
 
        if (session->endpoint_interface->io_routines->write_frame) {
+
                if ((status =
                         session->endpoint_interface->io_routines->write_frame(session, frame, timeout, flags,
                                                                                                                                   stream_id)) == SWITCH_STATUS_SUCCESS) {
@@ -2230,15 +2256,25 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
                                        if (bp->callback) {
                                                bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE);
                                        }
+                               } else if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
+                    do_bugs = 0;
+                                       if (bp->callback) {
+                        bp->replace_frame_in = frame;
+                        bp->replace_frame_out = NULL;
+                                               bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE);
+                        write_frame = bp->replace_frame_out;
+                                       }
                                }
                        }
                        switch_thread_rwlock_unlock(session->bug_rwlock);
                }
+
                if (do_bugs) {
-                       do_write = 1;
-                       write_frame = frame;
-                       goto done;
+            do_write = 1;
+            write_frame = frame;
+            goto done;
                }
+
                if (session->write_codec) {
                        if (write_frame->datalen == session->write_codec->implementation->bytes_per_frame) {
                                perfect = TRUE;
index 92d1455b212a215d1317b137dfa3c3c67ea7afe0..0e08a3bf51f404e9d1583ec06557b882da7831ed 100644 (file)
@@ -563,6 +563,7 @@ static void record_callback(switch_media_bug_t *bug, void *user_data, switch_abc
                }
                break;
        case SWITCH_ABC_TYPE_WRITE:
+    default:
                break;
        }
 }
@@ -787,6 +788,7 @@ static void speech_callback(switch_media_bug_t *bug, void *user_data, switch_abc
                }
                break;
        case SWITCH_ABC_TYPE_WRITE:
+    default:
                break;
        }
 }