diff --git a/src/include/switch_core.h b/src/include/switch_core.h index ae57dc1c9f..1d83cb3649 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -162,6 +162,7 @@ typedef enum { } dtls_type_t; typedef enum { + DS_OFF, DS_HANDSHAKE, DS_SETUP, DS_READY, diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 9e7f9198d8..12146517b4 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -514,6 +514,7 @@ SWITCH_DECLARE(void) switch_rtp_set_interdigit_delay(switch_rtp_t *rtp_session, SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, dtls_fingerprint_t *local_fp, dtls_fingerprint_t *remote_fp, dtls_type_t type); SWITCH_DECLARE(switch_status_t) switch_rtp_del_dtls(switch_rtp_t *rtp_session, dtls_type_t type); +SWITCH_DECLARE(dtls_state_t) switch_rtp_dtls_state(switch_rtp_t *rtp_session, dtls_type_t type); SWITCH_DECLARE(int) switch_rtp_has_dtls(void); SWITCH_DECLARE(void) switch_rtp_video_refresh(switch_rtp_t *rtp_session); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 308017bb65..5f224f76ab 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -6046,6 +6046,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi end: + switch_channel_clear_flag(session->channel, CF_REINVITE); switch_core_recovery_track(session); @@ -8009,6 +8010,48 @@ SWITCH_DECLARE(void) switch_core_media_hard_mute(switch_core_session_t *session, switch_core_session_receive_message(session, &msg); } +static int check_engine(switch_rtp_engine_t *engine) +{ + dtls_state_t dtls_state = switch_rtp_dtls_state(engine->rtp_session, DTLS_TYPE_RTP); + int flags = 0; + switch_status_t status; + + if (dtls_state == DS_OFF || dtls_state == DS_READY || dtls_state >= DS_FAIL) return 0; + + status = switch_rtp_zerocopy_read_frame(engine->rtp_session, &engine->read_frame, flags); + + if (!SWITCH_READ_ACCEPTABLE(status)) { + return 0; + } + + return 1; +} + +static void check_dtls(switch_core_session_t *session) +{ + switch_media_handle_t *smh; + switch_rtp_engine_t *a_engine, *v_engine; + int audio_checking = 0, video_checking = 0; + + switch_assert(session); + + if (!(smh = session->media_handle)) { + return; + } + + if (switch_channel_down(session->channel)) { + return; + } + + a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; + + do { + if (a_engine->rtp_session) audio_checking = check_engine(a_engine); + if (v_engine->rtp_session) check_engine(v_engine); + } while (switch_channel_ready(session->channel) && (audio_checking || video_checking)); +} + //? SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) @@ -8040,6 +8083,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se } break; + case SWITCH_MESSAGE_INDICATE_ANSWER: + case SWITCH_MESSAGE_INDICATE_PROGRESS: + { + check_dtls(session); + } + break; case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ: { if (v_engine->rtp_session) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index a2e6c88aa2..27cf06dac6 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -270,7 +270,7 @@ static int dtls_state_ready(switch_rtp_t *rtp_session, switch_dtls_t *dtls); static int dtls_state_setup(switch_rtp_t *rtp_session, switch_dtls_t *dtls); static int dtls_state_fail(switch_rtp_t *rtp_session, switch_dtls_t *dtls); -dtls_state_handler_t dtls_states[DS_INVALID] = {dtls_state_handshake, dtls_state_setup, dtls_state_ready, dtls_state_fail}; +dtls_state_handler_t dtls_states[DS_INVALID] = {NULL, dtls_state_handshake, dtls_state_setup, dtls_state_ready, dtls_state_fail}; typedef struct ts_normalize_s { uint32_t last_ssrc; @@ -2850,7 +2850,9 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS packet read err %d\n", rtp_type(rtp_session), ret); } - r = dtls_states[dtls->state](rtp_session, dtls); + if (dtls_states[dtls->state]) { + r = dtls_states[dtls->state](rtp_session, dtls); + } if ((len = BIO_read(dtls->write_bio, buf, sizeof(buf))) > 0) { bytes = len; @@ -2902,10 +2904,27 @@ SWITCH_DECLARE(int) switch_rtp_has_dtls(void) { #endif } +SWITCH_DECLARE(dtls_state_t) switch_rtp_dtls_state(switch_rtp_t *rtp_session, dtls_type_t type) +{ + if (!rtp_session || (!rtp_session->dtls && !rtp_session->rtcp_dtls)) { + return DS_OFF; + } + + if ((type == DTLS_TYPE_RTP) && rtp_session->dtls) { + return rtp_session->dtls->state; + } + + if ((type == DTLS_TYPE_RTCP) && rtp_session->rtcp_dtls) { + return rtp_session->rtcp_dtls->state; + } + + return DS_OFF; +} + SWITCH_DECLARE(switch_status_t) switch_rtp_del_dtls(switch_rtp_t *rtp_session, dtls_type_t type) { - if (!rtp_session->dtls && !rtp_session->rtcp_dtls) { + if (!rtp_session || (!rtp_session->dtls && !rtp_session->rtcp_dtls)) { return SWITCH_STATUS_FALSE; } @@ -3106,6 +3125,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d SSL_set_connect_state(dtls->ssl); } + dtls_set_state(dtls, DS_HANDSHAKE); + rtp_session->flags[SWITCH_RTP_FLAG_VIDEO_BREAK] = 1; switch_rtp_break(rtp_session); @@ -4494,7 +4515,6 @@ SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session, switch_rtp { if (rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] || - rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] || rtp_session->flags[SWITCH_RTP_FLAG_UDPTL]) { return; }