diff --git a/src/include/switch_core.h b/src/include/switch_core.h index ee890a80c9..681fbf4dc6 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -248,6 +248,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_close(_Inout_ switch_media SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_all(_In_ switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_core_media_bug_enumerate(switch_core_session_t *session, switch_stream_handle_t *stream); +SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_recordings(switch_core_session_t *orig_session, switch_core_session_t *new_session); /*! \brief Read a frame from the bug diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f881d6f734..dda5588cc7 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4975,6 +4975,14 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, char *br_a = b_private->uuid; if (br_b) { + switch_core_session_t *tmp; + + if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")) && + (tmp = switch_core_session_locate(br_a))) { + switch_core_media_bug_transfer_recordings(session, tmp); + switch_core_session_rwunlock(tmp); + } + switch_ivr_uuid_bridge(br_a, br_b); switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER"); sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); @@ -5478,6 +5486,11 @@ void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void if ((status = switch_ivr_originate(NULL, &tsession, &cause, nhelper->exten_with_params, timeout, NULL, NULL, NULL, switch_channel_get_caller_profile(channel_a), nhelper->vars, SOF_NONE, NULL)) == SWITCH_STATUS_SUCCESS) { if (switch_channel_up(channel_a)) { + + if (switch_true(switch_channel_get_variable(channel_a, "recording_follow_transfer"))) { + switch_core_media_bug_transfer_recordings(session, a_session); + } + tuuid_str = switch_core_session_get_uuid(tsession); switch_ivr_uuid_bridge(nhelper->bridge_to_uuid, tuuid_str); switch_channel_set_variable(channel_a, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER"); @@ -5828,6 +5841,14 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_core_session_rwunlock(tmp); } + + if (switch_true(switch_channel_get_variable(channel_a, "recording_follow_transfer")) && + (tmp = switch_core_session_locate(br_a))) { + switch_core_media_bug_transfer_recordings(session, tmp); + switch_core_session_rwunlock(tmp); + } + + switch_ivr_uuid_bridge(br_b, br_a); switch_channel_set_variable(channel_b, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER"); nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"), diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index 5cc28a3c88..c8a17cfd91 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -392,6 +392,45 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_flush_all(switch_core_sess return SWITCH_STATUS_FALSE; } +SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_recordings(switch_core_session_t *orig_session, switch_core_session_t *new_session) +{ + switch_media_bug_t *bp; + char *list[100] = { 0 }; + int stop_times[100] = { 0 }; + int i = 0, x = 0; + + if (orig_session->bugs) { + switch_channel_t *new_channel = switch_core_session_get_channel(new_session); + const char *save = switch_channel_get_variable(new_channel, "record_append"); + + switch_thread_rwlock_wrlock(orig_session->bug_rwlock); + + switch_channel_set_variable(new_channel, "record_append", "true"); + + for (bp = orig_session->bugs; bp; bp = bp->next) { + if (!strcmp(bp->function, "session_record")) { + list[x] = switch_core_session_strdup(new_session, bp->target); + if (bp->stop_time > 0) { + stop_times[x] = bp->stop_time - switch_epoch_time_now(NULL); + } + x++; + } + } + + switch_thread_rwlock_unlock(orig_session->bug_rwlock); + + for(i = 0; i < x; i++) { + switch_ivr_stop_record_session(orig_session, list[i]); + switch_ivr_record_session(new_session, list[i], stop_times[i], NULL); + } + + switch_channel_set_variable(new_channel, "record_append", save); + + } + + return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; +} + SWITCH_DECLARE(switch_status_t) switch_core_media_bug_enumerate(switch_core_session_t *session, switch_stream_handle_t *stream) { switch_media_bug_t *bp; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index ed69799d26..955fdee14c 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1638,6 +1638,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t return SWITCH_STATUS_SUCCESS; } + typedef struct { SpeexPreprocessState *read_st; SpeexPreprocessState *write_st;