diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 1fd94ce688..3459f7db2c 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -351,7 +351,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read(switch_rtp_t *rtp_sessi */ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_frame_t *frame, switch_io_flag_t io_flags); -SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session); +SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session, switch_rtp_flush_t flush); /*! \brief Enable VAD on an RTP Session diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 4a9a11219e..fea61d5ec6 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -110,6 +110,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_PATH_SEPARATOR "/" #endif #define SWITCH_URL_SEPARATOR "://" +#define SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE "bridge_hangup_cause" #define SWITCH_READ_TERMINATOR_USED_VARIABLE "read_terminator_used" #define SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE "send_silence_when_idle" #define SWITCH_CURRENT_APPLICATION_VARIABLE "current_application" @@ -443,6 +444,11 @@ typedef struct { switch_rtp_numbers_t outbound; } switch_rtp_stats_t; +typedef enum { + SWITCH_RTP_FLUSH_ONCE, + SWITCH_RTP_FLUSH_STICK, + SWITCH_RTP_FLUSH_UNSTICK +} switch_rtp_flush_t; #define SWITCH_RTP_CNG_PAYLOAD 13 @@ -464,7 +470,7 @@ typedef struct { SWITCH_RTP_FLAG_DATAWAIT - Do not return from reads unless there is data even when non blocking SWITCH_RTP_FLAG_BUGGY_2833 - Emulate the bug in cisco equipment to allow interop SWITCH_RTP_FLAG_PASS_RFC2833 - Pass 2833 (ignore it) - SWITCH_RTP_FLAG_AUTO_CNG - Generate outbound CNG frames when idle + SWITCH_RTP_FLAG_AUTO_CNG - Generate outbound CNG frames when idle */ typedef enum { @@ -489,7 +495,8 @@ typedef enum { SWITCH_RTP_FLAG_PROXY_MEDIA = (1 << 18), SWITCH_RTP_FLAG_SHUTDOWN = (1 << 19), SWITCH_RTP_FLAG_FLUSH = (1 << 20), - SWITCH_RTP_FLAG_AUTOFLUSH = (1 << 21) + SWITCH_RTP_FLAG_AUTOFLUSH = (1 << 21), + SWITCH_RTP_FLAG_STICKY_FLUSH = (1 << 22) } switch_rtp_flag_enum_t; typedef uint32_t switch_rtp_flag_t; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index fc3c817129..c9138b03d5 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1015,10 +1015,18 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi goto end; case SWITCH_MESSAGE_INDICATE_BRIDGE: + if (switch_rtp_ready(tech_pvt->rtp_session)) { + rtp_flush_read_buffer(tech_pvt->rtp_session, SWITCH_RTP_FLUSH_STICK); + } + goto end; case SWITCH_MESSAGE_INDICATE_UNBRIDGE: + if (switch_rtp_ready(tech_pvt->rtp_session)) { + rtp_flush_read_buffer(tech_pvt->rtp_session, SWITCH_RTP_FLUSH_UNSTICK); + } + goto end; case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC: if (switch_rtp_ready(tech_pvt->rtp_session)) { - rtp_flush_read_buffer(tech_pvt->rtp_session); + rtp_flush_read_buffer(tech_pvt->rtp_session, SWITCH_RTP_FLUSH_ONCE); } goto end; diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index d2a84b1783..2b10b26a80 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -829,6 +829,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses int br = 0; int inner_bridge = switch_channel_test_flag(caller_channel, CF_INNER_BRIDGE); const char *var; + switch_call_cause_t cause; switch_channel_set_flag(caller_channel, CF_ORIGINATOR); @@ -961,6 +962,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_cond_next(); } + if ((cause = switch_channel_get_cause(caller_channel))) { + switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE, switch_channel_cause2str(cause)); + } + + if ((cause = switch_channel_get_cause(peer_channel))) { + switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE, switch_channel_cause2str(cause)); + } + switch_core_session_rwunlock(peer_session); } else { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 01d77a2cdc..070062ef10 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1330,10 +1330,20 @@ static void do_2833(switch_rtp_t *rtp_session) } } -SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session) +SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session, switch_rtp_flush_t flush) { if (switch_rtp_ready(rtp_session) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) { switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_FLUSH); + switch (flush) { + case SWITCH_RTP_FLUSH_STICK: + switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH); + break; + case SWITCH_RTP_FLUSH_UNSTICK: + switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH); + break; + default: + break; + } } } @@ -1459,7 +1469,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ int do_cng = 0; if (rtp_session->timer.interval) { - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTOFLUSH)) { + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTOFLUSH) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH)) { if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 1) == SWITCH_STATUS_SUCCESS) { hot_socket = 1; } @@ -1526,7 +1536,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } if (bytes && rtp_session->recv_msg.header.m && rtp_session->recv_msg.header.pt != rtp_session->te) { - rtp_flush_read_buffer(rtp_session); + rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE); } if (bytes && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ) && switch_sockaddr_get_port(rtp_session->from_addr)) {