From 221bf43984e01845938b367199e9308264ee36e7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthony.minessale@gmail.com> Date: Tue, 20 Mar 2007 20:37:52 +0000 Subject: [PATCH] update git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4690 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- .../applications/mod_ivrtest/mod_ivrtest.c | 3 +- src/switch_core.c | 76 +++++++++++++++---- src/switch_ivr.c | 14 +++- 3 files changed, 72 insertions(+), 21 deletions(-) diff --git a/src/mod/applications/mod_ivrtest/mod_ivrtest.c b/src/mod/applications/mod_ivrtest/mod_ivrtest.c index 267de1543a..2afca3c2e4 100644 --- a/src/mod/applications/mod_ivrtest/mod_ivrtest.c +++ b/src/mod/applications/mod_ivrtest/mod_ivrtest.c @@ -233,7 +233,7 @@ 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) +static switch_bool_t bug_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { switch_frame_t *frame; @@ -247,6 +247,7 @@ static void bug_callback(switch_media_bug_t *bug, void *user_data, switch_abc_ty break; } + return SWITCH_TRUE; } static void bugtest_function(switch_core_session_t *session, char *data) diff --git a/src/switch_core.c b/src/switch_core.c index 02eb1fde2c..18f17b2919 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -366,7 +366,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t *new_bug = bug; if (bug->callback) { - bug->callback(bug, bug->user_data, SWITCH_ABC_TYPE_INIT); + switch_bool_t result = bug->callback(bug, bug->user_data, SWITCH_ABC_TYPE_INIT); + if (result == SWITCH_FALSE) { + return switch_core_media_bug_remove(session, new_bug); + } } return SWITCH_STATUS_SUCCESS; @@ -394,9 +397,25 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_all(switch_core_ses return SWITCH_STATUS_FALSE; } +static switch_status_t switch_core_media_bug_close(switch_media_bug_t *bp) +{ + if (bp) { + if (bp->callback) { + bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE); + bp->ready = 0; + } + switch_core_media_bug_destroy(bp); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing BUG from %s\n", switch_channel_get_name(bp->session->channel)); + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(switch_core_session_t *session, switch_media_bug_t **bug) { switch_media_bug_t *bp = NULL, *last = NULL; + switch_status_t status = SWITCH_STATUS_FALSE; if (session->bugs) { switch_thread_rwlock_wrlock(session->bug_rwlock); @@ -416,19 +435,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(switch_core_session } switch_thread_rwlock_unlock(session->bug_rwlock); - if (bp) { - if (bp->callback) { - bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE); - bp->ready = 0; - } - switch_core_media_bug_destroy(bp); + if ((status = switch_core_media_bug_close(bp)) == SWITCH_STATUS_SUCCESS) { *bug = NULL; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing BUG from %s\n", switch_channel_get_name(session->channel)); - return SWITCH_STATUS_SUCCESS; } } - return SWITCH_STATUS_FALSE; + return status; } struct switch_core_port_allocator { @@ -2195,17 +2207,31 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi } if (session->bugs) { - switch_media_bug_t *bp; + switch_media_bug_t *bp, *dp, *last = NULL; + switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) { switch_mutex_lock(bp->read_mutex); switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen); if (bp->callback) { - bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ); + if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ) == SWITCH_FALSE) { + bp->ready = 0; + if (last) { + last->next = bp->next; + } else { + session->bugs = bp->next; + } + switch_mutex_unlock(bp->read_mutex); + dp = bp; + bp = last; + switch_core_media_bug_close(dp); + continue; + } } switch_mutex_unlock(bp->read_mutex); } + last = bp; } switch_thread_rwlock_unlock(session->bug_rwlock); } @@ -2457,7 +2483,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess } if (session->bugs) { - switch_media_bug_t *bp; + switch_media_bug_t *bp, *dp, *last = NULL; + switch_bool_t ok = SWITCH_TRUE; + switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (!bp->ready) { @@ -2468,17 +2496,33 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess switch_buffer_write(bp->raw_write_buffer, write_frame->data, write_frame->datalen); switch_mutex_unlock(bp->write_mutex); if (bp->callback) { - bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE); + ok = 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; + if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE)) == SWITCH_TRUE) { + write_frame = bp->replace_frame_out; + } } } + + if (ok == SWITCH_FALSE) { + bp->ready = 0; + if (last) { + last->next = bp->next; + } else { + session->bugs = bp->next; + } + switch_mutex_unlock(bp->read_mutex); + dp = bp; + bp = last; + switch_core_media_bug_close(dp); + continue; + } + last = bp; } switch_thread_rwlock_unlock(session->bug_rwlock); } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 83b197691c..94b7e2c167 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -555,7 +555,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se return status; } -static void record_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) +static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { switch_file_handle_t *fh = (switch_file_handle_t *) user_data; uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; @@ -586,6 +586,8 @@ static void record_callback(switch_media_bug_t *bug, void *user_data, switch_abc default: break; } + + return SWITCH_TRUE; } SWITCH_DECLARE(switch_status_t) switch_ivr_stop_record_session(switch_core_session_t *session, char *file) @@ -699,7 +701,7 @@ typedef struct { teletone_dtmf_detect_state_t dtmf_detect; } switch_inband_dtmf_t; -static void inband_dtmf_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) +static switch_bool_t inband_dtmf_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { switch_inband_dtmf_t *pvt = (switch_inband_dtmf_t *) user_data; uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; @@ -730,6 +732,8 @@ static void inband_dtmf_callback(switch_media_bug_t *bug, void *user_data, switc default: break; } + + return SWITCH_TRUE; } SWITCH_DECLARE(switch_status_t) switch_ivr_stop_inband_dtmf_session(switch_core_session_t *session) @@ -857,7 +861,7 @@ static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj return NULL; } -static void speech_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) +static switch_bool_t speech_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { struct speech_thread_handle *sth = (struct speech_thread_handle *) user_data; uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; @@ -891,7 +895,7 @@ static void speech_callback(switch_media_bug_t *bug, void *user_data, switch_abc if (switch_core_media_bug_read(bug, &frame) == SWITCH_STATUS_SUCCESS) { if (switch_core_asr_feed(sth->ah, frame.data, frame.datalen, &flags) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error Feeding Data\n"); - return; + return SWITCH_FALSE; } if (switch_core_asr_check_results(sth->ah, &flags) == SWITCH_STATUS_SUCCESS) { switch_mutex_lock(sth->mutex); @@ -905,6 +909,8 @@ static void speech_callback(switch_media_bug_t *bug, void *user_data, switch_abc default: break; } + + return SWITCH_TRUE; } SWITCH_DECLARE(switch_status_t) switch_ivr_stop_detect_speech(switch_core_session_t *session)