uint8_t codec_reinvites;
uint32_t max_missed_packets;
uint32_t max_missed_hold_packets;
+ uint32_t media_timeout;
+ uint32_t media_hold_timeout;
uint32_t ssrc;
uint32_t remote_ssrc;
switch_port_t remote_rtcp_port;
}
//?
+
+static void check_media_timeout_params(switch_core_session_t *session, switch_rtp_engine_t *engine)
+{
+ switch_media_type_t type = engine->type;
+ const char *val;
+
+ if ((val = switch_channel_get_variable(session->channel, "media_hold_timeout"))) {
+ engine->media_hold_timeout = atoi(val);
+ }
+
+ if ((val = switch_channel_get_variable(session->channel, "media_timeout"))) {
+ engine->media_timeout = atoi(val);
+ }
+
+ if (type == SWITCH_MEDIA_TYPE_VIDEO) {
+ if ((val = switch_channel_get_variable(session->channel, "media_hold_timeout_video"))) {
+ engine->media_hold_timeout = atoi(val);
+ }
+
+ if ((val = switch_channel_get_variable(session->channel, "media_timeout_video"))) {
+ engine->media_timeout = atoi(val);
+ }
+ } else {
+
+ if ((val = switch_channel_get_variable(session->channel, "media_hold_timeout_audio"))) {
+ engine->media_hold_timeout = atoi(val);
+ }
+
+ if ((val = switch_channel_get_variable(session->channel, "media_timeout_audio"))) {
+ engine->media_timeout = atoi(val);
+ }
+ }
+
+ if (switch_rtp_ready(engine->rtp_session) && engine->media_timeout) {
+ switch_rtp_set_media_timeout(engine->rtp_session, engine->media_timeout);
+ }
+
+}
+
SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session_t *session, switch_frame_t **frame,
switch_io_flag_t flags, int stream_id, switch_media_type_t type)
{
engine->reset_codec = 0;
if (switch_rtp_ready(engine->rtp_session)) {
+
+ check_media_timeout_params(session, engine);
+
if (type == SWITCH_MEDIA_TYPE_VIDEO) {
switch_core_media_set_video_codec(session, 1);
} else {
+
if (switch_core_media_set_codec(session, 1, smh->mparams->codec_flags) != SWITCH_STATUS_SUCCESS) {
*frame = NULL;
switch_goto_status(SWITCH_STATUS_GENERR, end);
if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) {
int v = atoi(val);
if (v >= 0) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
+ "rtp_timeout_sec deprecated use media_timeout variable.\n");
rtp_timeout_sec = v;
}
}
if ((val = switch_channel_get_variable(session->channel, "rtp_hold_timeout_sec"))) {
int v = atoi(val);
if (v >= 0) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
+ "rtp_hold_timeout_sec deprecated use media_timeout variable.\n");
rtp_hold_timeout_sec = v;
}
}
switch_channel_set_variable(session->channel, "media_audio_mode", "sendonly");
recvonly = 1;
+ a_engine->media_timeout = 0;
+ a_engine->media_hold_timeout = 0;
+
if (switch_rtp_ready(a_engine->rtp_session)) {
switch_rtp_set_max_missed_packets(a_engine->rtp_session, 0);
a_engine->max_missed_hold_packets = 0;
a_engine->max_missed_packets = 0;
+ switch_rtp_set_media_timeout(a_engine->rtp_session, a_engine->media_timeout);
} else {
+ switch_channel_set_variable(session->channel, "media_timeout_audio", "0");
+ switch_channel_set_variable(session->channel, "media_hold_timeout_audio", "0");
switch_channel_set_variable(session->channel, "rtp_timeout_sec", "0");
switch_channel_set_variable(session->channel, "rtp_hold_timeout_sec", "0");
}
switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_hold_packets);
}
+ if (a_engine->media_hold_timeout) {
+ switch_rtp_set_media_timeout(a_engine->rtp_session, a_engine->media_hold_timeout);
+ }
+
+ if (v_engine->media_hold_timeout) {
+ switch_rtp_set_media_timeout(v_engine->rtp_session, v_engine->media_hold_timeout);
+ }
+
+
if (!(stream = switch_channel_get_hold_music(session->channel))) {
stream = "local_stream://moh";
}
switch_ivr_bg_media(switch_core_session_get_uuid(session), SMF_REBRIDGE, SWITCH_FALSE, SWITCH_TRUE, 200);
}
- if (a_engine->max_missed_packets && a_engine->rtp_session) {
+ if (a_engine->rtp_session) {
switch_rtp_reset_media_timer(a_engine->rtp_session);
- switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_packets);
+
+ if (a_engine->max_missed_packets) {
+ switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_packets);
+ }
+
+ if (a_engine->media_hold_timeout) {
+ switch_rtp_set_media_timeout(a_engine->rtp_session, a_engine->media_timeout);
+ }
+ }
+
+ if (v_engine->rtp_session) {
+ switch_rtp_reset_media_timer(v_engine->rtp_session);
+
+ if (v_engine->media_hold_timeout) {
+ switch_rtp_set_media_timeout(v_engine->rtp_session, v_engine->media_timeout);
+ }
}
if (b_channel) {
if (switch_rtp_ready(a_engine->rtp_session)) {
switch_rtp_reset_media_timer(a_engine->rtp_session);
+ check_media_timeout_params(session, a_engine);
+ check_media_timeout_params(session, v_engine);
}
if (a_engine->crypto_type != CRYPTO_INVALID) {
switch_rtp_set_remote_ssrc(a_engine->rtp_session, a_engine->remote_ssrc);
}
+ check_media_timeout_params(session, a_engine);
+
switch_channel_set_flag(session->channel, CF_FS_RTP);
switch_channel_set_variable_printf(session->channel, "rtp_use_pt", "%d", a_engine->cur_payload_map->pt);
if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) {
int v = atoi(val);
if (v >= 0) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
+ "rtp_timeout_sec deprecated use media_timeout variable.\n");
smh->mparams->rtp_timeout_sec = v;
}
}
if ((val = switch_channel_get_variable(session->channel, "rtp_hold_timeout_sec"))) {
int v = atoi(val);
if (v >= 0) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
+ "rtp_hold_timeout_sec deprecated use media_hold_timeout variable.\n");
smh->mparams->rtp_hold_timeout_sec = v;
}
}
switch_rtp_set_remote_ssrc(v_engine->rtp_session, v_engine->remote_ssrc);
}
+ check_media_timeout_params(session, v_engine);
+
if (v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].ready) {
gen_ice(session, SWITCH_MEDIA_TYPE_VIDEO, NULL, 0);
{
if (a_engine && a_engine->rtp_session) {
switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_hold_packets);
+ switch_rtp_set_media_timeout(a_engine->rtp_session, a_engine->media_hold_timeout);
+ }
+
+ if (v_engine && v_engine->rtp_session) {
+ switch_rtp_set_media_timeout(v_engine->rtp_session, v_engine->media_hold_timeout);
}
}
break;
{
if (a_engine && a_engine->rtp_session) {
switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_packets);
+ switch_rtp_set_media_timeout(a_engine->rtp_session, a_engine->media_timeout);
+ }
+
+ if (v_engine && v_engine->rtp_session) {
+ switch_rtp_set_media_timeout(v_engine->rtp_session, v_engine->media_timeout);
}
}
break;
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
-
switch_jb_t *vbw;
uint32_t max_missed_packets;
uint32_t missed_count;
+ switch_time_t last_media;
+ uint32_t media_timeout;
rtp_msg_t write_msg;
switch_rtp_crypto_key_t *crypto_keys[SWITCH_RTP_CRYPTO_MAX];
int reading;
return status;
}
+SWITCH_DECLARE(void) switch_rtp_set_media_timeout(switch_rtp_t *rtp_session, uint32_t ms)
+{
+ if (!switch_rtp_ready(rtp_session) || rtp_session->flags[SWITCH_RTP_FLAG_UDPTL]) {
+ return;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1,
+ "%s MEDIA TIMEOUT %s set to %u", switch_core_session_get_name(rtp_session->session), rtp_type(rtp_session), ms);
+ rtp_session->media_timeout = ms;
+ switch_rtp_reset_media_timer(rtp_session);
+}
+
SWITCH_DECLARE(void) switch_rtp_set_max_missed_packets(switch_rtp_t *rtp_session, uint32_t max)
{
if (!switch_rtp_ready(rtp_session) || rtp_session->flags[SWITCH_RTP_FLAG_UDPTL]) {
SWITCH_DECLARE(void) switch_rtp_reset_media_timer(switch_rtp_t *rtp_session)
{
rtp_session->missed_count = 0;
+ rtp_session->last_media = switch_micro_time_now();
}
SWITCH_DECLARE(char *) switch_rtp_get_remote_host(switch_rtp_t *rtp_session)
if (bytes) {
int do_cng = 0;
+ if (rtp_session->media_timeout) {
+ rtp_session->last_media = switch_micro_time_now();
+ }
+
/* Make sure to handle RFC2833 packets, even if we're flushing the packets */
if (bytes > rtp_header_len && rtp_session->recv_msg.header.version == 2 && rtp_session->recv_msg.header.pt == rtp_session->recv_te) {
rtp_session->last_rtp_hdr = rtp_session->recv_msg.header;
/* version 2 probably rtp, zrtp cookie present means zrtp */
rtp_session->has_rtp = (rtp_session->recv_msg.header.version == 2 || ntohl(*(int *)(b+4)) == ZRTP_MAGIC_COOKIE);
+ if (rtp_session->media_timeout) {
+ rtp_session->last_media = switch_micro_time_now();
+ }
+
if ((*b >= 20) && (*b <= 64)) {
if (rtp_session->dtls) {
rtp_session->dtls->bytes = *bytes;
return status;
}
+static void check_timeout(switch_rtp_t *rtp_session)
+{
+
+ switch_time_t now = switch_micro_time_now();
+ uint32_t elapsed = 0;
+
+ if (now >= rtp_session->last_media) {
+ elapsed = (now - rtp_session->last_media) / 1000;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10,
+ "%s MEDIA TIMEOUT %s %d/%d", switch_core_session_get_name(rtp_session->session), rtp_type(rtp_session),
+ elapsed, rtp_session->media_timeout);
+
+ if (elapsed > rtp_session->media_timeout) {
+
+ if (rtp_session->session) {
+ switch_channel_t *channel = switch_core_session_get_channel(rtp_session->session);
+
+ switch_channel_execute_on(channel, "execute_on_media_timeout");
+ switch_channel_hangup(channel, SWITCH_CAUSE_MEDIA_TIMEOUT);
+ }
+ }
+}
+
static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_type,
payload_map_t **pmapP, switch_frame_flag_t *flags, switch_io_flag_t io_flags)
{
poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt);
+ if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && poll_status != SWITCH_STATUS_SUCCESS && rtp_session->media_timeout && rtp_session->last_media) {
+ check_timeout(rtp_session);
+ }
+
if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->dtmf_data.out_digit_dur > 0) {
return_cng_frame();
}
!rtp_session->flags[SWITCH_RTP_FLAG_UDPTL]) {
if (bytes && status == SWITCH_STATUS_SUCCESS) {
rtp_session->missed_count = 0;
- } else if (++rtp_session->missed_count >= rtp_session->max_missed_packets) {
- ret = -2;
- goto end;
+ } else {
+ if (rtp_session->media_timeout && rtp_session->last_media) {
+ check_timeout(rtp_session);
+ } else {
+ if (++rtp_session->missed_count >= rtp_session->max_missed_packets) {
+ ret = -2;
+ goto end;
+ }
+ }
}
}
rtp_session->missed_count += (poll_sec * 1000) / (rtp_session->ms_per_packet ? rtp_session->ms_per_packet / 1000 : 20);
bytes = 0;
- if (rtp_session->max_missed_packets) {
+ if (rtp_session->media_timeout && rtp_session->last_media) {
+ check_timeout(rtp_session);
+ } else if (rtp_session->max_missed_packets) {
if (rtp_session->missed_count >= rtp_session->max_missed_packets) {
ret = -2;
goto end;
result_continue:
timer_check:
- if (rtp_session->flags[SWITCH_RTP_FLAG_MUTE]) {
+ if (!rtp_session->media_timeout && rtp_session->flags[SWITCH_RTP_FLAG_MUTE]) {
do_cng++;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "%s %s timeout\n",
rtp_session_name(rtp_session), rtp_type(rtp_session));
+ if (rtp_session->media_timeout && rtp_session->last_media) {
+ check_timeout(rtp_session);
+ }
+
if (rtp_session->stats.inbound.error_log) {
rtp_session->stats.inbound.error_log->flaws++;
}
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
-