]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
ZRTP Video works with ZFone (but you have to set your endpoint to use 99 for the...
authorBrian West <brian@freeswitch.org>
Wed, 3 Feb 2010 19:19:10 +0000 (19:19 +0000)
committerBrian West <brian@freeswitch.org>
Wed, 3 Feb 2010 19:19:10 +0000 (19:19 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16563 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_channel.h
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/languages/mod_managed/freeswitch_wrap.cxx
src/mod/languages/mod_managed/managed/swig.cs
src/switch_channel.c
src/switch_rtp.c

index 8c59ffac44e6babac5007a8e2ec68e430e1d3b98..7e86f71599d6ee2621620160627220e78b94ccd2 100644 (file)
@@ -434,6 +434,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_private(switch_channel_t *cha
   \return void pointer to channel's private data
 */
 SWITCH_DECLARE(void *) switch_channel_get_private(switch_channel_t *channel, const char *key);
+SWITCH_DECLARE(void *) switch_channel_get_private_partner(switch_channel_t *channel, const char *key);
 
 /*!
   \brief Assign a name to a given channel
index 1a7cb8ae2440dc9df26b7a3f6787b04f186539bf..1db3056f2cf6767ad66bf09a09ea8d873e5360cd 100644 (file)
@@ -2032,16 +2032,6 @@ void sofia_glue_deactivate_rtp(private_object_t *tech_pvt)
                }
        }
 
-       if (tech_pvt->rtp_session) {
-               switch_rtp_destroy(&tech_pvt->rtp_session);
-       } else if (tech_pvt->local_sdp_audio_port) {
-               switch_rtp_release_port(tech_pvt->profile->rtpip, tech_pvt->local_sdp_audio_port);
-       }
-
-       if (tech_pvt->local_sdp_audio_port > 0 && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { 
-               switch_nat_del_mapping((switch_port_t)tech_pvt->local_sdp_audio_port, SWITCH_NAT_UDP);
-       }
-       
        if (tech_pvt->video_rtp_session) {
                switch_rtp_destroy(&tech_pvt->video_rtp_session);
        } else if (tech_pvt->local_sdp_video_port) {
@@ -2052,6 +2042,18 @@ void sofia_glue_deactivate_rtp(private_object_t *tech_pvt)
        if (tech_pvt->local_sdp_video_port > 0 && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { 
                switch_nat_del_mapping((switch_port_t)tech_pvt->local_sdp_video_port, SWITCH_NAT_UDP);
        }
+
+
+       if (tech_pvt->rtp_session) {
+               switch_rtp_destroy(&tech_pvt->rtp_session);
+       } else if (tech_pvt->local_sdp_audio_port) {
+               switch_rtp_release_port(tech_pvt->profile->rtpip, tech_pvt->local_sdp_audio_port);
+       }
+
+       if (tech_pvt->local_sdp_audio_port > 0 && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { 
+               switch_nat_del_mapping((switch_port_t)tech_pvt->local_sdp_audio_port, SWITCH_NAT_UDP);
+       }
+       
 }
 
 switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int force)
@@ -2749,7 +2751,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                        sofia_glue_tech_set_video_codec(tech_pvt, 0);
 
                        flags &= ~(SWITCH_RTP_FLAG_USE_TIMER | SWITCH_RTP_FLAG_NOBLOCK);
-                       flags |= SWITCH_RTP_FLAG_VIDEO | SWITCH_RTP_FLAG_PROXY_MEDIA;
+                       flags |= SWITCH_RTP_FLAG_VIDEO;
 
                        tech_pvt->video_rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip,
                                                                                                                 tech_pvt->local_sdp_video_port,
index 09ee75944aba8099c7dd357e7dc518655f4d131f..7ae0a6a6a9db1f3fe53ce2c6c711d380f526df0c 100644 (file)
@@ -21111,6 +21111,23 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_set_variable_printf(void * jarg
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_set_variable_name_printf(void * jarg1, char * jarg2, char * jarg3) {
+  int jresult ;
+  switch_channel_t *arg1 = (switch_channel_t *) 0 ;
+  char *arg2 = (char *) 0 ;
+  char *arg3 = (char *) 0 ;
+  void *arg4 = 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_channel_t *)jarg1; 
+  arg2 = (char *)jarg2; 
+  arg3 = (char *)jarg3; 
+  result = (switch_status_t)switch_channel_set_variable_name_printf(arg1,(char const *)arg2,(char const *)arg3,arg4);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_set_variable_partner_var_check(void * jarg1, char * jarg2, char * jarg3, int jarg4) {
   int jresult ;
   switch_channel_t *arg1 = (switch_channel_t *) 0 ;
@@ -21567,6 +21584,20 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_get_private(void * jarg1, ch
 }
 
 
+SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_get_private_partner(void * jarg1, char * jarg2) {
+  void * jresult ;
+  switch_channel_t *arg1 = (switch_channel_t *) 0 ;
+  char *arg2 = (char *) 0 ;
+  void *result = 0 ;
+  
+  arg1 = (switch_channel_t *)jarg1; 
+  arg2 = (char *)jarg2; 
+  result = (void *)switch_channel_get_private_partner(arg1,(char const *)arg2);
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_set_name(void * jarg1, char * jarg2) {
   int jresult ;
   switch_channel_t *arg1 = (switch_channel_t *) 0 ;
@@ -22746,15 +22777,17 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_add_header_string(void * jarg1, i
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_del_header(void * jarg1, char * jarg2) {
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_del_header_val(void * jarg1, char * jarg2, char * jarg3) {
   int jresult ;
   switch_event_t *arg1 = (switch_event_t *) 0 ;
   char *arg2 = (char *) 0 ;
+  char *arg3 = (char *) 0 ;
   switch_status_t result;
   
   arg1 = (switch_event_t *)jarg1; 
   arg2 = (char *)jarg2; 
-  result = (switch_status_t)switch_event_del_header(arg1,(char const *)arg2);
+  arg3 = (char *)jarg3; 
+  result = (switch_status_t)switch_event_del_header_val(arg1,(char const *)arg2,(char const *)arg3);
   jresult = result; 
   return jresult;
 }
index 73adfb6c2af86af7e81de626ef9fe7cad2f57ab0..10254c4783f4f29674c75ff7f5905b9c914202b3 100644 (file)
@@ -2851,6 +2851,11 @@ public class freeswitch {
     return ret;
   }
 
+  public static switch_status_t switch_channel_set_variable_name_printf(SWIGTYPE_p_switch_channel channel, string val, string fmt) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_set_variable_name_printf(SWIGTYPE_p_switch_channel.getCPtr(channel), val, fmt);
+    return ret;
+  }
+
   public static switch_status_t switch_channel_set_variable_partner_var_check(SWIGTYPE_p_switch_channel channel, string varname, string value, switch_bool_t var_check) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_set_variable_partner_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, value, (int)var_check);
     return ret;
@@ -3014,6 +3019,12 @@ public class freeswitch {
     return ret;
   }
 
+  public static SWIGTYPE_p_void switch_channel_get_private_partner(SWIGTYPE_p_switch_channel channel, string key) {
+    IntPtr cPtr = freeswitchPINVOKE.switch_channel_get_private_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), key);
+    SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false);
+    return ret;
+  }
+
   public static switch_status_t switch_channel_set_name(SWIGTYPE_p_switch_channel channel, string name) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_set_name(SWIGTYPE_p_switch_channel.getCPtr(channel), name);
     return ret;
@@ -3273,8 +3284,8 @@ public class freeswitch {
     return ret;
   }
 
-  public static switch_status_t switch_event_del_header(switch_event arg0, string header_name) {
-    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_del_header(switch_event.getCPtr(arg0), header_name);
+  public static switch_status_t switch_event_del_header_val(switch_event arg0, string header_name, string val) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_del_header_val(switch_event.getCPtr(arg0), header_name, val);
     return ret;
   }
 
@@ -10035,6 +10046,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_variable_printf")]
   public static extern int switch_channel_set_variable_printf(HandleRef jarg1, string jarg2, string jarg3);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_variable_name_printf")]
+  public static extern int switch_channel_set_variable_name_printf(HandleRef jarg1, string jarg2, string jarg3);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_variable_partner_var_check")]
   public static extern int switch_channel_set_variable_partner_var_check(HandleRef jarg1, string jarg2, string jarg3, int jarg4);
 
@@ -10137,6 +10151,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_private")]
   public static extern IntPtr switch_channel_get_private(HandleRef jarg1, string jarg2);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_private_partner")]
+  public static extern IntPtr switch_channel_get_private_partner(HandleRef jarg1, string jarg2);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_name")]
   public static extern int switch_channel_set_name(HandleRef jarg1, string jarg2);
 
@@ -10404,8 +10421,8 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_event_add_header_string")]
   public static extern int switch_event_add_header_string(HandleRef jarg1, int jarg2, string jarg3, string jarg4);
 
-  [DllImport("mod_managed", EntryPoint="CSharp_switch_event_del_header")]
-  public static extern int switch_event_del_header(HandleRef jarg1, string jarg2);
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_event_del_header_val")]
+  public static extern int switch_event_del_header_val(HandleRef jarg1, string jarg2, string jarg3);
 
   [DllImport("mod_managed", EntryPoint="CSharp_switch_event_destroy")]
   public static extern void switch_event_destroy(HandleRef jarg1);
index 7cbe7f683761b2dc4a19ff100c28226f637d86d8..d4ed3ec1407f1397ad25773eeaf061ba77da78e9 100644 (file)
@@ -623,6 +623,24 @@ SWITCH_DECLARE(void *) switch_channel_get_private(switch_channel_t *channel, con
        return val;
 }
 
+SWITCH_DECLARE(void *) switch_channel_get_private_partner(switch_channel_t *channel, const char *key)
+{
+       const char *uuid;
+       void *val = NULL;
+
+       switch_assert(channel != NULL);
+
+       if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
+               switch_core_session_t *session;
+               if ((session = switch_core_session_locate(uuid))) {
+                       val = switch_core_hash_find_locked(channel->private_hash, key, channel->profile_mutex);
+                       switch_core_session_rwunlock(session);
+               }
+       }
+
+       return val;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_channel_set_name(switch_channel_t *channel, const char *name)
 {
        const char *old = NULL;
index 7ecc2f74d87028ed869a2654999ee4a58987808c..f964dfa9f422de104576c86c4415dbb9887daa7d 100644 (file)
@@ -219,9 +219,9 @@ struct switch_rtp {
 #ifdef ENABLE_ZRTP
        zrtp_session_t *zrtp_session;
        zrtp_profile_t *zrtp_profile;
-       zrtp_stream_t *zrtp_audio_ctx;
-       zrtp_stream_t *zrtp_video_ctx;
+       zrtp_stream_t *zrtp_stream;
        int zrtp_mitm_tries;
+       int zinit;
 #endif
 
 #ifdef RTP_DEBUG_WRITE_DELTA
@@ -439,44 +439,74 @@ static int zrtp_send_rtp_callback(const zrtp_stream_t* stream, char* rtp_packet,
 static void zrtp_event_callback(zrtp_stream_t *stream, unsigned event)
 {
        switch_rtp_t *rtp_session = zrtp_stream_get_userdata(stream);
+       zrtp_session_info_t zrtp_session_info;
        switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session");
        switch_channel_t *channel = switch_core_session_get_channel(session);
        switch_event_t *fsevent = NULL;
+       const char *type;
+       
+       type = switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) ? "video" : "audio";
        
-       zrtp_session_info_t zrtp_session_info;
-
        switch (event) {
        case ZRTP_EVENT_IS_SECURE:
                {
                        switch_set_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_SEND);
                        switch_set_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_RECV);
-                       switch_set_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND);
-                       switch_set_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV);
-                       if (zrtp_status_ok == zrtp_session_get(rtp_session->zrtp_session, &zrtp_session_info)) {
+                       if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
+                               switch_set_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND);
+                               switch_set_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV);
+                       }
+                       if (zrtp_status_ok == zrtp_session_get(stream->session, &zrtp_session_info)) {
                                if (zrtp_session_info.sas_is_ready) {
                                        
-                                       switch_channel_set_variable(channel, "zrtp_secure_media_confirmed", "true");
-                                       switch_channel_set_variable(channel, "zrtp_sas1_string", rtp_session->zrtp_session->sas1.buffer);
-                                       switch_channel_set_variable(channel, "zrtp_sas2_string", rtp_session->zrtp_session->sas2.buffer);
+                                       switch_channel_set_variable_name_printf(channel, "true", "zrtp_secure_media_confirmed_%s", type);
+                                       switch_channel_set_variable_name_printf(channel, stream->session->sas1.buffer, "zrtp_sas1_string_%s", type);
+                                       switch_channel_set_variable_name_printf(channel, stream->session->sas2.buffer, "zrtp_sas2_string", type);
                                        
-                                       zrtp_verified_set(zrtp_global, &rtp_session->zrtp_session->zid, 
-                                                                         &rtp_session->zrtp_session->peer_zid, zrtp_session_info.sas_is_verified^1);
+                                       zrtp_verified_set(zrtp_global, &stream->session->zid, 
+                                                                         &stream->session->peer_zid, zrtp_session_info.sas_is_verified^1);
                                        
                                }
                        }
-               }
-               if (switch_event_create(&fsevent, SWITCH_EVENT_CALL_SECURE) == SWITCH_STATUS_SUCCESS) {
-                       switch_event_add_header(fsevent, SWITCH_STACK_BOTTOM, "secure_type", "zrtp:%s:%s",
-                                                                       rtp_session->zrtp_session->sas1.buffer, rtp_session->zrtp_session->sas2.buffer);
-                       switch_event_add_header_string(fsevent, SWITCH_STACK_BOTTOM, "caller-unique-id", switch_channel_get_uuid(channel));
-                       switch_event_fire(&fsevent);
+
+                       if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
+                               switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session");
+                               
+                               if (session) {
+                                       switch_channel_t *channel = switch_core_session_get_channel(session);
+                                       switch_rtp_t *video_rtp_session = switch_channel_get_private(channel, "__zrtp_video_rtp_session");
+                                       
+                                       if (!video_rtp_session) {
+                                               video_rtp_session = switch_channel_get_private_partner(channel, "__zrtp_video_rtp_session");
+                                       }
+
+                                       if (video_rtp_session) {
+                                               if (zrtp_status_ok != zrtp_stream_attach(stream->session, &video_rtp_session->zrtp_stream)) {
+                                                       abort();
+                                               }
+                                               zrtp_stream_set_userdata(video_rtp_session->zrtp_stream, video_rtp_session);
+                                               if (switch_true(switch_channel_get_variable(channel, "zrtp_enrollment"))) {
+                                                       zrtp_stream_registration_start(video_rtp_session->zrtp_stream, video_rtp_session->ssrc);
+                                               } else {
+                                                       zrtp_stream_start(video_rtp_session->zrtp_stream, video_rtp_session->ssrc);
+                                               }
+                                       }
+                               }                               
+                       }
+
+                       if (switch_event_create(&fsevent, SWITCH_EVENT_CALL_SECURE) == SWITCH_STATUS_SUCCESS) {
+                               switch_event_add_header(fsevent, SWITCH_STACK_BOTTOM, "secure_media_type", "%s", type);
+                               switch_event_add_header(fsevent, SWITCH_STACK_BOTTOM, "secure_type", "zrtp:%s:%s", stream->session->sas1.buffer, stream->session->sas2.buffer);
+                               switch_event_add_header_string(fsevent, SWITCH_STACK_BOTTOM, "caller-unique-id", switch_channel_get_uuid(channel));
+                               switch_event_fire(&fsevent);
+                       }
                }
                break;
 #if 0
        case ZRTP_EVENT_NO_ZRTP_QUICK:
                {
-                       if (rtp_session->zrtp_audio_ctx != NULL) {
-                               zrtp_stream_stop(rtp_session->zrtp_audio_ctx);
+                       if (stream != NULL) {
+                               zrtp_stream_stop(stream);
                        }
                }
                break;
@@ -484,19 +514,19 @@ static void zrtp_event_callback(zrtp_stream_t *stream, unsigned event)
        case ZRTP_EVENT_IS_CLIENT_ENROLLMENT:
                {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Enrolled complete!\n");
-                       switch_channel_set_variable(channel, "zrtp_enroll_complete", "true");
+                       switch_channel_set_variable_name_printf(channel, "true", "zrtp_enroll_complete_%s", type);
                }
                break;
 
        case ZRTP_EVENT_USER_ALREADY_ENROLLED:
                {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "User already enrolled!\n");
-                       switch_channel_set_variable(channel, "zrtp_already_enrolled", "true");
+                       switch_channel_set_variable_name_printf(channel, "true", "zrtp_already_enrolled_%s", type);
                        
-                       if (zrtp_status_ok == zrtp_session_get(rtp_session->zrtp_session, &zrtp_session_info)) {
+                       if (zrtp_status_ok == zrtp_session_get(stream->session, &zrtp_session_info)) {
                                if (zrtp_session_info.sas_is_ready) {
-                                       zrtp_verified_set(zrtp_global, &rtp_session->zrtp_session->zid, 
-                                                                         &rtp_session->zrtp_session->peer_zid, zrtp_session_info.sas_is_verified^1);
+                                       zrtp_verified_set(zrtp_global, &stream->session->zid, 
+                                                                         &stream->session->peer_zid, zrtp_session_info.sas_is_verified^1);
                                }
                        }
                }
@@ -505,12 +535,12 @@ static void zrtp_event_callback(zrtp_stream_t *stream, unsigned event)
        case ZRTP_EVENT_NEW_USER_ENROLLED:
                {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "New user enrolled!\n");
-                       switch_channel_set_variable(channel, "zrtp_new_user_enrolled", "true");
+                       switch_channel_set_variable_name_printf(channel, "true", "zrtp_new_user_enrolled_%s", type);
 
-                       if (zrtp_status_ok == zrtp_session_get(rtp_session->zrtp_session, &zrtp_session_info)) {
+                       if (zrtp_status_ok == zrtp_session_get(stream->session, &zrtp_session_info)) {
                                if (zrtp_session_info.sas_is_ready) {
-                                       zrtp_verified_set(zrtp_global, &rtp_session->zrtp_session->zid, 
-                                                                         &rtp_session->zrtp_session->peer_zid, zrtp_session_info.sas_is_verified^1);
+                                       zrtp_verified_set(zrtp_global, &stream->session->zid, 
+                                                                         &stream->session->peer_zid, zrtp_session_info.sas_is_verified^1);
                                }
                        }
                }
@@ -519,12 +549,12 @@ static void zrtp_event_callback(zrtp_stream_t *stream, unsigned event)
        case ZRTP_EVENT_USER_UNENROLLED:
                {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "User unenrolled!\n");
-                       switch_channel_set_variable(channel, "zrtp_user_unenrolled", "true");
+                       switch_channel_set_variable_name_printf(channel, "true", "zrtp_user_unenrolled_%s", type);
                        
-                       if (zrtp_status_ok == zrtp_session_get(rtp_session->zrtp_session, &zrtp_session_info)) {
+                       if (zrtp_status_ok == zrtp_session_get(stream->session, &zrtp_session_info)) {
                                if (zrtp_session_info.sas_is_ready) {
-                                       zrtp_verified_set(zrtp_global, &rtp_session->zrtp_session->zid, 
-                                                                         &rtp_session->zrtp_session->peer_zid, zrtp_session_info.sas_is_verified^1);
+                                       zrtp_verified_set(zrtp_global, &stream->session->zid, 
+                                                                         &stream->session->peer_zid, zrtp_session_info.sas_is_verified^1);
                                }
                        }
                }
@@ -532,7 +562,7 @@ static void zrtp_event_callback(zrtp_stream_t *stream, unsigned event)
 
        case ZRTP_EVENT_IS_PENDINGCLEAR:
                {
-                       switch_channel_set_variable(channel, "zrtp_secure_media_confirmed", "false");
+                       switch_channel_set_variable_name_printf(channel, "false", "zrtp_secure_media_confirmed_%s", type);
                        switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_SEND);
                        switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_RECV);
                        switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND);
@@ -543,7 +573,7 @@ static void zrtp_event_callback(zrtp_stream_t *stream, unsigned event)
 
        case ZRTP_EVENT_NO_ZRTP:
                {
-                       switch_channel_set_variable(channel, "zrtp_secure_media_confirmed", "false");
+                       switch_channel_set_variable_name_printf(channel, "false", "zrtp_secure_media_confirmed_%s", type);
                }
                break;
 
@@ -556,24 +586,6 @@ static void zrtp_logger(int level, const char *data, int len, int offset)
 {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s", data);
 }
-
-static void zrtp_handler(switch_rtp_t *rtp_session, switch_socket_t *sock, void *data, switch_size_t datalen, switch_sockaddr_t *from_addr)
-{
-       zrtp_status_t status = zrtp_status_fail;
-       unsigned int len = datalen;
-
-       status = zrtp_process_srtp(rtp_session->zrtp_audio_ctx, (char*)data, &len);
-       switch(status) {
-       case zrtp_status_ok:
-               break;
-       case zrtp_status_drop:
-               break;
-       case zrtp_status_fail:
-               break;
-       default:
-               break;
-       }
-}
 #endif
 
 SWITCH_DECLARE(void) switch_rtp_init(switch_memory_pool_t *pool)
@@ -1126,7 +1138,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
 
 
        rtp_session->seq = (uint16_t) rand();
-       rtp_session->ssrc = (uint32_t) ((intptr_t) &rtp_session + (uint32_t) switch_epoch_time_now(NULL));
+       rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (uint32_t) switch_epoch_time_now(NULL));
+
        rtp_session->send_msg.header.ssrc = htonl(rtp_session->ssrc);
        rtp_session->send_msg.header.ts = 0;
        rtp_session->send_msg.header.m = 0;
@@ -1180,6 +1193,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
 
 #ifdef ENABLE_ZRTP
        if (zrtp_on) {
+               switch_rtp_t *master_rtp_session = NULL;
+
                int initiator = 0;
                switch_channel_t *channel = switch_core_session_get_channel(session);
                const char *zrtp_enabled = switch_channel_get_variable(channel, "zrtp_secure_media");
@@ -1191,40 +1206,57 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
                        zrtp_enabled = NULL;
                }
 
-               switch_channel_set_private(channel, "__zrtp_rtp_session", rtp_session);
                
                if (switch_true(zrtp_enabled)) {
+                       if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)){ 
+                               switch_channel_set_private(channel, "__zrtp_video_rtp_session", rtp_session);
+                               master_rtp_session = switch_channel_get_private(channel, "__zrtp_audio_rtp_session");
+                       } else {
+                               switch_channel_set_private(channel, "__zrtp_audio_rtp_session", rtp_session);
+                               master_rtp_session = rtp_session;
+                       }
+
+
                        if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
                                initiator = 1;
                        }
+
+                       if (rtp_session == master_rtp_session) {
+                               rtp_session->zrtp_profile = switch_core_alloc(rtp_session->pool, sizeof(*rtp_session->zrtp_profile));
+                               zrtp_profile_defaults(rtp_session->zrtp_profile, zrtp_global);
                        
-                       rtp_session->zrtp_profile = switch_core_alloc(rtp_session->pool, sizeof(*rtp_session->zrtp_profile));
-                       zrtp_profile_defaults(rtp_session->zrtp_profile, zrtp_global);
+                               rtp_session->zrtp_profile->allowclear = 0;
+                               rtp_session->zrtp_profile->disclose_bit = 0;
+                               rtp_session->zrtp_profile->cache_ttl = -1;
                        
-                       rtp_session->zrtp_profile->allowclear = 0;
-                       rtp_session->zrtp_profile->disclose_bit = 0;
-                       rtp_session->zrtp_profile->cache_ttl = -1;
+                               if (zrtp_status_ok != zrtp_session_init(zrtp_global, rtp_session->zrtp_profile, zid, initiator, &rtp_session->zrtp_session)) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! zRTP INIT Failed\n");
+                                       zrtp_session_down(rtp_session->zrtp_session);
+                                       rtp_session->zrtp_session = NULL;
+                                       goto end;
+                               }
                        
-                       if (zrtp_status_ok != zrtp_session_init(zrtp_global, rtp_session->zrtp_profile, zid, initiator, &rtp_session->zrtp_session)) {
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! zRTP INIT Failed\n");
-                               zrtp_session_down(rtp_session->zrtp_session);
-                               rtp_session->zrtp_session = NULL;
-                       }
+                               zrtp_session_set_userdata(rtp_session->zrtp_session, session);
                        
-                       zrtp_session_set_userdata(rtp_session->zrtp_session, rtp_session);
                        
-                       if (zrtp_status_ok != zrtp_stream_attach(rtp_session->zrtp_session, &rtp_session->zrtp_audio_ctx)) {
-                               abort();
+                               if (zrtp_status_ok != zrtp_stream_attach(master_rtp_session->zrtp_session, &rtp_session->zrtp_stream)) {
+                                       abort();
+                               }
+                               
+                               zrtp_stream_set_userdata(rtp_session->zrtp_stream, rtp_session);
+
+                               if (switch_true(switch_channel_get_variable(channel, "zrtp_enrollment"))) {
+                                       zrtp_stream_registration_start(rtp_session->zrtp_stream, rtp_session->ssrc);
+                               } else {
+                                       zrtp_stream_start(rtp_session->zrtp_stream, rtp_session->ssrc);
+                               }
                        }
-                       zrtp_stream_set_userdata(rtp_session->zrtp_audio_ctx, rtp_session);
                        
-                       if (switch_true(switch_channel_get_variable(channel, "zrtp_enrollment"))) {
-                               zrtp_stream_registration_start(rtp_session->zrtp_audio_ctx, rtp_session->ssrc);
-                       } else {
-                               zrtp_stream_start(rtp_session->zrtp_audio_ctx, rtp_session->ssrc);
-                       }
                }
        }
+
+ end:
+
 #endif 
 
        rtp_session->ready = 1;
@@ -1484,8 +1516,8 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session)
        /* ZRTP */
        if (zrtp_on) {
 
-               if ((*rtp_session)->zrtp_audio_ctx != NULL) {
-                       zrtp_stream_stop((*rtp_session)->zrtp_audio_ctx);
+               if ((*rtp_session)->zrtp_stream != NULL) {
+                       zrtp_stream_stop((*rtp_session)->zrtp_stream);
                }
 
                if (switch_test_flag((*rtp_session), SWITCH_ZRTP_FLAG_SECURE_SEND)) {
@@ -1940,7 +1972,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
                if (!bytes && poll_loop) {
                        goto recvfrom;
                }
-               
+
                if (bytes && rtp_session->recv_msg.header.m && rtp_session->recv_msg.header.pt != rtp_session->te) {
                        rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE);
                }
@@ -2063,24 +2095,43 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
                        do_2833(rtp_session);
                }
 
+#ifdef ENABLE_ZRTP
+               /* ZRTP Recv */
+               if (bytes) {
+                       unsigned int sbytes = (int) bytes;
+                       zrtp_status_t stat = 0;
+                       
+                       stat = zrtp_process_srtp(rtp_session->zrtp_stream, (void *)&rtp_session->recv_msg, &sbytes);
+                       
+                       switch (stat) {
+                       case zrtp_status_ok:
+                               bytes = sbytes;
+                               break;
+                       case zrtp_status_drop:
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection drop with code %d\n", stat);
+                               bytes = 0;
+                               goto do_continue;
+                       case zrtp_status_fail:
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection fail with code %d\n", stat);
+                               ret = -1;
+                               goto end;
+                       default:
+                               break;
+                       }
+               }
+#endif
+               
                if (bytes && rtp_session->recv_msg.header.version != 2) {
                        uint8_t *data = (uint8_t *) rtp_session->recv_msg.body;
+
                        if (rtp_session->recv_msg.header.version == 0) {
-#ifdef ENABLE_ZRTP
-                               if (zrtp_on && ZRTP_PACKETS_MAGIC == zrtp_ntoh32(rtp_session->recv_msg.header.ts)) {
-                                       zrtp_handler(rtp_session, rtp_session->sock_input, (void *) &rtp_session->recv_msg, bytes, rtp_session->from_addr);
-                               } else {
-#endif
-                                       if (rtp_session->ice_user) {
-                                               handle_ice(rtp_session, (void *) &rtp_session->recv_msg, bytes);
-                                       } else if (rtp_session->remote_stun_addr) {
-                                               handle_stun_ping_reply(rtp_session, (void *) &rtp_session->recv_msg, bytes);
-                                       }
-#ifdef ENABLE_ZRTP
+                               if (rtp_session->ice_user) {
+                                       handle_ice(rtp_session, (void *) &rtp_session->recv_msg, bytes);
+                               } else if (rtp_session->remote_stun_addr) {
+                                       handle_stun_ping_reply(rtp_session, (void *) &rtp_session->recv_msg, bytes);
                                }
-#endif
                        }
-
+                       
                        if (rtp_session->invalid_handler) {
                                rtp_session->invalid_handler(rtp_session, rtp_session->sock_input, (void *) &rtp_session->recv_msg, bytes, rtp_session->from_addr);
                        }
@@ -2133,31 +2184,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
                        bytes = sbytes;
                }
 
-#ifdef ENABLE_ZRTP
-               /* ZRTP Recv */
-               if (bytes && switch_test_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_RECV)) {
-                       unsigned int sbytes = (int) bytes;
-                       zrtp_status_t stat = 0;
-                       
-                       stat = zrtp_process_srtp(rtp_session->zrtp_audio_ctx, (void *)&rtp_session->recv_msg, &sbytes);
-                       
-                       switch (stat) {
-                       case zrtp_status_ok:
-                               break;
-                       case zrtp_status_drop:
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection drop with code %d\n", stat);
-                               break;
-                       case zrtp_status_fail:
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection fail with code %d\n", stat);
-                               ret = -1;
-                               goto end;
-                       default:
-                               break;
-                       }
-                       bytes = sbytes;
-               }
-#endif
-
 #ifdef DEBUG_2833
                if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) {
                        printf("sanity %d\n", rtp_session->dtmf_data.in_digit_sanity);
@@ -2504,8 +2530,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
 #ifdef ENABLE_ZRTP
        if (zrtp_on && switch_test_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV)) {
                zrtp_session_info_t zrtp_session_info;
-
-               if (zrtp_status_ok == zrtp_session_get(rtp_session->zrtp_session, &zrtp_session_info)) { 
+               
+               if (rtp_session->zrtp_session && (zrtp_status_ok == zrtp_session_get(rtp_session->zrtp_session, &zrtp_session_info))) { 
                        if (zrtp_session_info.sas_is_ready) {    
                                switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session");
                                switch_channel_t *channel = switch_core_session_get_channel(session);
@@ -2516,7 +2542,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
 
                                        if ((other_session = switch_core_session_locate(uuid))) {
                                                switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
-                                               switch_rtp_t *other_rtp_session = switch_channel_get_private(other_channel, "__zrtp_rtp_session");
+                                               switch_rtp_t *other_rtp_session = switch_channel_get_private(other_channel, "__zrtp_audio_rtp_session");
 
                                                if (other_rtp_session) {
                                                        if (zrtp_status_ok == zrtp_session_get(other_rtp_session->zrtp_session, &zrtp_session_info)) {
@@ -2525,7 +2551,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
                                                                        switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND);
                                                                        switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV);
                                                                        switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND);
-                                                               } else if (zrtp_status_ok == zrtp_resolve_mitm_call(other_rtp_session->zrtp_audio_ctx, rtp_session->zrtp_audio_ctx)) {
+                                                               } else if (zrtp_status_ok == zrtp_resolve_mitm_call(other_rtp_session->zrtp_stream, rtp_session->zrtp_stream)) {
                                                                        switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV);
                                                                        switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND);
                                                                        switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV);
@@ -2541,8 +2567,12 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
                                        }
                                }
                        }
+               } else {
+                       switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV);
+                       switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND);
                }
        }
