]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-7500: poll rtp on answer until dtls is negotiated
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 10 Dec 2014 20:44:59 +0000 (14:44 -0600)
committerMichael Jerris <mike@jerris.com>
Thu, 28 May 2015 17:46:51 +0000 (12:46 -0500)
src/include/switch_core.h
src/include/switch_rtp.h
src/switch_core_media.c
src/switch_rtp.c

index ae57dc1c9fa6c238079f3fefb6a9ca54497c550a..1d83cb364938e783213f8cd9e6dd99a007af1028 100644 (file)
@@ -162,6 +162,7 @@ typedef enum {
 } dtls_type_t;
 
 typedef enum {
+       DS_OFF,
        DS_HANDSHAKE,
        DS_SETUP,
        DS_READY,
index 9e7f9198d8f22bf7c7522ee23dd798cb0fe5986a..12146517b488326a23c99a1501ba5de3694ed1a0 100644 (file)
@@ -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);
index 308017bb659348a253797bbea28fff4415d333d5..5f224f76ab0cec08734bb152a020ba12e1be3cca 100644 (file)
@@ -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) {
index a2e6c88aa2e253d6265a8ba5021e049537355d19..27cf06dac6665f4df3114f7c52f5777402d3860a 100644 (file)
@@ -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;
        }