diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index d50f896206..11c7a8c80a 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -153,6 +153,7 @@ struct switch_media_bug { uint32_t flags; uint8_t ready; time_t stop_time; + switch_thread_id_t thread_id; struct switch_media_bug *next; }; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 4fe49cc6c5..ed7c814062 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -830,6 +830,7 @@ SMBF_WRITE_REPLACE - Replace the Write Stream SMBF_READ_REPLACE - Replace the Read Stream SMBF_STEREO - Record in stereo SMBF_ANSWER_RECORD_REQ - Don't record until the channel is answered +SMBF_THREAD_LOCK - Only let the same thread who created the bug remove it. */ typedef enum { @@ -840,7 +841,8 @@ typedef enum { SMBF_READ_REPLACE = (1 << 3), SMBF_READ_PING = (1 << 4), SMBF_STEREO = (1 << 5), - SMBF_RECORD_ANSWER_REQ = (1 << 6) + SMBF_RECORD_ANSWER_REQ = (1 << 6), + SMBF_THREAD_LOCK = (1 << 7) } switch_media_bug_flag_t; /*! diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 16be182bb4..34cab0e514 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1748,11 +1748,11 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session } else if (!strchr(dest, '@')) { char buf[128]; tech_pvt->e_dest = switch_core_session_strdup(nsession, dest); - if (sofia_reg_find_reg_url(profile, dest, profile_name, buf, sizeof(buf))) { + if (sofia_reg_find_reg_url(profile, dest, profile->name, buf, sizeof(buf))) { tech_pvt->dest = switch_core_session_strdup(nsession, buf); - tech_pvt->local_url = switch_core_session_sprintf(nsession, "%s@%s", dest, profile_name); + tech_pvt->local_url = switch_core_session_sprintf(nsession, "%s@%s", dest, profile->name); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", dest, profile_name); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", dest, profile->name); cause = SWITCH_CAUSE_NO_ROUTE_DESTINATION; goto error; } diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index 47b4ed6300..07307a3314 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -244,6 +244,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t switch_buffer_create_dynamic(&bug->raw_write_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, MAX_BUG_BUFFER); switch_mutex_init(&bug->write_mutex, SWITCH_MUTEX_NESTED, session->pool); } + + if ((bug->flags & SMBF_THREAD_LOCK)) { + bug->thread_id = switch_thread_self(); + } + + bug->ready = 1; switch_thread_rwlock_wrlock(session->bug_rwlock); bug->next = session->bugs; @@ -269,6 +275,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_all(switch_core_ses if (session->bugs) { switch_thread_rwlock_wrlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { + if (bp->thread_id && bp->thread_id != switch_thread_self()) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n"); + continue; + } + if (bp->callback) { bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE); } @@ -287,6 +298,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_close(switch_media_bug_t * { switch_media_bug_t *bp = *bug; if (bp) { + if (bp->thread_id && bp->thread_id != switch_thread_self()) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n"); + return SWITCH_STATUS_FALSE; + } + if (bp->callback) { bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE); bp->ready = 0; @@ -308,6 +324,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(switch_core_session if (session->bugs) { switch_thread_rwlock_wrlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { + if (bp->thread_id && bp->thread_id != switch_thread_self()) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n"); + continue; + } + if (!bp->ready) { continue; } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index a7d4a9aa19..ff779042ba 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -657,7 +657,8 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t * switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_NOTICE, "Close Channel %s [%s]\n", switch_channel_get_name((*session)->channel), switch_channel_state_name(switch_channel_get_state((*session)->channel))); - + + switch_core_media_bug_remove_all(*session); switch_ivr_deactivate_unicast(*session); switch_scheduler_del_task_group((*session)->uuid_str); @@ -674,7 +675,7 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t * switch_event_fire(&event); } - switch_core_media_bug_remove_all(*session); + switch_buffer_destroy(&(*session)->raw_read_buffer); switch_buffer_destroy(&(*session)->raw_write_buffer); switch_ivr_clear_speech_cache(*session); @@ -694,10 +695,7 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t * thr switch_core_session_t *session = obj; session->thread = thread; - - switch_core_session_run(session); - switch_core_media_bug_remove_all(session); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session %"SWITCH_SIZE_T_FMT" (%s) Locked, Waiting on external entities\n", session->id, switch_channel_get_name(session->channel)); switch_core_session_write_lock(session); diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 6aebd8918f..6dd3bd774f 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -503,9 +503,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session switch_channel_t *tchannel = switch_core_session_get_channel(tsession); switch_frame_t *read_frame, write_frame = { 0 }; switch_codec_t codec = {0}; - int16_t buf[1024]; + int16_t buf[8192]; switch_codec_t *tread_codec = switch_core_session_get_read_codec(tsession); - + int tlen = tread_codec->implementation->bytes_per_frame; + ep = switch_core_session_alloc(session, sizeof(*ep)); switch_channel_pre_answer(channel); @@ -543,7 +544,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session if (switch_core_media_bug_add(tsession, eavesdrop_callback, ep, 0, - SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_REPLACE | SMBF_WRITE_REPLACE | SMBF_READ_PING, + SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_REPLACE | SMBF_WRITE_REPLACE | SMBF_READ_PING | SMBF_THREAD_LOCK, &bug) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot attach bug\n"); goto end; @@ -630,11 +631,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session switch_buffer_unlock(ep->w_buffer); } - - if (len > tread_codec->implementation->bytes_per_frame) { - len = tread_codec->implementation->bytes_per_frame; + if (len > tlen) { + len = tlen; } - + if (switch_buffer_inuse(ep->buffer) >= len) { switch_buffer_lock(ep->buffer); while (switch_buffer_inuse(ep->buffer) >= len) {