+                       
 #endif
 
        if (bytes < 0) {
@@ -2798,17 +2828,19 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
                }
 #ifdef ENABLE_ZRTP
                /* ZRTP Send */
-               if (switch_test_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_SEND)) {
+               if (1) {
                        unsigned int sbytes = (int) bytes;
                        zrtp_status_t stat = zrtp_status_fail;
                        
-                       stat = zrtp_process_rtp(rtp_session->zrtp_audio_ctx, (void*)send_msg, &sbytes);
+                       stat = zrtp_process_rtp(rtp_session->zrtp_stream, (void*)send_msg, &sbytes);
 
                        switch (stat) {
                        case zrtp_status_ok:
                                break;
                        case zrtp_status_drop:
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection drop with code %d\n", stat);
+                               ret = (int) bytes;
+                               goto end;
                                break;
                        case zrtp_status_fail:
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection fail with code %d\n", stat);
@@ -3004,7 +3036,6 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
                rtp_session->stats.outbound.media_bytes += bytes;
                rtp_session->stats.outbound.media_packet_count++;
                rtp_session->stats.outbound.packet_count++;
-
                return (int) bytes;
        }
 
@@ -3023,7 +3054,9 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
 
                                        if ((other_session = switch_core_session_locate(uuid))) {
                                                switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
-                                               switch_rtp_t *other_rtp_session = switch_channel_get_private(other_channel, "__zrtp_rtp_session");
+                                               switch_rtp_t *other_rtp_session = switch_channel_get_private(other_channel, "__zrtp_audio_rtp_session");
+
+
                                                if (other_rtp_session) {
                                                        if (zrtp_status_ok == zrtp_session_get(other_rtp_session->zrtp_session, &zrtp_session_info)) {
                                                                if (rtp_session->zrtp_mitm_tries > ZRTP_MITM_TRIES) {
@@ -3031,7 +3064,7 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
                                                                        switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND);
                                                                        switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV);
                                                                        switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND);
-                                                               } else if (zrtp_status_ok == zrtp_resolve_mitm_call(other_rtp_session->zrtp_audio_ctx, rtp_session->zrtp_audio_ctx)) {
+                                                               } else if (zrtp_status_ok == zrtp_resolve_mitm_call(other_rtp_session->zrtp_stream, rtp_session->zrtp_stream)) {
                                                                        switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV);
                                                                        switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND);
                                                                        switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV);
@@ -3152,17 +3185,19 @@ SWITCH_DECLARE(int) switch_rtp_write_manual(switch_rtp_t *rtp_session,
        }
 #ifdef ENABLE_ZRTP
        /* ZRTP Send */
-       if (switch_test_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_SEND)) {
+       if (1) {
                unsigned int sbytes = (int) bytes;
                zrtp_status_t stat = zrtp_status_fail;
                
-               stat = zrtp_process_rtp(rtp_session->zrtp_audio_ctx, (void*)&rtp_session->write_msg, &sbytes);
+               stat = zrtp_process_rtp(rtp_session->zrtp_stream, (void*)&rtp_session->write_msg, &sbytes);
                
                switch (stat) {
                case zrtp_status_ok:
                        break;
                case zrtp_status_drop:
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection drop with code %d\n", stat);
+                       ret = (int) bytes;
+                       goto end;
                        break;
                case zrtp_status_fail:
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection fail with code %d\n", stat);