Author: anthm Date: Tue Mar 20 16:37:52 2007 New Revision: 4690 Modified: freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c freeswitch/trunk/src/switch_core.c freeswitch/trunk/src/switch_ivr.c Log: update Modified: freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c ============================================================================== --- freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c (original) +++ freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c Tue Mar 20 16:37:52 2007 @@ -233,7 +233,7 @@ 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 @@ break; } + return SWITCH_TRUE; } static void bugtest_function(switch_core_session_t *session, char *data) Modified: freeswitch/trunk/src/switch_core.c ============================================================================== --- freeswitch/trunk/src/switch_core.c (original) +++ freeswitch/trunk/src/switch_core.c Tue Mar 20 16:37:52 2007 @@ -366,7 +366,10 @@ *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 @@ 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_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 @@ } 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 @@ } 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_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); } Modified: freeswitch/trunk/src/switch_ivr.c ============================================================================== --- freeswitch/trunk/src/switch_ivr.c (original) +++ freeswitch/trunk/src/switch_ivr.c Tue Mar 20 16:37:52 2007 @@ -555,7 +555,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ default: break; } + + return SWITCH_TRUE; } SWITCH_DECLARE(switch_status_t) switch_ivr_stop_detect_speech(switch_core_session_t *session)