FS-11654: [core] add media_timeout, media_hold_timeout and video vs audio variants

This commit is contained in:
Brian West 2019-02-13 17:48:54 -06:00 committed by Andrey Volk
parent 382ecb6612
commit b23d887586
5 changed files with 184 additions and 9 deletions

View File

@ -278,6 +278,7 @@ SWITCH_DECLARE(char *) switch_rtp_get_remote_host(switch_rtp_t *rtp_session);
SWITCH_DECLARE(switch_port_t) switch_rtp_get_remote_port(switch_rtp_t *rtp_session);
SWITCH_DECLARE(void) switch_rtp_reset_media_timer(switch_rtp_t *rtp_session);
SWITCH_DECLARE(void) switch_rtp_set_max_missed_packets(switch_rtp_t *rtp_session, uint32_t max);
SWITCH_DECLARE(void) switch_rtp_set_media_timeout(switch_rtp_t *rtp_session, uint32_t ms);
SWITCH_DECLARE(switch_status_t) switch_rtp_udptl_mode(switch_rtp_t *rtp_session);
SWITCH_DECLARE(void) switch_rtp_reset(switch_rtp_t *rtp_session);

View File

@ -368,15 +368,24 @@ void conference_utils_member_set_flag_locked(conference_member_t *member, member
switch_mutex_unlock(member->flag_mutex);
}
static void check_cleared_flag(conference_member_t *member, member_flag_t flag)
{
if (flag == MFLAG_RUNNING && member->session) {
switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK);
}
}
void conference_utils_member_clear_flag(conference_member_t *member, member_flag_t flag)
{
member->flags[flag] = 0;
check_cleared_flag(member, flag);
}
void conference_utils_member_clear_flag_locked(conference_member_t *member, member_flag_t flag)
{
switch_mutex_lock(member->flag_mutex);
member->flags[flag] = 0;
switch_mutex_unlock(member->flag_mutex);
check_cleared_flag(member, flag);
}
switch_bool_t conference_utils_member_test_flag(conference_member_t *member, member_flag_t flag)
{

View File

@ -5195,11 +5195,15 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
int v = atoi(val);
if (v >= 0) {
profile->rtp_timeout_sec = v;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"rtp-timeout-sec deprecated use media_timeout variable.\n");
}
} else if (!strcasecmp(var, "rtp-hold-timeout-sec") && !zstr(val)) {
int v = atoi(val);
if (v >= 0) {
profile->rtp_hold_timeout_sec = v;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"rtp-hold-timeout-sec deprecated use media_hold_timeout variable.\n");
}
} else if (!strcasecmp(var, "disable-transfer")) {
if (switch_true(val)) {

View File

@ -131,6 +131,8 @@ typedef struct switch_rtp_engine_s {
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;
@ -2815,6 +2817,45 @@ static void *get_rtt_payload(void *data, switch_size_t datalen, switch_payload_t
}
//?
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)
{
@ -2924,9 +2965,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
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);
@ -2937,6 +2982,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
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;
}
}
@ -2944,6 +2991,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
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;
}
}
@ -5300,11 +5349,17 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
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");
}
@ -6483,6 +6538,15 @@ SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session
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";
}
@ -6543,9 +6607,24 @@ SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session
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) {
@ -8469,6 +8548,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
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) {
@ -8702,6 +8783,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
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);
@ -8855,6 +8938,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
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;
}
}
@ -8862,6 +8947,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
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;
}
}
@ -9450,6 +9537,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
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);
@ -12432,6 +12521,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
{
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;
@ -12440,6 +12534,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
{
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;
@ -16135,4 +16234,3 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -435,6 +435,8 @@ struct switch_rtp {
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;
@ -2869,6 +2871,18 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s
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]) {
@ -2937,6 +2951,7 @@ SWITCH_DECLARE(void) switch_rtp_reset(switch_rtp_t *rtp_session)
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)
@ -5632,6 +5647,10 @@ static switch_size_t do_flush(switch_rtp_t *rtp_session, int force, switch_size_
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;
@ -5803,6 +5822,10 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
/* 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;
@ -7087,6 +7110,31 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t
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)
{
@ -7293,6 +7341,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
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();
}
@ -7332,9 +7384,15 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
!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;
}
}
}
}
@ -7385,7 +7443,9 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
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;
@ -7743,7 +7803,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
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++;
}
@ -7784,6 +7844,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
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++;
}
@ -9165,4 +9229,3 @@ SWITCH_DECLARE(void *) switch_rtp_get_private(switch_rtp_t *rtp_session)
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/