]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
wip
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 21 Dec 2012 20:22:25 +0000 (14:22 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Mon, 1 Apr 2013 02:27:14 +0000 (21:27 -0500)
Makefile.am
src/include/switch_core_media.h
src/include/switch_types.h
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_sofia/sofia_media.c
src/switch_core_media.c

index e219f0e9b0449e9dd73dc3ba25bef74de08b2752..f9a747d30e70f246b3167d8cd9c9673a49c10d99 100644 (file)
@@ -147,7 +147,7 @@ endif
 lib_LTLIBRARIES                 = libfreeswitch.la
 libfreeswitch_la_CFLAGS  = $(CORE_CFLAGS) $(AM_CFLAGS)
 libfreeswitch_la_LDFLAGS = -version-info 1:0:0 $(AM_LDFLAGS) $(PLATFORM_CORE_LDFLAGS)
-libfreeswitch_la_LIBADD  = $(CORE_LIBS) $(PLATFORM_CORE_LIBS)
+libfreeswitch_la_LIBADD  = $(CORE_LIBS) $(PLATFORM_CORE_LIBS) libs/sofia-sip/libsofia-sip-ua/sdp/.libs/libsdp.a libs/sofia-sip/libsofia-sip-ua/su/.libs/libsu.a
 libfreeswitch_la_DEPENDENCIES = $(BUILT_SOURCES)
 
 if HAVE_ODBC
index 4ee5f1880e385443b1afb5dc39b2b5785c6a1253..21a80a194f6ab8c1db22ad7e048b6e6cb357ffaa 100644 (file)
@@ -44,8 +44,6 @@ typedef enum {
        DTMF_NONE
 } switch_core_media_dtmf_t;
 
-
-
 typedef enum {
        SM_NDLB_ALLOW_BAD_IANANAME = (1 << 0),
        SM_NDLB_ALLOW_NONDUP_SDP = (1 << 1),
@@ -65,39 +63,78 @@ typedef enum {
        SCMF_T38_PASSTHRU,
        SCMF_LIBERAL_DTMF,
        SCMF_SUPPRESS_CNG,
+       SCMF_DISABLE_RTP_AUTOADJ,
+       SCMF_PASS_RFC2833,
+       SCMF_AUTOFLUSH,
+       SCMF_REWRITE_TIMESTAMPS,
        SCMF_MAX
 } switch_core_media_flag_t;
 
 struct switch_media_handle_s;
 
 typedef enum {
-       STYPE_INTVAL,
-       STYPE_UINTVAL,
-       STYPE_CHARVAL,
-} scm_type_t;
+       STUN_FLAG_SET = (1 << 0),
+       STUN_FLAG_PING = (1 << 1),
+       STUN_FLAG_FUNNY = (1 << 2)
+} STUNFLAGS;
 
 typedef enum {
-       SCM_INBOUND_CODEC_STRING,
-       SCM_OUTBOUND_CODEC_STRING,
-       SCM_AUTO_RTP_BUGS,
-       SCM_MANUAL_RTP_BUGS,
-       SCM_MAX
-} scm_param_t;
+       VAD_IN = (1 << 0),
+       VAD_OUT = (1 << 1)
+} switch_core_media_vflag_t;
+
+typedef struct switch_core_media_params_s {
+       uint32_t rtp_timeout_sec;
+       uint32_t rtp_hold_timeout_sec;
+       uint32_t dtmf_delay;
+       uint32_t codec_flags;
+       int reinvite;
+       switch_core_media_NDLB_t ndlb;
+       switch_rtp_bug_flag_t auto_rtp_bugs;
+
+       char *inbound_codec_string;
+       char *outbound_codec_string;
+
+       char *timer_name;
+
+       char *remote_sdp_str;
+       char *early_sdp;
+       char *local_sdp_str;
+       char *last_sdp_str;
+
+       char *stun_ip;
+       switch_port_t stun_port;
+       uint32_t stun_flags;
+
+       char *jb_msec;
+
+       switch_core_media_vflag_t vflags;
+
+       switch_rtp_bug_flag_t manual_rtp_bugs;
+       switch_rtp_bug_flag_t manual_video_rtp_bugs;
+
+       char *rtcp_audio_interval_msec;
+       char *rtcp_video_interval_msec;
+
+
+       char *extrtpip;
+       char *rtpip;
+
+       char *remote_ip;
+       int remote_port;
 
-#define switch_media_get_param_int(_h, _p) *(int *)switch_media_get_param(_h, _p)
-#define switch_media_get_param_uint(_h, _p) *(uint32_t *)switch_media_get_param(_h, _p)
-#define switch_media_get_param_char(_h, _p) (char *)switch_media_get_param(_h, _p)
+       char *extsipip;
+       char *local_network;
+       
 
+} switch_core_media_params_t;
 
 
 
-SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t **smhp, switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t **smhp, switch_core_session_t *session, switch_core_media_params_t *params);
 SWITCH_DECLARE(switch_media_handle_t *) switch_core_session_get_media_handle(switch_core_session_t *session);
 SWITCH_DECLARE(switch_status_t) switch_core_session_clear_media_handle(switch_core_session_t *session);
 SWITCH_DECLARE(switch_status_t) switch_core_session_media_handle_ready(switch_core_session_t *session);
-SWITCH_DECLARE(void) switch_media_handle_set_ndlb(switch_media_handle_t *smh, switch_core_media_NDLB_t flag);
-SWITCH_DECLARE(void) switch_media_handle_clear_ndlb(switch_media_handle_t *smh, switch_core_media_NDLB_t flag);
-SWITCH_DECLARE(int32_t) switch_media_handle_test_ndlb(switch_media_handle_t *smh, switch_core_media_NDLB_t flag);
 SWITCH_DECLARE(void) switch_media_handle_set_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag);
 SWITCH_DECLARE(void) switch_media_handle_clear_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag);
 SWITCH_DECLARE(int32_t) switch_media_handle_test_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag);
@@ -113,8 +150,6 @@ SWITCH_DECLARE(void) switch_core_session_get_recovery_crypto_key(switch_core_ses
 
 SWITCH_DECLARE(void) switch_core_media_set_rtp_session(switch_core_session_t *session, switch_media_type_t type, switch_rtp_t *rtp_session);
 
-SWITCH_DECLARE(void) switch_media_set_param(switch_media_handle_t *smh, scm_param_t param, ...);
-SWITCH_DECLARE(void *) switch_media_get_param(switch_media_handle_t *smh, scm_param_t param);
 SWITCH_DECLARE(const char *)switch_core_media_get_codec_string(switch_core_session_t *session);
 SWITCH_DECLARE(void) switch_core_media_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str);
 SWITCH_DECLARE(switch_t38_options_t *) switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m);
@@ -126,6 +161,14 @@ SWITCH_DECLARE(void) switch_core_media_pass_zrtp_hash2(switch_core_session_t *al
 SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session, int sendonly);
 SWITCH_DECLARE(void) switch_core_media_copy_t38_options(switch_t38_options_t *t38_options, switch_core_session_t *session);
 SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp, uint8_t *proceed, int reinvite, int codec_flags, switch_payload_t default_te);
+SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_session_t *session, int force);
+SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_t *session, int force, uint32_t codec_flags);
+SWITCH_DECLARE(void) switch_core_media_check_video_codecs(switch_core_session_t *session);
+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);
+SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_session_t *session, 
+                                                                                                                         switch_frame_t *frame, switch_io_flag_t flags, int stream_id, switch_media_type_t type);
+SWITCH_DECLARE(int) switch_core_media_check_nat(switch_media_handle_t *smh, const char *network_ip);
 
 SWITCH_END_EXTERN_C
 #endif
index 1a69c4c256f76d5b132e2670ee651d9f125888dd..f6ca438a6b4b8bd4090a1550ba32b0097432c206 100644 (file)
@@ -1288,6 +1288,8 @@ typedef enum {
        CF_PROTO_HOLD, //TFLAG_SIP_HOLD
        CF_HOLD_LOCK,
        CF_VIDEO_POSSIBLE,//TFLAG_VIDEO
+       CF_NOTIMER_DURING_BRIDGE,
+       CF_PASS_RFC2833,
        /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
        /* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
        CF_FLAG_MAX
index 93a232b9cd8164fe429ac5b264d5118af39772f8..209ae2577bddc423ae110c50b0842522c3c42bdc 100644 (file)
@@ -944,15 +944,13 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
 static switch_status_t sofia_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
 {
        private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
-       switch_channel_t *channel = switch_core_session_get_channel(session);
-       uint32_t sanity = 1000;
 
        switch_assert(tech_pvt != NULL);
 
        if (sofia_test_flag(tech_pvt, TFLAG_HUP)) {
                return SWITCH_STATUS_FALSE;
        }
-
+#if 0
        while (!(tech_pvt->video_read_codec.implementation && switch_rtp_ready(tech_pvt->video_rtp_session) && !switch_channel_test_flag(channel, CF_REQ_MEDIA))) {
                switch_ivr_parse_all_messages(tech_pvt->session);
                
@@ -963,59 +961,19 @@ static switch_status_t sofia_read_video_frame(switch_core_session_t *session, sw
                        return SWITCH_STATUS_GENERR;
                }
        }
+#endif
 
-       tech_pvt->video_read_frame.datalen = 0;
-
-       if (sofia_test_flag(tech_pvt, TFLAG_IO)) {
-               switch_status_t status;
-
-               if (!sofia_test_flag(tech_pvt, TFLAG_RTP)) {
-                       return SWITCH_STATUS_GENERR;
-               }
-
-               switch_assert(tech_pvt->rtp_session != NULL);
-               tech_pvt->video_read_frame.datalen = 0;
-
-               while (sofia_test_flag(tech_pvt, TFLAG_IO) && tech_pvt->video_read_frame.datalen == 0) {
-                       tech_pvt->video_read_frame.flags = SFF_NONE;
-
-                       status = switch_rtp_zerocopy_read_frame(tech_pvt->video_rtp_session, &tech_pvt->video_read_frame, flags);
-                       if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
-                               if (status == SWITCH_STATUS_TIMEOUT) {
-                                       if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)) {
-                                               sofia_media_toggle_hold(tech_pvt, 0);
-                                               sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
-                                               switch_channel_clear_flag(channel, CF_LEG_HOLDING);
-                                       }
-                                       switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_MEDIA_TIMEOUT);
-                               }
-                               return status;
-                       }
-
-                       if (tech_pvt->video_read_frame.datalen > 0) {
-                               break;
-                       }
-               }
-       }
 
-       if (tech_pvt->video_read_frame.datalen == 0) {
-               *frame = NULL;
-               return SWITCH_STATUS_GENERR;
-       }
-
-       *frame = &tech_pvt->video_read_frame;
+       return switch_core_media_read_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_VIDEO);
 
-       return SWITCH_STATUS_SUCCESS;
 }
 
 static switch_status_t sofia_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
 {
        private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
-       switch_channel_t *channel = switch_core_session_get_channel(session);
-       int wrote = 0;
-
        switch_assert(tech_pvt != NULL);
 
+#if 0
        while (!(tech_pvt->video_read_codec.implementation && switch_rtp_ready(tech_pvt->video_rtp_session))) {
                if (switch_channel_ready(channel)) {
                        switch_yield(10000);
@@ -1023,6 +981,7 @@ static switch_status_t sofia_write_video_frame(switch_core_session_t *session, s
                        return SWITCH_STATUS_GENERR;
                }
        }
+#endif
 
        if (sofia_test_flag(tech_pvt, TFLAG_HUP)) {
                return SWITCH_STATUS_FALSE;
@@ -1036,11 +995,8 @@ static switch_status_t sofia_write_video_frame(switch_core_session_t *session, s
                return SWITCH_STATUS_SUCCESS;
        }
 
-       if (!switch_test_flag(frame, SFF_CNG)) {
-               wrote = switch_rtp_write_frame(tech_pvt->video_rtp_session, frame);
-       }
-
-       return wrote > 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_GENERR;
+       return switch_core_media_write_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_VIDEO);
+       
 }
 
 static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
@@ -1105,7 +1061,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
                                if (status == SWITCH_STATUS_TIMEOUT) {
 
                                        if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)) {
-                                               sofia_media_toggle_hold(tech_pvt, 0);
+                                               switch_core_media_toggle_hold(session, 0);
                                                sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
                                                switch_channel_clear_flag(channel, CF_LEG_HOLDING);
                                        }
@@ -1274,7 +1230,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
                                                                                tech_pvt->codec_ms = codec_ms;
                                                                        }
 
-                                                                       if (sofia_media_tech_set_codec(tech_pvt, 2) != SWITCH_STATUS_SUCCESS) {
+                                                                       if (switch_core_media_set_codec(tech_pvt->session, 2, tech_pvt->profile->codec_flags) != SWITCH_STATUS_SUCCESS) {
                                                                                *frame = NULL;
                                                                                return SWITCH_STATUS_GENERR;
                                                                        }
@@ -1906,7 +1862,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                tech_pvt->video_rm_encoding = NULL;
                                switch_channel_clear_flag(tech_pvt->channel, CF_VIDEO_POSSIBLE);
                                sofia_media_tech_prepare_codecs(tech_pvt);
-                               sofia_media_check_video_codecs(tech_pvt);
+                               switch_core_media_check_video_codecs(tech_pvt->session);
                                sofia_media_set_local_sdp(tech_pvt, NULL, 0, NULL, 1);
                                sofia_set_pflag(tech_pvt->profile, PFLAG_RENEG_ON_REINVITE);
                                sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
@@ -2446,7 +2402,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                {
 
                        if (msg->numeric_arg) {
-                               sofia_media_toggle_hold(tech_pvt, 1);
+                               switch_core_media_toggle_hold(session, 1);
                        } else {
 
                                sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
index 8f6a083316de7fadc13cd5cc8b60f225b58dff11..0f07da49157dec2fe983a2ca3819a33b54b3cda0 100644 (file)
@@ -199,9 +199,7 @@ typedef enum {
        PFLAG_AUTH_ALL,
        PFLAG_FULL_ID,
        PFLAG_MULTIREG_CONTACT,
-       PFLAG_PASS_RFC2833,
        PFLAG_DISABLE_TRANSCODING,
-       PFLAG_REWRITE_TIMESTAMPS,
        PFLAG_RUNNING,
        PFLAG_RESPAWN,
        PFLAG_MULTIREG,
@@ -218,10 +216,6 @@ typedef enum {
        PFLAG_AGGRESSIVE_NAT_DETECTION,
        PFLAG_RECIEVED_IN_NAT_REG_CONTACT,
        PFLAG_3PCC,
-       PFLAG_DISABLE_RTP_AUTOADJ,
-       PFLAG_FUNNY_STUN,
-       PFLAG_STUN_ENABLED,
-       PFLAG_STUN_AUTO_DISABLE,
        PFLAG_3PCC_PROXY,
        PFLAG_CALLID_AS_UUID,
        PFLAG_UUID_AS_CALLID,
@@ -230,7 +224,6 @@ typedef enum {
        PFLAG_DISABLE_SRV,
        PFLAG_DISABLE_SRV503,
        PFLAG_DISABLE_NAPTR,
-       PFLAG_AUTOFLUSH,
        PFLAG_NAT_OPTIONS_PING,
        PFLAG_ALL_REG_OPTIONS_PING,
        PFLAG_MESSAGE_QUERY_ON_REGISTER,
@@ -282,12 +275,6 @@ typedef enum {
        PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE = (1 << 6)
 } sofia_NDLB_t;
 
-typedef enum {
-       STUN_FLAG_SET = (1 << 0),
-       STUN_FLAG_PING = (1 << 1),
-       STUN_FLAG_FUNNY = (1 << 2)
-} STUNFLAGS;
-
 typedef enum {
        TFLAG_IO,
        TFLAG_CHANGE_MEDIA,
@@ -299,9 +286,6 @@ typedef enum {
        TFLAG_BYE,
        TFLAG_ANS,
        TFLAG_EARLY_MEDIA,
-       TFLAG_VAD_IN,
-       TFLAG_VAD_OUT,
-       TFLAG_VAD,
        TFLAG_3PCC,
        TFLAG_READY,
        TFLAG_REINVITE,
@@ -326,7 +310,6 @@ typedef enum {
        TFLAG_T38_PASSTHRU,
        TFLAG_RECOVERED,
        TFLAG_AUTOFLUSH_DURING_BRIDGE,
-       TFLAG_NOTIMER_DURING_BRIDGE,
        TFLAG_JB_PAUSED,
        TFLAG_3PCC_INVITE,
        TFLAG_NOREPLY,
@@ -575,9 +558,6 @@ struct sofia_profile {
        char *presence_hosts;
        char *presence_privacy;
        char *challenge_realm;
-       char *rtcp_audio_interval_msec;
-       char *rtcp_video_interval_msec;
-       char *jb_msec;
        char *pnp_prov_url;
        char *pnp_notify_profile;
        sofia_cid_type_t cid_type;
@@ -603,7 +583,6 @@ struct sofia_profile {
        switch_memory_pool_t *pool;
        su_root_t *s_root;
        sip_alias_node_t *aliases;
-       switch_payload_t te;
        switch_payload_t cng_pt;
        uint32_t codec_flags;
        switch_mutex_t *ireg_mutex;
@@ -684,6 +663,7 @@ struct sofia_profile {
        uint32_t rtp_digit_delay;
        switch_queue_t *event_queue;
        switch_thread_t *thread;                
+       switch_core_media_vflag_t vflags;
 };
 
 struct private_object {
@@ -695,6 +675,7 @@ struct private_object {
        switch_core_session_t *session;
        switch_channel_t *channel;
        switch_media_handle_t *media_handle;
+       switch_core_media_params_t *mparams;
 
        switch_frame_t read_frame;
        char *codec_order[SWITCH_MAX_CODECS];
@@ -710,17 +691,9 @@ struct private_object {
        switch_caller_profile_t *caller_profile;
        uint32_t timestamp_send;
        switch_rtp_t *rtp_session;
-       uint32_t ssrc;
+
        uint32_t video_ssrc;
        sofia_profile_t *profile;
-       char *local_sdp_audio_ip;
-       switch_port_t local_sdp_audio_port;
-       char *remote_sdp_audio_ip;
-       switch_port_t remote_sdp_audio_port;
-       char *adv_sdp_audio_ip;
-       switch_port_t adv_sdp_audio_port;
-       char *proxy_sdp_audio_ip;
-       switch_port_t proxy_sdp_audio_port;
        char *reply_contact;
        char *from_uri;
        char *to_uri;
@@ -738,10 +711,6 @@ struct private_object {
        char *iananame;
        char *rm_fmtp;
        char *fmtp_out;
-       char *remote_sdp_str;
-       char *early_sdp;
-       char *local_sdp_str;
-       char *last_sdp_str;
        char *dest;
        char *dest_to;
        char *key;
@@ -757,16 +726,12 @@ struct private_object {
        char *local_url;
        char *gateway_name;
        char *record_route;
-       char *extrtpip;
-       char *stun_ip;
        char *route_uri;
        char *x_freeswitch_support_remote;
        char *x_freeswitch_support_local;
        char *last_sent_callee_id_name;
        char *last_sent_callee_id_number;
-       char *rtpip;
-       switch_port_t stun_port;
-       uint32_t stun_flags;
+
        unsigned long rm_rate;
        switch_payload_t pt;
        switch_mutex_t *flag_mutex;
@@ -795,16 +760,12 @@ struct private_object {
        switch_payload_t video_pt;
        unsigned long video_rm_rate;
        uint32_t video_codec_ms;
-       char *remote_sdp_video_ip;
-       switch_port_t remote_sdp_video_port;
        char *video_rm_fmtp;
        switch_payload_t video_agreed_pt;
        char *video_fmtp_out;
        uint32_t video_count;
        switch_core_media_dtmf_t dtmf_type;
        int q850_cause;
-       char *remote_ip;
-       int remote_port;
        int got_bye;
        int hold_laps;
        switch_thread_id_t locker;
@@ -1012,8 +973,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot);
 void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now);
 void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now);
 void sofia_reg_unregister(sofia_profile_t *profile);
-switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, private_object_t *tech_pvt, char **ip, switch_port_t *port,
-                                                                                         const char *sourceip, switch_memory_pool_t *pool);
+
 
 void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp);
 switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status);
@@ -1033,7 +993,6 @@ char *sofia_overcome_sip_uri_weakness(switch_core_session_t *session, const char
 switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback,
                                                                                          void *pdata);
 char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len);
-void sofia_media_check_video_codecs(private_object_t *tech_pvt);
 void sofia_glue_del_profile(sofia_profile_t *profile);
 
 switch_status_t sofia_glue_add_profile(char *key, sofia_profile_t *profile);
@@ -1106,18 +1065,17 @@ char *sofia_glue_find_parameter_value(switch_core_session_t *session, const char
 char *sofia_glue_create_via(switch_core_session_t *session, const char *ip, switch_port_t port, sofia_transport_t transport);
 char *sofia_glue_create_external_via(switch_core_session_t *session, sofia_profile_t *profile, sofia_transport_t transport);
 char *sofia_glue_strip_uri(const char *str);
-int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip);
+
 int sofia_glue_transport_has_tls(const sofia_transport_t tp);
 const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name);
 switch_status_t sofia_media_build_crypto(private_object_t *tech_pvt, int index, switch_rtp_crypto_key_type_t type, switch_rtp_crypto_direction_t direction);
 void sofia_media_tech_patch_sdp(private_object_t *tech_pvt);
-switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt, const char *sdp_str);
 void sofia_presence_event_thread_start(void);
 void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int reboot);
 void sofia_reg_check_call_id(sofia_profile_t *profile, const char *call_id);
 void sofia_reg_check_sync(sofia_profile_t *profile);
-switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, int force);
-switch_status_t sofia_media_tech_set_video_codec(private_object_t *tech_pvt, int force);
+
+
 char *sofia_glue_get_register_host(const char *uri);
 const char *sofia_glue_strip_proto(const char *uri);
 void sofia_glue_del_gateway(sofia_gateway_t *gp);
@@ -1126,9 +1084,7 @@ void sofia_glue_del_every_gateway(sofia_profile_t *profile);
 void sofia_reg_send_reboot(sofia_profile_t *profile, const char *callid, const char *user, const char *host, const char *contact, const char *user_agent,
                                                   const char *network_ip);
 void sofia_glue_restart_all_profiles(void);
-int sofia_media_toggle_hold(private_object_t *tech_pvt, int sendonly);
 const char *sofia_state_string(int state);
-switch_status_t sofia_media_tech_set_codec(private_object_t *tech_pvt, int force);
 void sofia_wait_for_reply(struct private_object *tech_pvt, nua_event_t event, uint32_t timeout);
 void sofia_glue_set_udptl_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *t38_options, int insist);
 
@@ -1175,8 +1131,6 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor
 const char *sofia_gateway_status_name(sofia_gateway_status_t status);
 void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int status, const char *phrase);
 uint32_t sofia_reg_reg_count(sofia_profile_t *profile, const char *user, const char *host);
-void sofia_media_copy_t38_options(switch_t38_options_t *t38_options, switch_core_session_t *session);
-switch_t38_options_t *sofia_media_extract_t38_options(switch_core_session_t *session, const char *r_sdp);
 char *sofia_media_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type);
 int sofia_glue_tech_simplify(private_object_t *tech_pvt);
 switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host);
index ea42f7731be4487a918e50c5b46bfb715371e6e5..f4bec11606eac379c16b5e9ae95e2eb7b0ea690b 100644 (file)
@@ -3920,27 +3920,13 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                        } else if (!strcasecmp(var, "aggressive-nat-detection") && switch_true(val)) {
                                                sofia_set_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION);
                                        } else if (!strcasecmp(var, "disable-rtp-auto-adjust") && switch_true(val)) {
-                                               sofia_set_pflag(profile, PFLAG_DISABLE_RTP_AUTOADJ);
-                                       } else if (!strcasecmp(var, "NDLB-support-asterisk-missing-srtp-auth") && switch_true(val)) {
-                                               profile->ndlb |= SM_NDLB_DISABLE_SRTP_AUTH;
-                                       } else if (!strcasecmp(var, "NDLB-funny-stun")) {
-                                               if (switch_true(val)) {
-                                                       sofia_set_pflag(profile, PFLAG_FUNNY_STUN);
-                                               } else {
-                                                       sofia_clear_pflag(profile, PFLAG_FUNNY_STUN);
-                                               }
-                                       } else if (!strcasecmp(var, "stun-enabled")) {
                                                if (switch_true(val)) {
-                                                       sofia_set_pflag(profile, PFLAG_STUN_ENABLED);
+                                                       sofia_set_media_flag(profile, SCMF_DISABLE_RTP_AUTOADJ);
                                                } else {
-                                                       sofia_clear_pflag(profile, PFLAG_STUN_ENABLED);
-                                               }
-                                       } else if (!strcasecmp(var, "stun-auto-disable")) {
-                                               if (switch_true(val)) {
-                                                       sofia_set_pflag(profile, PFLAG_STUN_AUTO_DISABLE);
-                                               } else {
-                                                       sofia_clear_pflag(profile, PFLAG_STUN_AUTO_DISABLE);
+                                                       sofia_clear_media_flag(profile, SCMF_DISABLE_RTP_AUTOADJ);
                                                }
+                                       } else if (!strcasecmp(var, "NDLB-support-asterisk-missing-srtp-auth") && switch_true(val)) {
+                                               profile->ndlb |= SM_NDLB_DISABLE_SRTP_AUTH;
                                        } else if (!strcasecmp(var, "user-agent-filter")) {
                                                profile->user_agent_filter = switch_core_strdup(profile->pool, val);
                                        } else if (!strcasecmp(var, "max-registrations-per-extension")) {
@@ -3958,12 +3944,11 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                                }
                                        } else if (!strcasecmp(var, "vad")) {
                                                if (!strcasecmp(val, "in")) {
-                                                       sofia_set_flag(profile, TFLAG_VAD_IN);
+                                                       profile->vflags |= VAD_IN;
                                                } else if (!strcasecmp(val, "out")) {
-                                                       sofia_set_flag(profile, TFLAG_VAD_OUT);
+                                                       profile->vflags |= VAD_OUT;
                                                } else if (!strcasecmp(val, "both")) {
-                                                       sofia_set_flag(profile, TFLAG_VAD_IN);
-                                                       sofia_set_flag(profile, TFLAG_VAD_OUT);
+                                                       profile->vflags |= VAD_OUT | VAD_IN;
                                                } else if (strcasecmp(val, "none")) {
                                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid option %s for VAD\n", val);
                                                }
@@ -5235,7 +5220,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
                                                switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ);
                                                switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_FAIL);
                                        } else if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38 && sip->sip_payload && sip->sip_payload->pl_data) {
-                                               switch_t38_options_t *t38_options = sofia_media_extract_t38_options(session, sip->sip_payload->pl_data);
+                                               switch_t38_options_t *t38_options = switch_core_media_extract_t38_options(session, sip->sip_payload->pl_data);
                                                
                                                if (!t38_options) {
                                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Could not parse T.38 options from sdp.\n");
@@ -5274,7 +5259,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
                                                                }
                                                        }
 
-                                                       sofia_media_copy_t38_options(t38_options, other_session);
+                                                       switch_core_media_copy_t38_options(t38_options, other_session);
                                                }
                                        }
 
@@ -5450,7 +5435,7 @@ void *SWITCH_THREAD_FUNC media_on_hold_thread_run(switch_thread_t *thread, void
                                        switch_rtp_clear_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
                                }
 
-                               sofia_media_toggle_hold(tech_pvt, 1);
+                               switch_core_media_toggle_hold(session, 1);
                        }
                        switch_core_session_rwunlock(other_session);
                }
index f72eee39e2f8bcc3540d2fb15c711c051b58af5a..9dedfbc672a69fb1dfb48e8e898c0e9ce5bea43b 100644 (file)
@@ -279,12 +279,22 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
        switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP);
        switch_channel_set_cap(tech_pvt->channel, CC_QUEUEABLE_DTMF_DELAY);
 
-       switch_media_handle_create(&tech_pvt->media_handle, session);
-       switch_media_handle_set_ndlb(tech_pvt->media_handle, tech_pvt->profile->ndlb);
-       switch_media_handle_set_media_flags(tech_pvt->media_handle, tech_pvt->profile->media_flags);
+       tech_pvt->mparams->ndlb = tech_pvt->profile->ndlb;
+       tech_pvt->mparams->inbound_codec_string = profile->inbound_codec_string;
+       tech_pvt->mparams->outbound_codec_string = profile->outbound_codec_string;
+       tech_pvt->mparams->auto_rtp_bugs = profile->auto_rtp_bugs;
+       tech_pvt->mparams->timer_name = profile->timer_name;
+       tech_pvt->mparams->vflags = profile->vflags;
+       tech_pvt->mparams->manual_rtp_bugs = profile->manual_rtp_bugs;
+       tech_pvt->mparams->manual_video_rtp_bugs = profile->manual_video_rtp_bugs;
+       tech_pvt->mparams->extsipip = profile->extsipip;
+       tech_pvt->mparams->local_network = profile->local_network;
+
        
-       switch_media_set_param(tech_pvt->media_handle, SCM_INBOUND_CODEC_STRING, profile->inbound_codec_string);
-       switch_media_set_param(tech_pvt->media_handle, SCM_OUTBOUND_CODEC_STRING, profile->inbound_codec_string);
+       switch_media_handle_create(&tech_pvt->media_handle, session, &tech_pvt->mparams);
+       switch_media_handle_set_media_flags(tech_pvt->media_handle, tech_pvt->profile->media_flags);
+
+
 
 
        switch_core_session_set_private(session, tech_pvt);
@@ -295,100 +305,6 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
 
 }
 
-switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, private_object_t *tech_pvt, char **ip, switch_port_t *port,
-                                                                                         const char *sourceip, switch_memory_pool_t *pool)
-{
-       char *error = "";
-       switch_status_t status = SWITCH_STATUS_FALSE;
-       int x;
-       switch_port_t myport = *port;
-       const char *var;
-       int funny = 0;
-       switch_port_t stun_port = SWITCH_STUN_DEFAULT_PORT;
-       char *stun_ip = NULL;
-
-       if (!sourceip) {
-               return status;
-       }
-
-       if (!strncasecmp(sourceip, "host:", 5)) {
-               status = (*ip = switch_stun_host_lookup(sourceip + 5, pool)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
-       } else if (!strncasecmp(sourceip, "stun:", 5)) {
-               char *p;
-
-               if (!sofia_test_pflag(profile, PFLAG_STUN_ENABLED)) {
-                       *ip = switch_core_strdup(pool, tech_pvt->rtpip);
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Trying to use STUN but its disabled!\n");
-                       goto out;
-               }
-
-               stun_ip = strdup(sourceip + 5);
-
-               if ((p = strchr(stun_ip, ':'))) {
-                       int iport;
-                       *p++ = '\0';
-                       iport = atoi(p);
-                       if (iport > 0 && iport < 0xFFFF) {
-                               stun_port = (switch_port_t) iport;
-                       }
-               }
-
-               if (zstr(stun_ip)) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! NO STUN SERVER\n");
-                       goto out;
-               }
-
-               for (x = 0; x < 5; x++) {
-                       if (sofia_test_pflag(profile, PFLAG_FUNNY_STUN) ||
-                               (tech_pvt && (var = switch_channel_get_variable(tech_pvt->channel, "funny_stun")) && switch_true(var))) {
-                               error = "funny";
-                               funny++;
-                       }
-                       if ((status = switch_stun_lookup(ip, port, stun_ip, stun_port, &error, pool)) != SWITCH_STATUS_SUCCESS) {
-                               switch_yield(100000);
-                       } else {
-                               break;
-                       }
-               }
-               if (status != SWITCH_STATUS_SUCCESS) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! %s:%d [%s]\n", stun_ip, stun_port, error);
-                       goto out;
-               }
-               if (!*ip) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! No IP returned\n");
-                       goto out;
-               }
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN Success [%s]:[%d]\n", *ip, *port);
-               status = SWITCH_STATUS_SUCCESS;
-               if (tech_pvt) {
-                       if (myport == *port && !strcmp(*ip, tech_pvt->rtpip)) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN Not Required ip and port match. [%s]:[%d]\n", *ip, *port);
-                               if (sofia_test_pflag(profile, PFLAG_STUN_AUTO_DISABLE)) {
-                                       sofia_clear_pflag(profile, PFLAG_STUN_ENABLED);
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN completely disabled.\n");
-                               }
-                       } else {
-                               tech_pvt->stun_ip = switch_core_session_strdup(tech_pvt->session, stun_ip);
-                               tech_pvt->stun_port = stun_port;
-                               tech_pvt->stun_flags |= STUN_FLAG_SET;
-                               if (funny) {
-                                       tech_pvt->stun_flags |= STUN_FLAG_FUNNY;
-                               }
-                       }
-               }
-       } else {
-               *ip = (char *) sourceip;
-               status = SWITCH_STATUS_SUCCESS;
-       }
-
- out:
-
-       switch_safe_free(stun_ip);
-
-       return status;
-}
-
-
 const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name)
 {
        sip_unknown_t *un;
@@ -472,69 +388,6 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc
 }
 
 
-switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, int force)
-{
-       char *lookup_rtpip = tech_pvt->rtpip;   /* Pointer to externally looked up address */
-       switch_port_t sdp_port;         /* The external port to be sent in the SDP */
-       const char *use_ip = NULL;      /* The external IP to be sent in the SDP */
-
-       /* Don't do anything if we're in proxy mode or if a (remote) port already has been found */
-       if (!force) {
-               if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) ||
-                       switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) || tech_pvt->adv_sdp_video_port) {
-                       return SWITCH_STATUS_SUCCESS;
-               }
-       }
-
-       /* Release the local sdp port */
-       if (tech_pvt->local_sdp_video_port) {
-               switch_rtp_release_port(tech_pvt->rtpip, tech_pvt->local_sdp_video_port);
-       }
-
-       /* Request a local port from the core's allocator */
-       if (!(tech_pvt->local_sdp_video_port = switch_rtp_request_port(tech_pvt->rtpip))) {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_CRIT, "No RTP ports available!\n");
-               return SWITCH_STATUS_FALSE;
-       }
-
-       sdp_port = tech_pvt->local_sdp_video_port;
-
-       /* Check if NAT is detected  */
-       if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
-               /* Yes, map the port through switch_nat */
-               switch_nat_add_mapping(tech_pvt->local_sdp_video_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE);
-
-               /* Find an IP address to use */
-               if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_video_ip"))
-                       && !zstr(tech_pvt->profile->extrtpip)) {
-                       use_ip = tech_pvt->profile->extrtpip;
-               }
-
-               if (use_ip) {
-                       if (sofia_glue_ext_address_lookup(tech_pvt->profile, tech_pvt, &lookup_rtpip, &sdp_port,
-                                                                                         use_ip, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
-                               /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */
-                               return SWITCH_STATUS_FALSE;
-                       } else {
-                               /* Address properly resolved, use it as external ip */
-                               use_ip = lookup_rtpip;
-                       }
-               } else {
-                       /* No external ip found, use the profile's rtp ip */
-                       use_ip = tech_pvt->rtpip;
-               }
-       } else {
-               /* No NAT traversal required, use the profile's rtp ip */
-               use_ip = tech_pvt->rtpip;
-       }
-
-       tech_pvt->adv_sdp_video_port = sdp_port;
-       switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip);
-       switch_channel_set_variable_printf(tech_pvt->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, "%d", sdp_port);
-
-       return SWITCH_STATUS_SUCCESS;
-}
-
 sofia_transport_t sofia_glue_str2transport(const char *str)
 {
        if (!strncasecmp(str, "udp", 3)) {
@@ -726,14 +579,7 @@ char *sofia_glue_strip_uri(const char *str)
        return r;
 }
 
-int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip)
-{
-       switch_assert(network_ip);
 
-       return (profile->extsipip && 
-                       !switch_check_network_list_ip(network_ip, "loopback.auto") && 
-                       !switch_check_network_list_ip(network_ip, profile->local_network));
-}
 
 int sofia_glue_transport_has_tls(const sofia_transport_t tp)
 {
@@ -825,172 +671,6 @@ char *sofia_overcome_sip_uri_weakness(switch_core_session_t *session, const char
        return new_uri;
 }
 
-#define RA_PTR_LEN 512
-switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt, const char *sdp_str)
-{
-       const char *err;
-       char rip[RA_PTR_LEN] = "";
-       char rp[RA_PTR_LEN] = "";
-       char rvp[RA_PTR_LEN] = "";
-       char *p, *ip_ptr = NULL, *port_ptr = NULL, *vid_port_ptr = NULL, *pe;
-       int x;
-       const char *val;
-       switch_status_t status = SWITCH_STATUS_FALSE;
-       
-       if (zstr(sdp_str)) {
-               sdp_str = tech_pvt->remote_sdp_str;
-       }
-
-       if (zstr(sdp_str)) {
-               goto end;
-       }
-
-       if ((p = (char *) switch_stristr("c=IN IP4 ", sdp_str)) || (p = (char *) switch_stristr("c=IN IP6 ", sdp_str))) {
-               ip_ptr = p + 9;
-       }
-
-       if ((p = (char *) switch_stristr("m=audio ", sdp_str))) {
-               port_ptr = p + 8;
-       }
-
-       if ((p = (char *) switch_stristr("m=image ", sdp_str))) {
-               char *tmp = p + 8;
-
-               if (tmp && atoi(tmp)) {
-                       port_ptr = tmp;
-               }
-       }
-
-       if ((p = (char *) switch_stristr("m=video ", sdp_str))) {
-               vid_port_ptr = p + 8;
-       }
-
-       if (!(ip_ptr && port_ptr)) {
-               goto end;
-       }
-
-       p = ip_ptr;
-       pe = p + strlen(p);
-       x = 0;
-       while (x < sizeof(rip) - 1 && p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F'))) {
-               rip[x++] = *p;
-               p++;
-               if (p >= pe) {
-                       goto end;
-               }
-       }
-
-       p = port_ptr;
-       x = 0;
-       while (x < sizeof(rp) - 1 && p && *p && (*p >= '0' && *p <= '9')) {
-               rp[x++] = *p;
-               p++;
-               if (p >= pe) {
-                       goto end;
-               }
-       }
-
-       p = vid_port_ptr;
-       x = 0;
-       while (x < sizeof(rvp) - 1 && p && *p && (*p >= '0' && *p <= '9')) {
-               rvp[x++] = *p;
-               p++;
-               if (p >= pe) {
-                       goto end;
-               }
-       }
-
-       if (!(*rip && *rp)) {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "invalid SDP\n");
-               goto end;
-       }
-
-       tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, rip);
-       tech_pvt->remote_sdp_audio_port = (switch_port_t) atoi(rp);
-
-       if (*rvp) {
-               tech_pvt->remote_sdp_video_ip = switch_core_session_strdup(tech_pvt->session, rip);
-               tech_pvt->remote_sdp_video_port = (switch_port_t) atoi(rvp);
-       }
-
-       if (tech_pvt->remote_sdp_video_ip && tech_pvt->remote_sdp_video_port) {
-               if (!strcmp(tech_pvt->remote_sdp_video_ip, rip) && atoi(rvp) == tech_pvt->remote_sdp_video_port) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Remote video address:port [%s:%d] has not changed.\n",
-                                                         tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
-               } else {
-                       switch_channel_set_flag(tech_pvt->channel, CF_VIDEO_POSSIBLE);
-                       switch_channel_set_flag(tech_pvt->channel, CF_VIDEO);
-                       if (switch_rtp_ready(tech_pvt->video_rtp_session)) {
-                               const char *rport = NULL;
-                               switch_port_t remote_rtcp_port = 0;
-
-                               if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) {
-                                       remote_rtcp_port = (switch_port_t)atoi(rport);
-                               }
-
-
-                               if (switch_rtp_set_remote_address(tech_pvt->video_rtp_session, tech_pvt->remote_sdp_video_ip,
-                                                                                                 tech_pvt->remote_sdp_video_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err);
-                               } else {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n",
-                                                                         tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port);
-                                       if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) &&
-                                               !((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
-                                               /* Reactivate the NAT buster flag. */
-                                               switch_rtp_set_flag(tech_pvt->video_rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
-                                       }
-                                       if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)) {
-                                               tech_pvt->check_frames = 0;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if (switch_rtp_ready(tech_pvt->rtp_session)) {
-               char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session);
-               switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session);
-               const char *rport = NULL;
-               switch_port_t remote_rtcp_port = 0;
-
-               if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && remote_port == tech_pvt->remote_sdp_audio_port) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n",
-                                                         tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
-                       switch_goto_status(SWITCH_STATUS_BREAK, end);
-               }
-
-               if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"))) {
-                       remote_rtcp_port = (switch_port_t)atoi(rport);
-               }
-
-
-               if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip,
-                                                                                 tech_pvt->remote_sdp_audio_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
-                       status = SWITCH_STATUS_GENERR;
-               } else {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n",
-                                                         tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
-                       if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) &&
-                               !((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
-                               /* Reactivate the NAT buster flag. */
-                               switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
-                       }
-                       if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)) {
-                               tech_pvt->check_frames = 0;
-                       }
-                       status = SWITCH_STATUS_SUCCESS;
-               }
-       }
-
- end:
-
-       return status;
-}
-
-
-
 char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix)
 {
        char *extra_headers = NULL;
@@ -1159,7 +839,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
        cid_name = caller_profile->caller_id_name;
        cid_num = caller_profile->caller_id_number;
        sofia_media_tech_prepare_codecs(tech_pvt);
-       sofia_media_check_video_codecs(tech_pvt);
+       switch_core_media_check_video_codecs(tech_pvt->session);
        check_decode(cid_name, session);
        check_decode(cid_num, session);
 
@@ -2416,7 +2096,7 @@ int sofia_recover_callback(switch_core_session_t *session)
                                tech_pvt->pt = tech_pvt->agreed_pt = (switch_payload_t)atoi(tmp);
                        }
                        
-                       sofia_media_tech_set_codec(tech_pvt, 1);
+                       switch_core_media_set_codec(tech_pvt->session, 1, tech_pvt->profile->codec_flags);
 
                        tech_pvt->adv_sdp_audio_ip = tech_pvt->extrtpip = (char *) ip;
                        tech_pvt->adv_sdp_audio_port = tech_pvt->local_sdp_audio_port = (switch_port_t)atoi(port);
index 9176315211ba9d1248f6afff343bfc44b206a8ed..e0cef9e3236071445ea396bbdc61bc6eb97dc3a0 100644 (file)
@@ -183,7 +183,7 @@ void sofia_media_proxy_codec(switch_core_session_t *session, const char *r_sdp)
                                tech_pvt->iananame = switch_core_session_strdup(tech_pvt->session, map->rm_encoding);
                                tech_pvt->rm_rate = map->rm_rate;
                                tech_pvt->codec_ms = ptime;
-                               sofia_media_tech_set_codec(tech_pvt, 0);
+                               switch_core_media_set_codec(tech_pvt->session, 0, tech_pvt->profile->codec_flags);
                                break;
                        }
 
@@ -212,1451 +212,18 @@ uint8_t sofia_media_negotiate_sdp(switch_core_session_t *session, const char *r_
        return t;
 }
 
-
-#if 0
-uint8_t sofia_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp)
-{
-       uint8_t match = 0;
-       switch_payload_t best_te = 0, te = 0, cng_pt = 0;
-       private_object_t *tech_pvt = switch_core_session_get_private(session);
-       sdp_media_t *m;
-       sdp_attribute_t *attr;
-       int first = 0, last = 0;
-       int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0;
-       int sendonly = 0, recvonly = 0;
-       int greedy = 0, x = 0, skip = 0, mine = 0;
-       switch_channel_t *channel = switch_core_session_get_channel(session);
-       const char *val;
-       const char *crypto = NULL;
-       int got_crypto = 0, got_video_crypto = 0, got_audio = 0, got_avp = 0, got_video_avp = 0, got_video_savp = 0, got_savp = 0, got_udptl = 0;
-       int scrooge = 0;
-       sdp_parser_t *parser = NULL;
-       sdp_session_t *sdp;
-       int reneg = 1;
-       const switch_codec_implementation_t **codec_array;
-       int total_codecs;
-
-
-       codec_array = tech_pvt->codecs;
-       total_codecs = tech_pvt->num_codecs;
-
-
-       if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
-               return 0;
-       }
-
-       if (!(sdp = sdp_session(parser))) {
-               sdp_parser_free(parser);
-               return 0;
-       }
-
-       switch_assert(tech_pvt != NULL);
-
-       greedy = !!sofia_test_media_flag(tech_pvt->profile, SCMF_CODEC_GREEDY);
-       scrooge = !!sofia_test_media_flag(tech_pvt->profile, SCMF_CODEC_SCROOGE);
-
-       if ((val = switch_channel_get_variable(channel, "sip_codec_negotiation"))) {
-               if (!strcasecmp(val, "generous")) {
-                       greedy = 0;
-                       scrooge = 0;
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation overriding sofia inbound-codec-negotiation : generous\n" );
-               } else if (!strcasecmp(val, "greedy")) {
-                       greedy = 1;
-                       scrooge = 0;
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation overriding sofia inbound-codec-negotiation : greedy\n" );
-               } else if (!strcasecmp(val, "scrooge")) {
-                       scrooge = 1;
-                       greedy = 1;
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation overriding sofia inbound-codec-negotiation : scrooge\n" );
-               } else {
-                   switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation ignored invalid value : '%s' \n", val );    
-               }               
-       }
-
-       if ((tech_pvt->origin = switch_core_session_strdup(session, (char *) sdp->sdp_origin->o_username))) {
-
-               if (tech_pvt->profile->auto_rtp_bugs & RTP_BUG_CISCO_SKIP_MARK_BIT_2833) {
-
-                       if (strstr(tech_pvt->origin, "CiscoSystemsSIP-GW-UserAgent")) {
-                               tech_pvt->rtp_bugs |= RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activate Buggy RFC2833 Mode!\n");
-                       }
-               }
-
-               if (tech_pvt->profile->auto_rtp_bugs & RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833) {
-                       if (strstr(tech_pvt->origin, "Sonus_UAC")) {
-                               tech_pvt->rtp_bugs |= RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
-                                                                 "Hello,\nI see you have a Sonus!\n"
-                                                                 "FYI, Sonus cannot follow the RFC on the proper way to send DTMF.\n"
-                                                                 "Sadly, my creator had to spend several hours figuring this out so I thought you'd like to know that!\n"
-                                                                 "Don't worry, DTMF will work but you may want to ask them to fix it......\n");
-                       }
-               }
-       }
-
-       if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_liberal_dtmf")) && switch_true(val)) {
-               sofia_set_flag_locked(tech_pvt, TFLAG_LIBERAL_DTMF);
-       }
-
-       if ((m = sdp->sdp_media) && 
-               (m->m_mode == sdp_sendonly || m->m_mode == sdp_inactive || 
-                (m->m_connections && m->m_connections->c_address && !strcmp(m->m_connections->c_address, "0.0.0.0")))) {
-               sendonly = 2;                   /* global sendonly always wins */
-       }
-
-       for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
-               if (zstr(attr->a_name)) {
-                       continue;
-               }
-
-               if (!strcasecmp(attr->a_name, "sendonly")) {
-                       sendonly = 1;
-                       switch_channel_set_variable(tech_pvt->channel, "media_audio_mode", "recvonly");
-               } else if (!strcasecmp(attr->a_name, "inactive")) {
-                       sendonly = 1;
-                       switch_channel_set_variable(tech_pvt->channel, "media_audio_mode", "inactive");
-               } else if (!strcasecmp(attr->a_name, "recvonly")) {
-                       switch_channel_set_variable(tech_pvt->channel, "media_audio_mode", "sendonly");
-                       recvonly = 1;
-
-                       if (switch_rtp_ready(tech_pvt->rtp_session)) {
-                               switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, 0);
-                               tech_pvt->max_missed_hold_packets = 0;
-                               tech_pvt->max_missed_packets = 0;
-                       } else {
-                               switch_channel_set_variable(tech_pvt->channel, "rtp_timeout_sec", "0");
-                               switch_channel_set_variable(tech_pvt->channel, "rtp_hold_timeout_sec", "0");
-                       }
-               } else if (sendonly < 2 && !strcasecmp(attr->a_name, "sendrecv")) {
-                       sendonly = 0;
-               } else if (!strcasecmp(attr->a_name, "ptime")) {
-                       dptime = atoi(attr->a_value);
-               } else if (!strcasecmp(attr->a_name, "maxptime")) {
-                       dmaxptime = atoi(attr->a_value);
-               }
-       }
-
-       if (sendonly != 1 && recvonly != 1) {
-               switch_channel_set_variable(tech_pvt->channel, "media_audio_mode", NULL);
-       }
-
-
-       if (sofia_test_media_flag(tech_pvt->profile, SCMF_DISABLE_HOLD) ||
-               ((val = switch_channel_get_variable(tech_pvt->channel, "sip_disable_hold")) && switch_true(val))) {
-               sendonly = 0;
-       } else {
-
-               if (!tech_pvt->hold_laps) {
-                       tech_pvt->hold_laps++;
-                       if (sofia_media_toggle_hold(tech_pvt, sendonly)) {
-                               reneg = sofia_test_pflag(tech_pvt->profile, PFLAG_RENEG_ON_HOLD);
-                               
-                               if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_renegotiate_codec_on_hold"))) {
-                                       reneg = switch_true(val);
-                               }
-                       }
-                       
-               }
-       }
-
-       if (reneg) {
-               reneg = sofia_test_pflag(tech_pvt->profile, PFLAG_RENEG_ON_REINVITE);
-               
-               if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_renegotiate_codec_on_reinvite"))) {
-                       reneg = switch_true(val);
-               }
-       }
-
-       if (!reneg && tech_pvt->num_negotiated_codecs) {
-               codec_array = tech_pvt->negotiated_codecs;
-               total_codecs = tech_pvt->num_negotiated_codecs;
-       } else if (reneg) {
-               tech_pvt->num_codecs = 0;
-               sofia_media_tech_prepare_codecs(tech_pvt);
-               codec_array = tech_pvt->codecs;
-               total_codecs = tech_pvt->num_codecs;
-       }
-
-       if (switch_stristr("T38FaxFillBitRemoval:", r_sdp) || switch_stristr("T38FaxTranscodingMMR:", r_sdp) || 
-               switch_stristr("T38FaxTranscodingJBIG:", r_sdp)) {
-               switch_channel_set_variable(tech_pvt->channel, "t38_broken_boolean", "true");
-       }
-
-       switch_core_media_find_zrtp_hash(session, sdp);
-       switch_core_media_pass_zrtp_hash(session);
-
-       for (m = sdp->sdp_media; m; m = m->m_next) {
-               sdp_connection_t *connection;
-               switch_core_session_t *other_session;
-
-               ptime = dptime;
-               maxptime = dmaxptime;
-
-               if (m->m_proto == sdp_proto_srtp) {
-                       if (m->m_type == sdp_media_audio) {
-                               got_savp++;
-                       } else {
-                               got_video_savp++;
-                       }
-               } else if (m->m_proto == sdp_proto_rtp) {
-                       if (m->m_type == sdp_media_audio) {
-                               got_avp++;
-                       } else {
-                               got_video_avp++;
-                       }
-               } else if (m->m_proto == sdp_proto_udptl) {
-                       got_udptl++;
-               }
-
-               if (got_udptl && m->m_type == sdp_media_image && m->m_port) {
-                       switch_t38_options_t *t38_options = switch_core_media_process_udptl(tech_pvt->session, sdp, m);
-
-                       if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_NEGOTIATED)) {
-                               match = 1;
-                               goto done;
-                       }
-
-                       if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) {
-                               switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
-                               match = 0;
-                               goto done;
-                       } else {
-                               const char *var = switch_channel_get_variable(channel, "t38_passthru");
-                               int pass = sofia_test_pflag(tech_pvt->profile, PFLAG_T38_PASSTHRU);
-
-
-                               if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38)) {
-                                       sofia_set_flag(tech_pvt, TFLAG_NOREPLY);
-                               }
-
-                               if (var) {
-                                       if (!(pass = switch_true(var))) {
-                                               if (!strcasecmp(var, "once")) {
-                                                       pass = 2;
-                                               }
-                                       }
-                               }
-
-                               if ((pass == 2 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU)) || 
-                                       !sofia_test_flag(tech_pvt, TFLAG_REINVITE) ||
-                                       switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || 
-                                       switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) || 
-                                       !switch_rtp_ready(tech_pvt->rtp_session)) {
-                                       pass = 0;
-                               }
-                               
-                               if (pass && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
-                                       private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
-                                       switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
-                                       switch_core_session_message_t *msg;
-                                       char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session);
-                                       switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session);
-                                       char tmp[32] = "";
-
-                                       if (switch_true(switch_channel_get_variable(tech_pvt->channel, "t38_broken_boolean")) && 
-                                               switch_true(switch_channel_get_variable(tech_pvt->channel, "t38_pass_broken_boolean"))) {
-                                               switch_channel_set_variable(other_channel, "t38_broken_boolean", "true");
-                                       }
-                                       
-                                       tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, t38_options->remote_ip);
-                                       tech_pvt->remote_sdp_audio_port = t38_options->remote_port;
-
-                                       if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && remote_port == tech_pvt->remote_sdp_audio_port) {
-                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
-                                                                                 switch_channel_get_name(tech_pvt->channel));
-                                       } else {
-                                               const char *err = NULL;
-
-                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
-                                                                                 switch_channel_get_name(tech_pvt->channel),
-                                                                                 remote_host, remote_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
-                                               
-                                               switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port);
-                                               switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip);
-                                               switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
-
-                                               if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip,
-                                                                                                                 tech_pvt->remote_sdp_audio_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
-                                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
-                                                       switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
-                                               }
-                                               
-                                       }
-
-                                       
-
-                                       sofia_media_copy_t38_options(t38_options, other_session);
-
-                                       sofia_set_flag(tech_pvt, TFLAG_T38_PASSTHRU);
-                                       sofia_set_flag(other_tech_pvt, TFLAG_T38_PASSTHRU);
-
-                                       msg = switch_core_session_alloc(other_session, sizeof(*msg));
-                                       msg->message_id = SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA;
-                                       msg->from = __FILE__;
-                                       msg->string_arg = switch_core_session_strdup(other_session, r_sdp);
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing T38 req to other leg.\n%s\n", r_sdp);
-                                       switch_core_session_queue_message(other_session, msg);
-                                       switch_core_session_rwunlock(other_session);
-                               }
-                       }
-
-
-                       /* do nothing here, mod_fax will trigger a response (if it's listening =/) */
-                       match = 1;
-                       goto done;
-               } else if (m->m_type == sdp_media_audio && m->m_port && !got_audio) {
-                       sdp_rtpmap_t *map;
-
-                       for (attr = m->m_attributes; attr; attr = attr->a_next) {
-
-                               if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) {
-                                       switch_channel_set_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port", attr->a_value);
-                               } else if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
-                                       ptime = atoi(attr->a_value);
-                               } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) {
-                                       maxptime = atoi(attr->a_value);
-                               } else if (!got_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
-                                       int crypto_tag;
-
-                                       if (!(tech_pvt->profile->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) && 
-                                               !switch_true(switch_channel_get_variable(tech_pvt->channel, "sip_allow_crypto_in_avp"))) {
-                                               if (m->m_proto != sdp_proto_srtp) {
-                                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n");
-                                                       match = 0;
-                                                       goto done;
-                                               }
-                                       }
-
-                                       crypto = attr->a_value;
-                                       crypto_tag = atoi(crypto);
-
-                                       got_crypto = switch_core_session_check_incoming_crypto(tech_pvt->session, 
-                                                                                                                                                  SOFIA_HAS_CRYPTO_VARIABLE, SWITCH_MEDIA_TYPE_AUDIO, crypto, crypto_tag);
-
-                               }
-                       }
-
-                       if (got_crypto && !got_avp) {
-                               switch_channel_set_variable(tech_pvt->channel, SOFIA_CRYPTO_MANDATORY_VARIABLE, "true");
-                               switch_channel_set_variable(tech_pvt->channel, SOFIA_SECURE_MEDIA_VARIABLE, "true");
-                       }
-
-                       connection = sdp->sdp_connection;
-                       if (m->m_connections) {
-                               connection = m->m_connections;
-                       }
-
-                       if (!connection) {
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
-                               match = 0;
-                               break;
-                       }
-
-               greed:
-                       x = 0;
-
-                       if (tech_pvt->rm_encoding && !(sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF))) {     // && !sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
-                               char *remote_host = tech_pvt->remote_sdp_audio_ip;
-                               switch_port_t remote_port = tech_pvt->remote_sdp_audio_port;
-                               int same = 0;
-
-                               if (switch_rtp_ready(tech_pvt->rtp_session)) {
-                                       remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session);
-                                       remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session);
-                               }
-
-                               for (map = m->m_rtpmaps; map; map = map->rm_next) {
-                                       if ((zstr(map->rm_encoding) || (tech_pvt->profile->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
-                                               match = (map->rm_pt == tech_pvt->pt) ? 1 : 0;
-                                       } else {
-                                               match = strcasecmp(switch_str_nil(map->rm_encoding), tech_pvt->iananame) ? 0 : 1;
-                                       }
-
-                                       if (match && connection->c_address && remote_host && !strcmp(connection->c_address, remote_host) && m->m_port == remote_port) {
-                                               same = 1;
-                                       } else {
-                                               same = 0;
-                                               break;
-                                       }
-                               }
-
-                               if (same) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
-                                                                         "Our existing sdp is still good [%s %s:%d], let's keep it.\n",
-                                                                         tech_pvt->rm_encoding, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
-                                       got_audio = 1;
-                               } else {
-                                       match = 0;
-                                       got_audio = 0;
-                               }
-                       }
-
-                       for (map = m->m_rtpmaps; map; map = map->rm_next) {
-                               int32_t i;
-                               uint32_t near_rate = 0;
-                               const switch_codec_implementation_t *mimp = NULL, *near_match = NULL;
-                               const char *rm_encoding;
-                               uint32_t map_bit_rate = 0;
-                               int codec_ms = 0;
-                               switch_codec_fmtp_t codec_fmtp = { 0 };
-
-                               if (x++ < skip) {
-                                       continue;
-                               }
-
-                               if (!(rm_encoding = map->rm_encoding)) {
-                                       rm_encoding = "";
-                               }
-
-                               if (!strcasecmp(rm_encoding, "telephone-event")) {
-                                       if (!best_te || map->rm_rate == tech_pvt->rm_rate) {
-                                               best_te = (switch_payload_t) map->rm_pt;
-                                       }
-                               }
-                               
-                               if (!sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG) && !cng_pt && !strcasecmp(rm_encoding, "CN")) {
-                                       cng_pt = (switch_payload_t) map->rm_pt;
-                                       if (tech_pvt->rtp_session) {
-                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", cng_pt);
-                                               switch_rtp_set_cng_pt(tech_pvt->rtp_session, tech_pvt->cng_pt);
-                                       }
-                               }
-
-                               if (match) {
-                                       continue;
-                               }
-
-                               if (greedy) {
-                                       first = mine;
-                                       last = first + 1;
-                               } else {
-                                       first = 0;
-                                       last = tech_pvt->num_codecs;
-                               }
-
-                               codec_ms = ptime;
-
-                               if (maxptime && (!codec_ms || codec_ms > maxptime)) {
-                                       codec_ms = maxptime;
-                               }
-
-                               if (!codec_ms) {
-                                       codec_ms = switch_default_ptime(rm_encoding, map->rm_pt);
-                               }
-
-                               map_bit_rate = switch_known_bitrate((switch_payload_t)map->rm_pt);
-                               
-                               if (!ptime && !strcasecmp(map->rm_encoding, "g723")) {
-                                       codec_ms = 30;
-                               }
-                               
-                               if (zstr(map->rm_fmtp)) {
-                                       if (!strcasecmp(map->rm_encoding, "ilbc")) {
-                                               codec_ms = 30;
-                                               map_bit_rate = 13330;
-                                       }
-                               } else {
-                                       if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) {
-                                               if (codec_fmtp.bits_per_second) {
-                                                       map_bit_rate = codec_fmtp.bits_per_second;
-                                               }
-                                               if (codec_fmtp.microseconds_per_packet) {
-                                                       codec_ms = (codec_fmtp.microseconds_per_packet / 1000);
-                                               }
-                                       }
-                               }
-
-                               
-                               for (i = first; i < last && i < total_codecs; i++) {
-                                       const switch_codec_implementation_t *imp = codec_array[i];
-                                       uint32_t bit_rate = imp->bits_per_second;
-                                       uint32_t codec_rate = imp->samples_per_second;
-                                       if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
-                                               continue;
-                                       }
-
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d:%u]/[%s:%d:%u:%d:%u]\n",
-                                                                         rm_encoding, map->rm_pt, (int) map->rm_rate, codec_ms, map_bit_rate,
-                                                                         imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate);
-                                       if ((zstr(map->rm_encoding) || (tech_pvt->profile->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
-                                               match = (map->rm_pt == imp->ianacode) ? 1 : 0;
-                                       } else {
-                                               match = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1;
-                                       }
-
-                                       if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding, "ilbc")) {
-                                               /* if a bit rate is specified and doesn't match, this is not a codec match, except for ILBC */
-                                               match = 0;
-                                       }
-
-                                       if (match && map->rm_rate && codec_rate && map->rm_rate != codec_rate && (!strcasecmp(map->rm_encoding, "pcma") || !strcasecmp(map->rm_encoding, "pcmu"))) {
-                                               /* if the sampling rate is specified and doesn't match, this is not a codec match for G.711 */
-                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sampling rates have to match for G.711\n");
-                                               match = 0;
-                                       }
-                                       
-                                       if (match) {
-                                               if (scrooge) {
-                                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
-                                                                                         "Bah HUMBUG! Sticking with %s@%uh@%ui\n",
-                                                                                         imp->iananame, imp->samples_per_second, imp->microseconds_per_packet / 1000);
-                                               } else {
-                                                       if ((ptime && codec_ms && codec_ms * 1000 != imp->microseconds_per_packet) || map->rm_rate != codec_rate) {
-                                                               near_rate = map->rm_rate;
-                                                               near_match = imp;
-                                                               match = 0;
-                                                               continue;
-                                                       }
-                                               }
-                                               mimp = imp;
-                                               break;
-                                       }
-                               }
-
-                               if (!match && near_match) {
-                                       const switch_codec_implementation_t *search[1];
-                                       char *prefs[1];
-                                       char tmp[80];
-                                       int num;
-
-                                       switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui", near_match->iananame, near_rate ? near_rate : near_match->samples_per_second,
-                                                                       codec_ms);
-
-                                       prefs[0] = tmp;
-                                       num = switch_loadable_module_get_codecs_sorted(search, 1, prefs, 1);
-
-                                       if (num) {
-                                               mimp = search[0];
-                                       } else {
-                                               mimp = near_match;
-                                       }
-
-                                       if (!maxptime || mimp->microseconds_per_packet / 1000 <= maxptime) {
-                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Substituting codec %s@%ui@%uh\n",
-                                                                                 mimp->iananame, mimp->microseconds_per_packet / 1000, mimp->samples_per_second);
-                                               match = 1;
-                                       } else {
-                                               mimp = NULL;
-                                               match = 0;
-                                       }
-
-                               }
-
-                               if (!match && greedy) {
-                                       skip++;
-                                       continue;
-                               }
-
-                               if (mimp) {
-                                       char tmp[50];
-                                       const char *mirror = switch_channel_get_variable(tech_pvt->channel, "rtp_mirror_remote_audio_codec_payload");
-
-                                       tech_pvt->rm_encoding = switch_core_session_strdup(session, (char *) map->rm_encoding);
-                                       tech_pvt->iananame = switch_core_session_strdup(session, (char *) mimp->iananame);
-                                       tech_pvt->pt = (switch_payload_t) map->rm_pt;
-                                       tech_pvt->rm_rate = mimp->samples_per_second;
-                                       tech_pvt->codec_ms = mimp->microseconds_per_packet / 1000;
-                                       tech_pvt->bitrate = mimp->bits_per_second;
-                                       tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(session, (char *) connection->c_address);
-                                       tech_pvt->rm_fmtp = switch_core_session_strdup(session, (char *) map->rm_fmtp);
-                                       tech_pvt->remote_sdp_audio_port = (switch_port_t) m->m_port;
-                                       tech_pvt->agreed_pt = (switch_payload_t) map->rm_pt;
-                                       tech_pvt->num_negotiated_codecs = 0;
-                                       tech_pvt->negotiated_codecs[tech_pvt->num_negotiated_codecs++] = mimp;
-                                       switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port);
-                                       switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip);
-                                       switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
-                                       tech_pvt->audio_recv_pt = (switch_payload_t)map->rm_pt;
-                                       
-                                       if (!switch_true(mirror) && 
-                                               switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && 
-                                               (!sofia_test_flag(tech_pvt, TFLAG_REINVITE) || sofia_test_pflag(tech_pvt->profile, PFLAG_RENEG_ON_REINVITE))) {
-                                               sofia_media_get_offered_pt(tech_pvt, mimp, &tech_pvt->audio_recv_pt);
-                                       }
-                                       
-                                       switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->audio_recv_pt);
-                                       switch_channel_set_variable(tech_pvt->channel, "rtp_audio_recv_pt", tmp);
-                                       
-                               }
-                               
-                               if (match) {
-                                       if (sofia_media_tech_set_codec(tech_pvt, 1) == SWITCH_STATUS_SUCCESS) {
-                                               got_audio = 1;
-                                       } else {
-                                               match = 0;
-                                       }
-                               }
-                       }
-
-                       if (!best_te && (sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF))) {
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
-                                                                 "No 2833 in SDP. Liberal DTMF mode adding %d as telephone-event.\n", tech_pvt->profile->te);
-                               best_te = tech_pvt->profile->te;
-                       }
-
-                       if (best_te) {
-                               if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
-                                       te = tech_pvt->te = (switch_payload_t) best_te;
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", best_te);
-                                       if (tech_pvt->rtp_session) {
-                                               switch_rtp_set_telephony_event(tech_pvt->rtp_session, (switch_payload_t) best_te);
-                                               switch_channel_set_variable_printf(tech_pvt->channel, "sip_2833_send_payload", "%d", best_te);
-                                       }
-                               } else {
-                                       te = tech_pvt->recv_te = tech_pvt->te = (switch_payload_t) best_te;
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send/recv payload to %u\n", te);
-                                       if (tech_pvt->rtp_session) {
-                                               switch_rtp_set_telephony_event(tech_pvt->rtp_session, te);
-                                               switch_channel_set_variable_printf(tech_pvt->channel, "sip_2833_send_payload", "%d", te);
-                                               switch_rtp_set_telephony_recv_event(tech_pvt->rtp_session, te);
-                                               switch_channel_set_variable_printf(tech_pvt->channel, "sip_2833_recv_payload", "%d", te);
-                                       }
-                               }
-                       } else {
-                               /* by default, use SIP INFO if 2833 is not in the SDP */
-                               if (!switch_false(switch_channel_get_variable(channel, "sip_info_when_no_2833"))) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No 2833 in SDP.  Disable 2833 dtmf and switch to INFO\n");
-                                       switch_channel_set_variable(tech_pvt->channel, "dtmf_type", "info");
-                                       tech_pvt->dtmf_type = DTMF_INFO;
-                                       te = tech_pvt->recv_te = tech_pvt->te = 0;
-                               } else {
-                                       switch_channel_set_variable(tech_pvt->channel, "dtmf_type", "none");
-                                       tech_pvt->dtmf_type = DTMF_NONE;
-                                       te = tech_pvt->recv_te = tech_pvt->te = 0;
-                               }
-                       }
-
-                       
-                       if (!match && greedy && mine < total_codecs) {
-                               mine++;
-                               skip = 0;
-                               goto greed;
-                       }
-
-               } else if (m->m_type == sdp_media_video && m->m_port) {
-                       sdp_rtpmap_t *map;
-                       const char *rm_encoding;
-                       const switch_codec_implementation_t *mimp = NULL;
-                       int vmatch = 0, i;
-                       switch_channel_set_variable(tech_pvt->channel, "video_possible", "true");
-
-                       connection = sdp->sdp_connection;
-                       if (m->m_connections) {
-                               connection = m->m_connections;
-                       }
-
-                       if (!connection) {
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
-                               match = 0;
-                               break;
-                       }
-
-                       for (map = m->m_rtpmaps; map; map = map->rm_next) {
-
-                               for (attr = m->m_attributes; attr; attr = attr->a_next) {
-                                       if (!strcasecmp(attr->a_name, "framerate") && attr->a_value) {
-                                               //framerate = atoi(attr->a_value);
-                                       }
-                                       if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) {
-                                               switch_channel_set_variable(tech_pvt->channel, "sip_remote_video_rtcp_port", attr->a_value);
-
-                                       } else if (!got_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
-                                               int crypto_tag;
-                                               
-                                               if (!(tech_pvt->profile->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) && 
-                                                       !switch_true(switch_channel_get_variable(tech_pvt->channel, "sip_allow_crypto_in_avp"))) {
-                                                       if (m->m_proto != sdp_proto_srtp) {
-                                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n");
-                                                               match = 0;
-                                                               goto done;
-                                                       }
-                                               }
-                                               
-                                               crypto = attr->a_value;
-                                               crypto_tag = atoi(crypto);
-                                               
-                                               got_video_crypto = switch_core_session_check_incoming_crypto(tech_pvt->session, 
-                                                                                                                                                                        SOFIA_HAS_VIDEO_CRYPTO_VARIABLE, 
-                                                                                                                                                                        SWITCH_MEDIA_TYPE_VIDEO, crypto, crypto_tag);
-                                       
-                                       }
-                               }
-
-                               if (got_video_crypto && !got_video_avp) {
-                                       switch_channel_set_variable(tech_pvt->channel, SOFIA_CRYPTO_MANDATORY_VARIABLE, "true");
-                                       switch_channel_set_variable(tech_pvt->channel, SOFIA_SECURE_MEDIA_VARIABLE, "true");
-                               }
-
-                               if (!(rm_encoding = map->rm_encoding)) {
-                                       rm_encoding = "";
-                               }
-
-                               for (i = 0; i < total_codecs; i++) {
-                                       const switch_codec_implementation_t *imp = codec_array[i];
-
-                                       if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
-                                               continue;
-                                       }
-
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d]/[%s:%d]\n",
-                                                                         rm_encoding, map->rm_pt, imp->iananame, imp->ianacode);
-                                       if ((zstr(map->rm_encoding) || (tech_pvt->profile->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
-                                               vmatch = (map->rm_pt == imp->ianacode) ? 1 : 0;
-                                       } else {
-                                               vmatch = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1;
-                                       }
-
-
-                                       if (vmatch && (map->rm_rate == imp->samples_per_second)) {
-                                               mimp = imp;
-                                               break;
-                                       } else {
-                                               vmatch = 0;
-                                       }
-                               }
-
-                               if (mimp) {
-                                       if ((tech_pvt->video_rm_encoding = switch_core_session_strdup(session, (char *) rm_encoding))) {
-                                               char tmp[50];
-                                               const char *mirror = switch_channel_get_variable(tech_pvt->channel, "sip_mirror_remote_video_codec_payload");
-
-                                               tech_pvt->video_pt = (switch_payload_t) map->rm_pt;
-                                               tech_pvt->video_rm_rate = map->rm_rate;
-                                               tech_pvt->video_codec_ms = mimp->microseconds_per_packet / 1000;
-                                               tech_pvt->remote_sdp_video_ip = switch_core_session_strdup(session, (char *) connection->c_address);
-                                               tech_pvt->video_rm_fmtp = switch_core_session_strdup(session, (char *) map->rm_fmtp);
-                                               tech_pvt->remote_sdp_video_port = (switch_port_t) m->m_port;
-                                               tech_pvt->video_agreed_pt = (switch_payload_t) map->rm_pt;
-                                               switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_video_port);
-                                               switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_VIDEO_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip);
-                                               switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_VIDEO_PORT_VARIABLE, tmp);
-                                               switch_channel_set_variable(tech_pvt->channel, "sip_video_fmtp", tech_pvt->video_rm_fmtp);
-                                               switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->video_agreed_pt);
-                                               switch_channel_set_variable(tech_pvt->channel, "sip_video_pt", tmp);
-                                               sofia_media_check_video_codecs(tech_pvt);
-
-                                               tech_pvt->video_recv_pt = (switch_payload_t)map->rm_pt;
-                                               
-                                               if (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
-                                                       sofia_media_get_offered_pt(tech_pvt, mimp, &tech_pvt->video_recv_pt);
-                                               }
-
-                                               switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->video_recv_pt);
-                                               switch_channel_set_variable(tech_pvt->channel, "sip_video_recv_pt", tmp);
-                                               if (!match && vmatch) match = 1;
-
-                                               break;
-                                       } else {
-                                               vmatch = 0;
-                                       }
-                               }
-                       }
-               }
-       }
-
- done:
-
-       if (parser) {
-               sdp_parser_free(parser);
-       }
-
-       tech_pvt->cng_pt = cng_pt;
-       sofia_set_flag_locked(tech_pvt, TFLAG_SDP);
-
-       return match;
-}
-#endif
-
-switch_status_t sofia_media_activate_rtp(private_object_t *tech_pvt)
-{
-       const char *err = NULL;
-       const char *val = NULL;
-       switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0};
-       switch_status_t status = SWITCH_STATUS_SUCCESS;
-       char tmp[50];
-       uint32_t rtp_timeout_sec = tech_pvt->profile->rtp_timeout_sec;
-       uint32_t rtp_hold_timeout_sec = tech_pvt->profile->rtp_hold_timeout_sec;
-       char *timer_name = NULL;
-       const char *var;
-       uint32_t delay = tech_pvt->profile->rtp_digit_delay;
-
-       switch_assert(tech_pvt != NULL);
-
-       if (switch_channel_down(tech_pvt->channel) || sofia_test_flag(tech_pvt, TFLAG_BYE)) {
-               return SWITCH_STATUS_FALSE;
-       }
+switch_status_t sofia_media_activate_rtp(private_object_t *tech_pvt)
+{
+       int ok;
 
        switch_mutex_lock(tech_pvt->sofia_mutex);
+       switch_mutex_unlock(tech_pvt->sofia_mutex);
 
-       if (switch_rtp_ready(tech_pvt->rtp_session)) {
-               switch_rtp_reset_media_timer(tech_pvt->rtp_session);
-       }
-
-       if ((var = switch_channel_get_variable(tech_pvt->channel, SOFIA_SECURE_MEDIA_VARIABLE)) && switch_true(var)) {
-               switch_channel_set_flag(tech_pvt->channel, CF_SECURE);
-       }
-
-       if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE)) {
-               status = SWITCH_STATUS_SUCCESS;
-               goto end;
-       }
-
-
-       if (!sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
-               if (switch_rtp_ready(tech_pvt->rtp_session)) {
-                       if (switch_channel_test_flag(tech_pvt->channel, CF_VIDEO_POSSIBLE) && !switch_rtp_ready(tech_pvt->video_rtp_session)) {
-                               goto video;
-                       }
-
-                       status = SWITCH_STATUS_SUCCESS;
-                       goto end;
-               } 
-       }
-
-       if ((status = sofia_media_tech_set_codec(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
-               goto end;
-       }
-
-       memset(flags, 0, sizeof(flags));
-       flags[SWITCH_RTP_FLAG_DATAWAIT]++;
-
-       if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) &&
-               !((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
-               flags[SWITCH_RTP_FLAG_AUTOADJ]++;
-       }
-
-
-       if (sofia_test_pflag(tech_pvt->profile, PFLAG_PASS_RFC2833)
-               || ((val = switch_channel_get_variable(tech_pvt->channel, "pass_rfc2833")) && switch_true(val))) {
-               sofia_set_flag(tech_pvt, TFLAG_PASS_RFC2833);
-       }
-
-
-       if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTOFLUSH)
-               || ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_autoflush")) && switch_true(val))) {
-               flags[SWITCH_RTP_FLAG_AUTOFLUSH]++;
-       }
-
-       if (!(sofia_test_pflag(tech_pvt->profile, PFLAG_REWRITE_TIMESTAMPS) ||
-                 ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_rewrite_timestamps")) && switch_true(val)))) {
-               flags[SWITCH_RTP_FLAG_RAW_WRITE]++;
-       }
-
-       if (sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG)) {
-               tech_pvt->cng_pt = 0;
-       } else if (tech_pvt->cng_pt) {
-               flags[SWITCH_RTP_FLAG_AUTO_CNG]++;
-       }
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-       if (!strcasecmp(tech_pvt->read_impl.iananame, "L16")) {
-               flags[SWITCH_RTP_FLAG_BYTESWAP]++;
-       }
-#endif
-       
-       if ((flags[SWITCH_RTP_FLAG_BYTESWAP]) && (val = switch_channel_get_variable(tech_pvt->channel, "rtp_disable_byteswap")) && switch_true(val)) {
-               flags[SWITCH_RTP_FLAG_BYTESWAP] = 0;
-       }
-
-       if (tech_pvt->rtp_session && sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
-               //const char *ip = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
-               //const char *port = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
-               char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session);
-               switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session);
-
-               if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && remote_port == tech_pvt->remote_sdp_audio_port) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
-                                                         switch_channel_get_name(tech_pvt->channel));
-                       if (switch_rtp_ready(tech_pvt->rtp_session)) {
-                               if (tech_pvt->audio_recv_pt != tech_pvt->agreed_pt) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, 
-                                                                 "%s Set audio receive payload in Re-INVITE for non-matching dynamic PT to %u\n", 
-                                                                         switch_channel_get_name(tech_pvt->channel), tech_pvt->audio_recv_pt);
-                               
-                                       switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->audio_recv_pt);
-                               } else {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, 
-                                                                 "%s Setting audio receive payload in Re-INVITE to %u\n", 
-                                                                         switch_channel_get_name(tech_pvt->channel), tech_pvt->audio_recv_pt);
-                                       switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->agreed_pt);
-                               }
-
-                       }
-                       goto video;
-               } else {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
-                                                         switch_channel_get_name(tech_pvt->channel),
-                                                         remote_host, remote_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
-
-                       switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port);
-                       switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip);
-                       switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
-               }
-       }
-
-       if (!switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "AUDIO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n",
-                                                 switch_channel_get_name(tech_pvt->channel),
-                                                 tech_pvt->local_sdp_audio_ip,
-                                                 tech_pvt->local_sdp_audio_port,
-                                                 tech_pvt->remote_sdp_audio_ip,
-                                                 tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000);
-
-               if (switch_rtp_ready(tech_pvt->rtp_session)) {
-                       switch_rtp_set_default_payload(tech_pvt->rtp_session, tech_pvt->agreed_pt);
-
-                       if (tech_pvt->audio_recv_pt != tech_pvt->agreed_pt) {
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, 
-                                                                 "%s Set audio receive payload to %u\n", switch_channel_get_name(tech_pvt->channel), tech_pvt->audio_recv_pt);
-                               
-                               switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->audio_recv_pt);
-                       } else {
-                               switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->agreed_pt);
-                       }
-
-               }
-       }
-
-       switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->local_sdp_audio_port);
-       switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, tech_pvt->local_sdp_audio_ip);
-       switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, tmp);
-       switch_channel_set_variable(tech_pvt->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip);
-
-       if (tech_pvt->rtp_session && sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
-               const char *rport = NULL;
-               switch_port_t remote_rtcp_port = 0;
-
-               
-
-               if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"))) {
-                       remote_rtcp_port = (switch_port_t)atoi(rport);
-               }
-
-               if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port,
-                                                                                 remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
-               } else {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n",
-                                                         tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
-                       if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) &&
-                               !((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
-                               /* Reactivate the NAT buster flag. */
-                               switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
-                       }
-               }
-               goto video;
-       }
-
-       if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
-               sofia_glue_tech_proxy_remote_addr(tech_pvt, NULL);
-
-               memset(flags, 0, sizeof(flags));
-               flags[SWITCH_RTP_FLAG_DATAWAIT]++;
-               flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
-
-               if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) &&
-                       !((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
-                       flags[SWITCH_RTP_FLAG_AUTOADJ]++;
-               }
-               timer_name = NULL;
-
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
-                                                 "PROXY AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
-                                                 switch_channel_get_name(tech_pvt->channel),
-                                                 tech_pvt->local_sdp_audio_ip,
-                                                 tech_pvt->local_sdp_audio_port,
-                                                 tech_pvt->remote_sdp_audio_ip,
-                                                 tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000);
-
-               if (switch_rtp_ready(tech_pvt->rtp_session)) {
-                       switch_rtp_set_default_payload(tech_pvt->rtp_session, tech_pvt->agreed_pt);
-               }
-
-       } else {
-               timer_name = tech_pvt->profile->timer_name;
-
-               if ((var = switch_channel_get_variable(tech_pvt->channel, "rtp_timer_name"))) {
-                       timer_name = (char *) var;
-               }
-       }
-
-       if (switch_channel_up(tech_pvt->channel) && !sofia_test_flag(tech_pvt, TFLAG_BYE)) {
-               tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip,
-                                                                                          tech_pvt->local_sdp_audio_port,
-                                                                                          tech_pvt->remote_sdp_audio_ip,
-                                                                                          tech_pvt->remote_sdp_audio_port,
-                                                                                          tech_pvt->agreed_pt,
-                                                                                          tech_pvt->read_impl.samples_per_packet,
-                                                                                          tech_pvt->codec_ms * 1000,
-                                                                                          flags, timer_name, &err, switch_core_session_get_pool(tech_pvt->session));
-       }
-
-       if (switch_rtp_ready(tech_pvt->rtp_session)) {
-               uint8_t vad_in = sofia_test_flag(tech_pvt, TFLAG_VAD_IN) ? 1 : 0;
-               uint8_t vad_out = sofia_test_flag(tech_pvt, TFLAG_VAD_OUT) ? 1 : 0;
-               uint8_t inb = sofia_test_flag(tech_pvt, TFLAG_OUTBOUND) ? 0 : 1;
-               uint32_t stun_ping = 0;
-               const char *ssrc;
-
-               switch_core_media_set_rtp_session(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, tech_pvt->rtp_session);
-
-
-               if ((ssrc = switch_channel_get_variable(tech_pvt->channel, "rtp_use_ssrc"))) {
-                       uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10);
-                       switch_rtp_set_ssrc(tech_pvt->rtp_session, ssrc_ul);
-               }
-
-
-               switch_channel_set_flag(tech_pvt->channel, CF_FS_RTP);
-
-               switch_channel_set_variable_printf(tech_pvt->channel, "sip_use_pt", "%d", tech_pvt->agreed_pt);
-
-               if ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_enable_vad_in")) && switch_true(val)) {
-                       vad_in = 1;
-               }
-               if ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_enable_vad_out")) && switch_true(val)) {
-                       vad_out = 1;
-               }
-
-               if ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_disable_vad_in")) && switch_true(val)) {
-                       vad_in = 0;
-               }
-               if ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_disable_vad_out")) && switch_true(val)) {
-                       vad_out = 0;
-               }
-
-               if ((tech_pvt->stun_flags & STUN_FLAG_SET) && (val = switch_channel_get_variable(tech_pvt->channel, "rtp_stun_ping"))) {
-                       int ival = atoi(val);
-
-                       if (ival <= 0) {
-                               if (switch_true(val)) {
-                                       ival = 6;
-                               }
-                       }
-
-                       stun_ping = (ival * tech_pvt->read_impl.samples_per_second) / tech_pvt->read_impl.samples_per_packet;
-               }
-
-               tech_pvt->ssrc = switch_rtp_get_ssrc(tech_pvt->rtp_session);
-               switch_channel_set_variable_printf(tech_pvt->channel, "rtp_use_ssrc", "%u", tech_pvt->ssrc);
-
+       if (ok) {
                sofia_set_flag(tech_pvt, TFLAG_RTP);
                sofia_set_flag(tech_pvt, TFLAG_IO);
-
-               if (tech_pvt->profile->auto_rtp_bugs & RTP_BUG_IGNORE_MARK_BIT) {
-                       tech_pvt->rtp_bugs |= RTP_BUG_IGNORE_MARK_BIT;
-               }
-
-               if ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_manual_rtp_bugs"))) {
-                       switch_core_media_parse_rtp_bugs(&tech_pvt->rtp_bugs, val);
-               }
-
-               switch_rtp_intentional_bugs(tech_pvt->rtp_session, tech_pvt->rtp_bugs | tech_pvt->profile->manual_rtp_bugs);
-
-               if ((vad_in && inb) || (vad_out && !inb)) {
-                       switch_rtp_enable_vad(tech_pvt->rtp_session, tech_pvt->session, &tech_pvt->read_codec, SWITCH_VAD_FLAG_TALKING | SWITCH_VAD_FLAG_EVENTS_TALK | SWITCH_VAD_FLAG_EVENTS_NOTALK);
-                       sofia_set_flag(tech_pvt, TFLAG_VAD);
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "AUDIO RTP Engage VAD for %s ( %s %s )\n",
-                                                         switch_channel_get_name(switch_core_session_get_channel(tech_pvt->session)), vad_in ? "in" : "", vad_out ? "out" : "");
-               }
-
-               if (stun_ping) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Setting stun ping to %s:%d\n", tech_pvt->stun_ip,
-                                                         stun_ping);
-                       switch_rtp_activate_stun_ping(tech_pvt->rtp_session, tech_pvt->stun_ip, tech_pvt->stun_port, stun_ping,
-                                                                                 (tech_pvt->stun_flags & STUN_FLAG_FUNNY) ? 1 : 0);
-               }
-
-               if ((val = switch_channel_get_variable(tech_pvt->channel, "rtcp_audio_interval_msec")) || (val = tech_pvt->profile->rtcp_audio_interval_msec)) {
-                       const char *rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port");
-                       switch_port_t remote_port = 0;
-                       if (rport) {
-                               remote_port = (switch_port_t)atoi(rport);
-                       }
-                       if (!strcasecmp(val, "passthru")) {
-                               switch_rtp_activate_rtcp(tech_pvt->rtp_session, -1, remote_port);
-                       } else {
-                               int interval = atoi(val);
-                               if (interval < 100 || interval > 5000) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR,
-                                                                         "Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval);
-                               } else {
-                                       switch_rtp_activate_rtcp(tech_pvt->rtp_session, interval, remote_port);
-                               }
-                       }
-               }
-
-               if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec")) || (val = tech_pvt->profile->jb_msec)) {
-                       int jb_msec = atoi(val);
-                       int maxlen = 0, max_drift = 0;
-                       char *p, *q;
-                       
-                       if ((p = strchr(val, ':'))) {
-                               p++;
-                               maxlen = atoi(p);
-                               if ((q = strchr(p, ':'))) {
-                                       q++;
-                                       max_drift = abs(atoi(q));
-                               }
-                       }
-
-                       if (jb_msec < 20 || jb_msec > 10000) {
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR,
-                                                                 "Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", jb_msec);
-                       } else {
-                               int qlen, maxqlen = 50;
-                               
-                               qlen = jb_msec / (tech_pvt->read_impl.microseconds_per_packet / 1000);
-
-                               if (qlen < 1) {
-                                       qlen = 3;
-                               }
-
-                               if (maxlen) {
-                                       maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000);
-                               }
-
-                               if (maxqlen < qlen) {
-                                       maxqlen = qlen * 5;
-                               }
-                               if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen,
-                                                                                                         tech_pvt->read_impl.samples_per_packet, 
-                                                                                                         tech_pvt->read_impl.samples_per_second, max_drift) == SWITCH_STATUS_SUCCESS) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), 
-                                                                         SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
-                                       switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER);
-                                       if (!switch_false(switch_channel_get_variable(tech_pvt->channel, "sip_jitter_buffer_plc"))) {
-                                               switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER_PLC);
-                                       }
-                               } else {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), 
-                                                                         SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
-                               }
-                               
-                       }
-               }
-
-               if ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_timeout_sec"))) {
-                       int v = atoi(val);
-                       if (v >= 0) {
-                               rtp_timeout_sec = v;
-                       }
-               }
-
-               if ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_hold_timeout_sec"))) {
-                       int v = atoi(val);
-                       if (v >= 0) {
-                               rtp_hold_timeout_sec = v;
-                       }
-               }
-
-               if (rtp_timeout_sec) {
-                       tech_pvt->max_missed_packets = (tech_pvt->read_impl.samples_per_second * rtp_timeout_sec) / tech_pvt->read_impl.samples_per_packet;
-
-                       switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, tech_pvt->max_missed_packets);
-                       if (!rtp_hold_timeout_sec) {
-                               rtp_hold_timeout_sec = rtp_timeout_sec * 10;
-                       }
-               }
-
-               if (rtp_hold_timeout_sec) {
-                       tech_pvt->max_missed_hold_packets = (tech_pvt->read_impl.samples_per_second * rtp_hold_timeout_sec) / tech_pvt->read_impl.samples_per_packet;
-               }
-
-               if (tech_pvt->te) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", tech_pvt->te);
-                       switch_rtp_set_telephony_event(tech_pvt->rtp_session, tech_pvt->te);
-                       switch_channel_set_variable_printf(tech_pvt->channel, "sip_2833_send_payload", "%d", tech_pvt->te);
-               }
-
-               if (tech_pvt->recv_te) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set 2833 dtmf receive payload to %u\n", tech_pvt->recv_te);
-                       switch_rtp_set_telephony_recv_event(tech_pvt->rtp_session, tech_pvt->recv_te);
-                       switch_channel_set_variable_printf(tech_pvt->channel, "sip_2833_recv_payload", "%d", tech_pvt->recv_te);
-               }
-
-               if (tech_pvt->audio_recv_pt != tech_pvt->agreed_pt) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, 
-                                                         "%s Set audio receive payload to %u\n", switch_channel_get_name(tech_pvt->channel), tech_pvt->audio_recv_pt);
-
-                       switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->audio_recv_pt);
-               }
-
-               if (sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG) ||
-                       ((val = switch_channel_get_variable(tech_pvt->channel, "supress_cng")) && switch_true(val)) ||
-                       ((val = switch_channel_get_variable(tech_pvt->channel, "suppress_cng")) && switch_true(val))) {
-                       tech_pvt->cng_pt = 0;
-               }
-
-               if (((val = switch_channel_get_variable(tech_pvt->channel, "rtp_digit_delay")))) {
-                       int delayi = atoi(val);
-                       if (delayi < 0) delayi = 0;
-                       delay = (uint32_t) delayi;
-               }
-
-
-               if (delay) {
-                       switch_rtp_set_interdigit_delay(tech_pvt->rtp_session, delay);
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, 
-                                                         "%s Set rtp dtmf delay to %u\n", switch_channel_get_name(tech_pvt->channel), delay);
-                       
-               }
-
-               if (tech_pvt->cng_pt && !sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG)) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", tech_pvt->cng_pt);
-                       switch_rtp_set_cng_pt(tech_pvt->rtp_session, tech_pvt->cng_pt);
-               }
-
-               switch_core_session_apply_crypto(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SOFIA_SECURE_MEDIA_CONFIRMED_VARIABLE);
-
-               switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port);
-               switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip);
-               switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
-
-
-               if (switch_channel_test_flag(tech_pvt->channel, CF_ZRTP_PASSTHRU)) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_INFO, "Activating ZRTP PROXY MODE\n");
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Disable NOTIMER_DURING_BRIDGE\n");
-                       sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Activating audio UDPTL mode\n");
-                       switch_rtp_udptl_mode(tech_pvt->rtp_session);
-               }
-
-
-       video:
-               
-               sofia_media_check_video_codecs(tech_pvt);
-
-               if (switch_channel_test_flag(tech_pvt->channel, CF_VIDEO_POSSIBLE) && tech_pvt->video_rm_encoding && tech_pvt->remote_sdp_video_port) {
-                       /******************************************************************************************/
-                       if (tech_pvt->video_rtp_session && sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
-                               //const char *ip = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
-                               //const char *port = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
-                               char *remote_host = switch_rtp_get_remote_host(tech_pvt->video_rtp_session);
-                               switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->video_rtp_session);
-                               
-
-
-                               if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_video_ip) && remote_port == tech_pvt->remote_sdp_video_port) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Video params are unchanged for %s.\n",
-                                                                         switch_channel_get_name(tech_pvt->channel));
-                                       goto video_up;
-                               } else {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Video params changed for %s from %s:%d to %s:%d\n",
-                                                                         switch_channel_get_name(tech_pvt->channel),
-                                                                         remote_host, remote_port, tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port);
-                               }
-                       }
-
-                       if (!switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
-                                                                 "VIDEO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n", switch_channel_get_name(tech_pvt->channel),
-                                                                 tech_pvt->local_sdp_audio_ip, tech_pvt->local_sdp_video_port, tech_pvt->remote_sdp_video_ip,
-                                                                 tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000);
-
-                               if (switch_rtp_ready(tech_pvt->video_rtp_session)) {
-                                       switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt);
-                               }
-                       }
-                       
-                       switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->local_sdp_video_port);
-                       switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip);
-                       switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp);
-
-
-                       if (tech_pvt->video_rtp_session && sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
-                               const char *rport = NULL;
-                               switch_port_t remote_rtcp_port = 0;
-
-                               sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE);
-
-                               if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) {
-                                       remote_rtcp_port = (switch_port_t)atoi(rport);
-                               }
-                               
-                               if (switch_rtp_set_remote_address
-                                       (tech_pvt->video_rtp_session, tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, remote_rtcp_port, SWITCH_TRUE,
-                                        &err) != SWITCH_STATUS_SUCCESS) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err);
-                               } else {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n",
-                                                                         tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port);
-                                       if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) &&
-                                               !((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
-                                               /* Reactivate the NAT buster flag. */
-                                               switch_rtp_set_flag(tech_pvt->video_rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
-                                       }
-
-                               }
-                               goto video_up;
-                       }
-
-                       if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
-                               sofia_glue_tech_proxy_remote_addr(tech_pvt, NULL);
-
-                               memset(flags, 0, sizeof(flags));
-                               flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
-                               flags[SWITCH_RTP_FLAG_DATAWAIT]++;
-
-                               if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) &&
-                                       !((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
-                                       flags[SWITCH_RTP_FLAG_AUTOADJ]++;
-                               }
-                               timer_name = NULL;
-
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
-                                                                 "PROXY VIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
-                                                                 switch_channel_get_name(tech_pvt->channel),
-                                                                 tech_pvt->local_sdp_audio_ip,
-                                                                 tech_pvt->local_sdp_video_port,
-                                                                 tech_pvt->remote_sdp_video_ip,
-                                                                 tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000);
-
-                               if (switch_rtp_ready(tech_pvt->video_rtp_session)) {
-                                       switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt);
-                               }
-                       } else {
-                               timer_name = tech_pvt->profile->timer_name;
-
-                               if ((var = switch_channel_get_variable(tech_pvt->channel, "rtp_timer_name"))) {
-                                       timer_name = (char *) var;
-                               }
-                       }
-
-                       /******************************************************************************************/
-
-                       if (tech_pvt->video_rtp_session) {
-                               goto video_up;
-                       }
-
-
-                       if (!tech_pvt->local_sdp_video_port) {
-                               sofia_glue_tech_choose_video_port(tech_pvt, 1);
-                       }
-
-                       memset(flags, 0, sizeof(flags));
-                       flags[SWITCH_RTP_FLAG_DATAWAIT]++;
-                       flags[SWITCH_RTP_FLAG_RAW_WRITE]++;
-
-                       if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) &&
-                               !((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
-                               flags[SWITCH_RTP_FLAG_AUTOADJ]++;                               
-                       }
-
-                       if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
-                               flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
-                       }
-                       sofia_media_tech_set_video_codec(tech_pvt, 0);
-
-                       flags[SWITCH_RTP_FLAG_USE_TIMER] = 0;
-                       flags[SWITCH_RTP_FLAG_NOBLOCK] = 0;
-                       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,
-                                                                                                                tech_pvt->remote_sdp_video_ip,
-                                                                                                                tech_pvt->remote_sdp_video_port,
-                                                                                                                tech_pvt->video_agreed_pt,
-                                                                                                                1, 90000, flags, NULL, &err, switch_core_session_get_pool(tech_pvt->session));
-
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%sVIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n",
-                                                         switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) ? "PROXY " : "",
-                                                         switch_channel_get_name(tech_pvt->channel),
-                                                         tech_pvt->local_sdp_audio_ip,
-                                                         tech_pvt->local_sdp_video_port,
-                                                         tech_pvt->remote_sdp_video_ip,
-                                                         tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt,
-                                                         0, switch_rtp_ready(tech_pvt->video_rtp_session) ? "SUCCESS" : err);
-
-
-                       if (switch_rtp_ready(tech_pvt->video_rtp_session)) {
-                               switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt);
-                               switch_core_media_set_rtp_session(tech_pvt->session, SWITCH_MEDIA_TYPE_VIDEO, tech_pvt->video_rtp_session);
-                       }
-
-                       if (switch_rtp_ready(tech_pvt->video_rtp_session)) {
-                               const char *ssrc;
-                               switch_channel_set_flag(tech_pvt->channel, CF_VIDEO);
-                               if ((ssrc = switch_channel_get_variable(tech_pvt->channel, "rtp_use_video_ssrc"))) {
-                                       uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10);
-                                       switch_rtp_set_ssrc(tech_pvt->video_rtp_session, ssrc_ul);
-                               }
-
-
-
-                               if ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_manual_video_rtp_bugs"))) {
-                                       switch_core_media_parse_rtp_bugs(&tech_pvt->video_rtp_bugs, val);
-                               }
-                               
-                               switch_rtp_intentional_bugs(tech_pvt->video_rtp_session, tech_pvt->video_rtp_bugs | tech_pvt->profile->manual_video_rtp_bugs);
-
-                               if (tech_pvt->video_recv_pt != tech_pvt->video_agreed_pt) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, 
-                                                                         "%s Set video receive payload to %u\n", switch_channel_get_name(tech_pvt->channel), tech_pvt->video_recv_pt);
-                                       switch_rtp_set_recv_pt(tech_pvt->video_rtp_session, tech_pvt->video_recv_pt);
-                               }
-
-                               switch_channel_set_variable_printf(tech_pvt->channel, "sip_use_video_pt", "%d", tech_pvt->video_agreed_pt);
-                               tech_pvt->video_ssrc = switch_rtp_get_ssrc(tech_pvt->rtp_session);
-                               switch_channel_set_variable_printf(tech_pvt->channel, "rtp_use_video_ssrc", "%u", tech_pvt->ssrc);
-
-                               switch_core_session_apply_crypto(tech_pvt->session, SWITCH_MEDIA_TYPE_VIDEO, SOFIA_SECURE_VIDEO_CONFIRMED_VARIABLE);
-
-
-                               if ((val = switch_channel_get_variable(tech_pvt->channel, "rtcp_audio_interval_msec"))
-                                       || (val = tech_pvt->profile->rtcp_audio_interval_msec)) {
-                                       const char *rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port");
-                                       switch_port_t remote_port = 0;
-                                       if (rport) {
-                                               remote_port = (switch_port_t)atoi(rport);
-                                       }
-                                       if (!strcasecmp(val, "passthru")) {
-                                               switch_rtp_activate_rtcp(tech_pvt->rtp_session, -1, remote_port);
-                                       } else {
-                                               int interval = atoi(val);
-                                               if (interval < 100 || interval > 5000) {
-                                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR,
-                                                                                         "Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval);
-                                               } else {
-                                                       switch_rtp_activate_rtcp(tech_pvt->rtp_session, interval, remote_port);
-                                               }
-                                       }
-                               }
-                               if (switch_channel_test_flag(tech_pvt->channel, CF_ZRTP_PASSTHRU)) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Activating video UDPTL mode\n");
-                                       switch_rtp_udptl_mode(tech_pvt->video_rtp_session);
-                               }
-
-                       } else {
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", switch_str_nil(err));
-                               switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
-                               goto end;
-                       }
-               }
-
-       } else {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", switch_str_nil(err));
-               switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
-               sofia_clear_flag_locked(tech_pvt, TFLAG_IO);
-               status = SWITCH_STATUS_FALSE;
-               goto end;
        }
 
- video_up:
-
-       sofia_set_flag(tech_pvt, TFLAG_IO);
-       status = SWITCH_STATUS_SUCCESS;
-
- end:
-
-       sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE);
-       switch_core_recovery_track(tech_pvt->session);
-
-       switch_mutex_unlock(tech_pvt->sofia_mutex);
-
-       return status;
-
 }
 
 
@@ -2419,7 +986,7 @@ void sofia_media_set_local_sdp(private_object_t *tech_pvt, const char *ip, switc
 
                        /*****************************/
                        if (tech_pvt->video_rm_encoding) {
-                               sofia_media_tech_set_video_codec(tech_pvt, 0);
+                               switch_core_media_set_video_codec(tech_pvt->session, 0);
                                switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", tech_pvt->video_agreed_pt);
                        } else if (tech_pvt->num_codecs) {
                                int i;
index 18c93e19c5bc6311c414a115e8a21e94833263c5..62b5f10b2164e13ab46916ecb422049ee4da4c4a 100644 (file)
 #include <errno.h>
 
 
-
 #define MAX_CODEC_CHECK_FRAMES 50//x:mod_sofia.h
 #define MAX_MISMATCH_FRAMES 5//x:mod_sofia.h
 
-typedef union {
-       int32_t intval;
-       uint32_t uintval;
-       char *charval;
-} scm_multi_t;
-
-
-static scm_type_t typemap[SCM_MAX] = {
-       /*SCM_INBOUND_CODEC_STRING*/  STYPE_CHARVAL, 
-       /*SCM_OUTBOUND_CODEC_STRING*/ STYPE_CHARVAL,
-       /*SCM_AUTO_RTP_BUGS */ STYPE_INTVAL,
-       /*SCM_MANUAL_RTP_BUGS*/ STYPE_INTVAL
-};
-
 typedef enum {
        SMH_INIT = (1 << 0),
        SMH_READY = (1 << 1)
@@ -82,12 +67,26 @@ typedef struct codec_params_s {//x:tmp
        unsigned long rm_rate;
        uint32_t codec_ms;
        uint32_t bitrate;
-       char *remote_sdp_ip;
+
        char *rm_fmtp;
-       switch_port_t remote_sdp_port;
+
        switch_payload_t agreed_pt;
        switch_payload_t recv_pt;
        char *fmtp_out;
+
+
+       char *remote_sdp_ip;
+       switch_port_t remote_sdp_port;
+
+       char *local_sdp_ip;
+       switch_port_t local_sdp_port;
+
+       char *adv_sdp_ip;
+       switch_port_t adv_sdp_port;
+       char *proxy_sdp_ip;
+       switch_port_t proxy_sdp_port;
+
+
 } codec_params_t;
 
 
@@ -111,8 +110,9 @@ typedef struct switch_rtp_engine_s {
        uint8_t codec_reinvites;//x:tp
        uint32_t max_missed_packets;//x:tp
        uint32_t max_missed_hold_packets;//x:tp
+       uint32_t ssrc;
 
-
+       switch_rtp_bug_flag_t rtp_bugs;
 
        /** ZRTP **/
        char *local_sdp_zrtp_hash;
@@ -120,7 +120,7 @@ typedef struct switch_rtp_engine_s {
 
 
        codec_params_t codec_params;
-
+       uint32_t timestamp_send;
 
 } switch_rtp_engine_t;
 
@@ -128,11 +128,10 @@ typedef struct switch_rtp_engine_s {
 struct switch_media_handle_s {
        switch_core_session_t *session;
        switch_channel_t *channel;
-       switch_core_media_NDLB_t ndlb;
        switch_core_media_flag_t media_flags[SCMF_MAX];
        smh_flag_t flags;
        switch_rtp_engine_t engines[SWITCH_MEDIA_TYPE_TOTAL];
-       scm_multi_t params[SCM_MAX];
+
        char *codec_order[SWITCH_MAX_CODECS];//x:tp
     int codec_order_last;//x:tp
     const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS];//x:tp
@@ -147,62 +146,11 @@ struct switch_media_handle_s {
        const switch_codec_implementation_t *negotiated_codecs[SWITCH_MAX_CODECS];//x:tp
        int num_negotiated_codecs;//x:tp
        switch_payload_t ianacodes[SWITCH_MAX_CODECS];//x:tp
-       int video_count;//x:tmp
+       int video_count;//x:tp
 
+       switch_core_media_params_t *mparams;
 };
 
-SWITCH_DECLARE(void) switch_media_set_param(switch_media_handle_t *smh, scm_param_t param, ...)
-{
-       scm_multi_t *val = &smh->params[param];
-       scm_type_t type = typemap[param];
-       va_list ap;
-
-       va_start(ap, param);
-
-       switch(type) {
-       case STYPE_INTVAL:
-               val->intval = va_arg(ap, int);
-               break;
-       case STYPE_UINTVAL:
-               val->uintval = va_arg(ap, unsigned int);
-               break;
-       case STYPE_CHARVAL:
-               val->charval = switch_core_session_strdup(smh->session, va_arg(ap, char *));
-               break;
-       default:
-               abort();
-       }
-
-       va_end(ap);
-}
-
-SWITCH_DECLARE(void *) switch_media_get_param(switch_media_handle_t *smh, scm_param_t param)
-{
-       scm_multi_t *val = &smh->params[param];
-       scm_type_t type = typemap[param];
-
-       switch(type) {
-       case STYPE_INTVAL:
-               return &val->intval;
-               break;
-       case STYPE_UINTVAL:
-               return &val->uintval;
-               break;
-       case STYPE_CHARVAL:
-               return val->charval;
-               break;
-       default:
-               abort();
-       }
-       
-       return NULL;
-       
-}
-
-#define get_str(_o, _p) _o->params[_p].charval
-
-
-
 static void _switch_core_media_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core_session_t *bleg_session, switch_media_type_t type)
 {
        switch_rtp_engine_t *aleg_engine;
@@ -400,12 +348,12 @@ SWITCH_DECLARE(switch_t38_options_t *) switch_core_media_extract_t38_options(swi
        switch_t38_options_t *t38_options = NULL;
 
        if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
-               return 0;
+               return NULL;
        }
 
        if (!(sdp = sdp_session(parser))) {
                sdp_parser_free(parser);
-               return 0;
+               return NULL;
        }
 
        //switch_assert(tech_pvt != NULL);
@@ -443,12 +391,12 @@ SWITCH_DECLARE(const char *)switch_core_media_get_codec_string(switch_core_sessi
        
                if (!preferred) {
                        if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
-                               preferred = get_str(smh, SCM_OUTBOUND_CODEC_STRING);
-                               fallback = get_str(smh, SCM_INBOUND_CODEC_STRING);
+                               preferred = smh->mparams->outbound_codec_string;
+                               fallback = smh->mparams->inbound_codec_string;
 
                        } else {
-                               preferred = get_str(smh, SCM_INBOUND_CODEC_STRING);
-                               fallback = get_str(smh, SCM_OUTBOUND_CODEC_STRING);
+                               preferred = smh->mparams->inbound_codec_string;
+                               fallback = smh->mparams->outbound_codec_string;
                        }
                }
        }
@@ -604,7 +552,7 @@ static switch_status_t switch_core_media_build_crypto(switch_media_handle_t *smh
        ssec->local_crypto_key = switch_core_session_sprintf(smh->session, "%d %s inline:%s", index, type_str, b64_key);
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "Set Local Key [%s]\n", ssec->local_crypto_key);
 
-       if (!(smh->ndlb & SM_NDLB_DISABLE_SRTP_AUTH) &&
+       if (!(smh->mparams->ndlb & SM_NDLB_DISABLE_SRTP_AUTH) &&
                !((val = switch_channel_get_variable(channel, "NDLB_support_asterisk_missing_srtp_auth")) && switch_true(val))) {
                ssec->crypto_type = type;
        } else {
@@ -819,7 +767,7 @@ SWITCH_DECLARE(void) switch_core_session_check_outgoing_crypto(switch_core_sessi
 }
 
 
-SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t **smhp, switch_core_session_t *session)
+SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t **smhp, switch_core_session_t *session, switch_core_media_params_t *params)
 {
        switch_status_t status = SWITCH_STATUS_FALSE;
        switch_media_handle_t *smh = NULL;
@@ -833,7 +781,7 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t
                session->media_handle->media_flags[SCMF_RUNNING] = 1;
                session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
                session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
-
+               session->media_handle->mparams = params;
                status = SWITCH_STATUS_SUCCESS;
        }
 
@@ -841,27 +789,6 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t
        return status;
 }
 
-SWITCH_DECLARE(void) switch_media_handle_set_ndlb(switch_media_handle_t *smh, switch_core_media_NDLB_t flag)
-{
-       switch_assert(smh);
-
-       smh->ndlb |= flag;
-       
-}
-
-SWITCH_DECLARE(void) switch_media_handle_clear_ndlb(switch_media_handle_t *smh, switch_core_media_NDLB_t flag)
-{
-       switch_assert(smh);
-
-       smh->ndlb &= ~flag;
-}
-
-SWITCH_DECLARE(int32_t) switch_media_handle_test_ndlb(switch_media_handle_t *smh, switch_core_media_NDLB_t flag)
-{
-       switch_assert(smh);
-       return (smh->ndlb & flag);
-}
-
 SWITCH_DECLARE(void) switch_media_handle_set_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag)
 {
        switch_assert(smh);
@@ -991,9 +918,9 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses
 }
 
 
-
-SWITCH_DECLARE(switch_status_t) switch_core_session_read_media_frame(switch_core_session_t *session, switch_frame_t **frame,
-                                                                                                                                        switch_io_flag_t flags, int stream_id, switch_media_type_t type)
+//?
+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)
 {
        switch_rtcp_frame_t rtcp_frame;
        switch_rtp_engine_t *engine;
@@ -1028,14 +955,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_media_frame(switch_core
                if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
                        if (status == SWITCH_STATUS_TIMEOUT) {
 
-#if 0
-                               if (sofia_test_flag(engine, TFLAG_SIP_HOLD)) {
-                                       switch_core_media_toggle_hold(engine, 0);
-                                       sofia_clear_flag_locked(engine, TFLAG_SIP_HOLD);
-                                       switch_channel_clear_flag(channel, CF_LEG_HOLDING);
-                               }
-#endif
-
                                if (switch_channel_get_variable(session->channel, "execute_on_media_timeout")) {
                                        *frame = &engine->read_frame;
                                        switch_set_flag((*frame), SFF_CNG);
@@ -1199,12 +1118,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_media_frame(switch_core
                                                                        engine->codec_ms = codec_ms;
                                                                }
 
-#if fixmeXXXXX
-                                                               if (switch_core_media_tech_set_codec(engine, 2) != SWITCH_STATUS_SUCCESS) {
+
+                                                               if (switch_core_media_set_codec(session, 2, 0) != SWITCH_STATUS_SUCCESS) {
                                                                        *frame = NULL;
                                                                        return SWITCH_STATUS_GENERR;
                                                                }
-#endif
+
                                                                if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) {
                                                                        int v = atoi(val);
                                                                        if (v >= 0) {
@@ -1283,7 +1202,65 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_media_frame(switch_core
        return SWITCH_STATUS_SUCCESS;
 }
 
+//?
+SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_session_t *session, 
+                                                                                                 switch_frame_t *frame, switch_io_flag_t flags, int stream_id, switch_media_type_t type)
+{
+       switch_status_t status = SWITCH_STATUS_SUCCESS;
+       int bytes = 0, samples = 0, frames = 0;
+       switch_rtp_engine_t *engine;
+       switch_media_handle_t *smh;
+
+       if (!(smh = session->media_handle)) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+       if (!(smh->flags & SCMF_RUNNING)) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+       engine = &smh->engines[type];
+
+
+       while (!(engine->read_codec.implementation && switch_rtp_ready(engine->rtp_session))) {
+               if (switch_channel_ready(session->channel)) {
+                       switch_yield(10000);
+               } else {
+                       return SWITCH_STATUS_GENERR;
+               }
+       }
+
+       if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
+               return SWITCH_STATUS_GENERR;
+       }
+
+
+       if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+       if (!switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) {
+               if (engine->read_impl.encoded_bytes_per_packet) {
+                       bytes = engine->read_impl.encoded_bytes_per_packet;
+                       frames = ((int) frame->datalen / bytes);
+               } else
+                       frames = 1;
+
+               samples = frames * engine->read_impl.samples_per_packet;
+       }
+
+       engine->timestamp_send += samples;
+
+       if (!switch_rtp_write_frame(engine->rtp_session, frame)) {
+               status = SWITCH_STATUS_FALSE;
+       }
+
+
+       return status;
+}
+
 
+//?
 SWITCH_DECLARE(void) switch_core_media_copy_t38_options(switch_t38_options_t *t38_options, switch_core_session_t *session)
 {
        switch_channel_t *channel = switch_core_session_get_channel(session);
@@ -1312,7 +1289,7 @@ SWITCH_DECLARE(void) switch_core_media_copy_t38_options(switch_t38_options_t *t3
 
 }
 
-
+//?
 SWITCH_DECLARE(switch_status_t) switch_core_media_get_offered_pt(switch_core_session_t *session, const switch_codec_implementation_t *mimp, switch_payload_t *pt)
 {
        int i = 0;
@@ -1336,8 +1313,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_get_offered_pt(switch_core_ses
        return SWITCH_STATUS_FALSE;
 }
 
+
+
 //?
-switch_status_t switch_core_media_set_video_codec(switch_core_session_t *session, int force)
+SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_session_t *session, int force)
 {
        switch_media_handle_t *smh;
        switch_rtp_engine_t *v_engine;
@@ -1442,7 +1421,7 @@ switch_status_t switch_core_media_set_video_codec(switch_core_session_t *session
 
 
 //?
-switch_status_t switch_core_media_set_codec(switch_core_session_t *session, int force, uint32_t codec_flags)
+SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_t *session, int force, uint32_t codec_flags)
 {
        switch_status_t status = SWITCH_STATUS_SUCCESS;
        int resetting = 0;
@@ -1587,7 +1566,7 @@ switch_status_t switch_core_media_set_codec(switch_core_session_t *session, int
 }
 
 //?
-void switch_core_media_check_video_codecs(switch_core_session_t *session)
+SWITCH_DECLARE(void) switch_core_media_check_video_codecs(switch_core_session_t *session)
 {
        switch_media_handle_t *smh;
 
@@ -1683,17 +1662,17 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 
        if ((smh->origin = switch_core_session_strdup(session, (char *) sdp->sdp_origin->o_username))) {
 
-               if ((smh->params[SCM_AUTO_RTP_BUGS].intval & RTP_BUG_CISCO_SKIP_MARK_BIT_2833)) {
+               if ((smh->mparams->auto_rtp_bugs & RTP_BUG_CISCO_SKIP_MARK_BIT_2833)) {
 
                        if (strstr(smh->origin, "CiscoSystemsSIP-GW-UserAgent")) {
-                               smh->params[SCM_MANUAL_RTP_BUGS].intval |= RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
+                               a_engine->rtp_bugs |= RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activate Buggy RFC2833 Mode!\n");
                        }
                }
 
-               if ((smh->params[SCM_AUTO_RTP_BUGS].intval & RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833)) {
+               if ((smh->mparams->auto_rtp_bugs & RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833)) {
                        if (strstr(smh->origin, "Sonus_UAC")) {
-                               smh->params[SCM_MANUAL_RTP_BUGS].intval |= RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
+                               a_engine->rtp_bugs |= RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
                                                                  "Hello,\nI see you have a Sonus!\n"
                                                                  "FYI, Sonus cannot follow the RFC on the proper way to send DTMF.\n"
@@ -1927,7 +1906,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                                } else if (!got_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
                                        int crypto_tag;
 
-                                       if (!(smh->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) && 
+                                       if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) && 
                                                !switch_true(switch_channel_get_variable(session->channel, "sip_allow_crypto_in_avp"))) {
                                                if (m->m_proto != sdp_proto_srtp) {
                                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n");
@@ -1976,7 +1955,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                                }
 
                                for (map = m->m_rtpmaps; map; map = map->rm_next) {
-                                       if ((zstr(map->rm_encoding) || (smh->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
+                                       if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
                                                match = (map->rm_pt == a_engine->codec_params.pt) ? 1 : 0;
                                        } else {
                                                match = strcasecmp(switch_str_nil(map->rm_encoding), a_engine->codec_params.iananame) ? 0 : 1;
@@ -2088,7 +2067,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d:%u]/[%s:%d:%u:%d:%u]\n",
                                                                          rm_encoding, map->rm_pt, (int) map->rm_rate, codec_ms, map_bit_rate,
                                                                          imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate);
-                                       if ((zstr(map->rm_encoding) || (smh->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
+                                       if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
                                                match = (map->rm_pt == imp->ianacode) ? 1 : 0;
                                        } else {
                                                match = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1;
@@ -2273,7 +2252,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                                        } else if (!got_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
                                                int crypto_tag;
                                                
-                                               if (!(smh->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) && 
+                                               if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) && 
                                                        !switch_true(switch_channel_get_variable(session->channel, "sip_allow_crypto_in_avp"))) {
                                                        if (m->m_proto != sdp_proto_srtp) {
                                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n");
@@ -2310,7 +2289,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d]/[%s:%d]\n",
                                                                          rm_encoding, map->rm_pt, imp->iananame, imp->ianacode);
-                                       if ((zstr(map->rm_encoding) || (smh->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
+                                       if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
                                                vmatch = (map->rm_pt == imp->ianacode) ? 1 : 0;
                                        } else {
                                                vmatch = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1;
@@ -2478,6 +2457,1041 @@ SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session
 }
 
 
+//?
+#define RA_PTR_LEN 512
+SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_session_t *session, const char *sdp_str)
+{
+       const char *err;
+       char rip[RA_PTR_LEN] = "";
+       char rp[RA_PTR_LEN] = "";
+       char rvp[RA_PTR_LEN] = "";
+       char *p, *ip_ptr = NULL, *port_ptr = NULL, *vid_port_ptr = NULL, *pe;
+       int x;
+       const char *val;
+       switch_status_t status = SWITCH_STATUS_FALSE;
+       switch_rtp_engine_t *a_engine, *v_engine;
+       switch_media_handle_t *smh;
+
+       if (!(smh = session->media_handle)) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+       a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
+       v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
+       
+       if (zstr(sdp_str)) {
+               sdp_str = smh->mparams->remote_sdp_str;
+       }
+
+       if (zstr(sdp_str)) {
+               goto end;
+       }
+
+       if ((p = (char *) switch_stristr("c=IN IP4 ", sdp_str)) || (p = (char *) switch_stristr("c=IN IP6 ", sdp_str))) {
+               ip_ptr = p + 9;
+       }
+
+       if ((p = (char *) switch_stristr("m=audio ", sdp_str))) {
+               port_ptr = p + 8;
+       }
+
+       if ((p = (char *) switch_stristr("m=image ", sdp_str))) {
+               char *tmp = p + 8;
+               
+               if (tmp && atoi(tmp)) {
+                       port_ptr = tmp;
+               }
+       }
+
+       if ((p = (char *) switch_stristr("m=video ", sdp_str))) {
+               vid_port_ptr = p + 8;
+       }
+
+       if (!(ip_ptr && port_ptr)) {
+               goto end;
+       }
+
+       p = ip_ptr;
+       pe = p + strlen(p);
+       x = 0;
+       while (x < sizeof(rip) - 1 && p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F'))) {
+               rip[x++] = *p;
+               p++;
+               if (p >= pe) {
+                       goto end;
+               }
+       }
+
+       p = port_ptr;
+       x = 0;
+       while (x < sizeof(rp) - 1 && p && *p && (*p >= '0' && *p <= '9')) {
+               rp[x++] = *p;
+               p++;
+               if (p >= pe) {
+                       goto end;
+               }
+       }
+
+       p = vid_port_ptr;
+       x = 0;
+       while (x < sizeof(rvp) - 1 && p && *p && (*p >= '0' && *p <= '9')) {
+               rvp[x++] = *p;
+               p++;
+               if (p >= pe) {
+                       goto end;
+               }
+       }
+
+       if (!(*rip && *rp)) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "invalid SDP\n");
+               goto end;
+       }
+
+       a_engine->codec_params.remote_sdp_ip = switch_core_session_strdup(session, rip);
+       a_engine->codec_params.remote_sdp_port = (switch_port_t) atoi(rp);
+
+       if (*rvp) {
+               v_engine->codec_params.remote_sdp_ip = switch_core_session_strdup(session, rip);
+               v_engine->codec_params.remote_sdp_port = (switch_port_t) atoi(rvp);
+       }
+
+       if (v_engine->codec_params.remote_sdp_ip && v_engine->codec_params.remote_sdp_port) {
+               if (!strcmp(v_engine->codec_params.remote_sdp_ip, rip) && atoi(rvp) == v_engine->codec_params.remote_sdp_port) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote video address:port [%s:%d] has not changed.\n",
+                                                         v_engine->codec_params.remote_sdp_ip, v_engine->codec_params.remote_sdp_port);
+               } else {
+                       switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE);
+                       switch_channel_set_flag(session->channel, CF_VIDEO);
+                       if (switch_rtp_ready(v_engine->rtp_session)) {
+                               const char *rport = NULL;
+                               switch_port_t remote_rtcp_port = 0;
+
+                               if ((rport = switch_channel_get_variable(session->channel, "sip_remote_video_rtcp_port"))) {
+                                       remote_rtcp_port = (switch_port_t)atoi(rport);
+                               }
+
+
+                               if (switch_rtp_set_remote_address(v_engine->rtp_session, v_engine->codec_params.remote_sdp_ip,
+                                                                                                 v_engine->codec_params.remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err);
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n",
+                                                                         v_engine->codec_params.remote_sdp_ip, v_engine->codec_params.remote_sdp_port);
+                                       if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_PROXY_MODE) &&
+                                               !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
+                                               /* Reactivate the NAT buster flag. */
+                                               switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
+                                       }
+                                       if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING)) {
+                                               v_engine->check_frames = 0;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if (switch_rtp_ready(a_engine->rtp_session)) {
+               char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
+               switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
+               const char *rport = NULL;
+               switch_port_t remote_rtcp_port = 0;
+
+               if (remote_host && remote_port && !strcmp(remote_host, a_engine->codec_params.remote_sdp_ip) && remote_port == a_engine->codec_params.remote_sdp_port) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n",
+                                                         a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port);
+                       switch_goto_status(SWITCH_STATUS_BREAK, end);
+               }
+
+               if ((rport = switch_channel_get_variable(session->channel, "sip_remote_audio_rtcp_port"))) {
+                       remote_rtcp_port = (switch_port_t)atoi(rport);
+               }
+
+
+               if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->codec_params.remote_sdp_ip,
+                                                                                 a_engine->codec_params.remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
+                       status = SWITCH_STATUS_GENERR;
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n",
+                                                         a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port);
+                       if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
+                               !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
+                               /* Reactivate the NAT buster flag. */
+                               switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
+                       }
+                       if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING)) {
+                               a_engine->check_frames = 0;
+                       }
+                       status = SWITCH_STATUS_SUCCESS;
+               }
+       }
+
+ end:
+
+       return status;
+}
+
+//?
+SWITCH_DECLARE(int) switch_core_media_check_nat(switch_media_handle_t *smh, const char *network_ip)
+{
+       switch_assert(network_ip);
+
+       return (smh->mparams->extsipip && 
+                       !switch_check_network_list_ip(network_ip, "loopback.auto") && 
+                       !switch_check_network_list_ip(network_ip, smh->mparams->local_network));
+}
+
+//?
+SWITCH_DECLARE(switch_status_t) sofia_glue_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip)
+                                                                                                                         
+{
+       char *error = "";
+       switch_status_t status = SWITCH_STATUS_FALSE;
+       int x;
+       switch_port_t myport = *port;
+       switch_port_t stun_port = SWITCH_STUN_DEFAULT_PORT;
+       char *stun_ip = NULL;
+       switch_media_handle_t *smh;
+       switch_memory_pool_t *pool = switch_core_session_get_pool(session);
+
+       if (!(smh = session->media_handle)) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+       if (!sourceip) {
+               return status;
+       }
+
+       if (!strncasecmp(sourceip, "host:", 5)) {
+               status = (*ip = switch_stun_host_lookup(sourceip + 5, pool)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
+       } else if (!strncasecmp(sourceip, "stun:", 5)) {
+               char *p;
+
+               stun_ip = strdup(sourceip + 5);
+
+               if ((p = strchr(stun_ip, ':'))) {
+                       int iport;
+                       *p++ = '\0';
+                       iport = atoi(p);
+                       if (iport > 0 && iport < 0xFFFF) {
+                               stun_port = (switch_port_t) iport;
+                       }
+               }
+
+               if (zstr(stun_ip)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! NO STUN SERVER\n");
+                       goto out;
+               }
+
+               for (x = 0; x < 5; x++) {
+                       if ((status = switch_stun_lookup(ip, port, stun_ip, stun_port, &error, pool)) != SWITCH_STATUS_SUCCESS) {
+                               switch_yield(100000);
+                       } else {
+                               break;
+                       }
+               }
+               if (status != SWITCH_STATUS_SUCCESS) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! %s:%d [%s]\n", stun_ip, stun_port, error);
+                       goto out;
+               }
+               if (!*ip) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! No IP returned\n");
+                       goto out;
+               }
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN Success [%s]:[%d]\n", *ip, *port);
+               status = SWITCH_STATUS_SUCCESS;
+
+               if (myport == *port && !strcmp(*ip, smh->mparams->rtpip)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN Not Required ip and port match. [%s]:[%d]\n", *ip, *port);
+               } else {
+                       smh->mparams->stun_ip = switch_core_session_strdup(session, stun_ip);
+                       smh->mparams->stun_port = stun_port;
+                       smh->mparams->stun_flags |= STUN_FLAG_SET;
+               }
+       } else {
+               *ip = (char *) sourceip;
+               status = SWITCH_STATUS_SUCCESS;
+       }
+
+ out:
+
+       switch_safe_free(stun_ip);
+
+       return status;
+}
+
+
+
+
+//?
+SWITCH_DECLARE(switch_status_t) switch_core_media_choose_video_port(switch_core_session_t *session, int force)
+{
+       char *lookup_rtpip;     /* Pointer to externally looked up address */
+       switch_port_t sdp_port;         /* The external port to be sent in the SDP */
+       const char *use_ip = NULL;      /* The external IP to be sent in the SDP */
+       switch_rtp_engine_t *a_engine, *v_engine;
+       switch_media_handle_t *smh;
+
+       if (!(smh = session->media_handle)) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+       a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
+       v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];      
+
+       lookup_rtpip = smh->mparams->rtpip;
+
+
+       /* Don't do anything if we're in proxy mode or if a (remote) port already has been found */
+       if (!force) {
+               if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) ||
+                       switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) || v_engine->codec_params.adv_sdp_port) {
+                       return SWITCH_STATUS_SUCCESS;
+               }
+       }
+
+       /* Release the local sdp port */
+       if (v_engine->codec_params.local_sdp_port) {
+               switch_rtp_release_port(smh->mparams->rtpip, v_engine->codec_params.local_sdp_port);
+       }
+
+       /* Request a local port from the core's allocator */
+       if (!(v_engine->codec_params.local_sdp_port = switch_rtp_request_port(smh->mparams->rtpip))) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "No RTP ports available!\n");
+               return SWITCH_STATUS_FALSE;
+       }
+
+       sdp_port = v_engine->codec_params.local_sdp_port;
+
+       /* Check if NAT is detected  */
+       if (!zstr(smh->mparams->remote_ip) && switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
+               /* Yes, map the port through switch_nat */
+               switch_nat_add_mapping(v_engine->codec_params.local_sdp_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE);
+
+               /* Find an IP address to use */
+               if (!(use_ip = switch_channel_get_variable(session->channel, "rtp_adv_video_ip"))
+                       && !zstr(smh->mparams->extrtpip)) {
+                       use_ip = smh->mparams->extrtpip;
+               }
+
+               if (use_ip) {
+                       if (sofia_glue_ext_address_lookup(session, &lookup_rtpip, &sdp_port, use_ip) != SWITCH_STATUS_SUCCESS) {
+                               /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */
+                               return SWITCH_STATUS_FALSE;
+                       } else {
+                               /* Address properly resolved, use it as external ip */
+                               use_ip = lookup_rtpip;
+                       }
+               } else {
+                       /* No external ip found, use the profile's rtp ip */
+                       use_ip = smh->mparams->rtpip;
+               }
+       } else {
+               /* No NAT traversal required, use the profile's rtp ip */
+               use_ip = smh->mparams->rtpip;
+       }
+
+       v_engine->codec_params.adv_sdp_port = sdp_port;
+       switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, a_engine->codec_params.adv_sdp_ip);
+       switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, "%d", sdp_port);
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+
+//?
+SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_session_t *session, switch_core_media_params_t *params)
+
+{
+       const char *err = NULL;
+       const char *val = NULL;
+       switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0};
+       switch_status_t status = SWITCH_STATUS_SUCCESS;
+       char tmp[50];
+       char *timer_name = NULL;
+       const char *var;
+       switch_rtp_engine_t *a_engine, *v_engine;
+       switch_media_handle_t *smh;
+
+       if (!(smh = session->media_handle)) {
+               return SWITCH_STATUS_FALSE;;
+       }
+
+       a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
+       v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
+
+
+       if (switch_channel_down(session->channel)) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+
+       if (switch_rtp_ready(a_engine->rtp_session)) {
+               switch_rtp_reset_media_timer(a_engine->rtp_session);
+       }
+
+       if ((var = switch_channel_get_variable(session->channel, "rtp_secure_media")) && switch_true(var)) {
+               switch_channel_set_flag(session->channel, CF_SECURE);
+       }
+
+       if (switch_channel_test_flag(session->channel, CF_PROXY_MODE)) {
+               status = SWITCH_STATUS_SUCCESS;
+               goto end;
+       }
+
+       if (!params->reinvite) {
+               if (switch_rtp_ready(a_engine->rtp_session)) {
+                       if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && !switch_rtp_ready(v_engine->rtp_session)) {
+                               goto video;
+                       }
+
+                       status = SWITCH_STATUS_SUCCESS;
+                       goto end;
+               } 
+       }
+
+       if ((status = switch_core_media_set_codec(session, 0, params->codec_flags)) != SWITCH_STATUS_SUCCESS) {
+               goto end;
+       }
+
+       memset(flags, 0, sizeof(flags));
+       flags[SWITCH_RTP_FLAG_DATAWAIT]++;
+
+       if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
+               !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
+               flags[SWITCH_RTP_FLAG_AUTOADJ]++;
+       }
+
+       if (switch_media_handle_test_media_flag(smh, SCMF_PASS_RFC2833)
+               || ((val = switch_channel_get_variable(session->channel, "pass_rfc2833")) && switch_true(val))) {
+               switch_channel_set_flag(session->channel, CF_PASS_RFC2833);
+       }
+
+
+       if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFLUSH)
+               || ((val = switch_channel_get_variable(session->channel, "rtp_autoflush")) && switch_true(val))) {
+               flags[SWITCH_RTP_FLAG_AUTOFLUSH]++;
+       }
+
+       if (!(switch_media_handle_test_media_flag(smh, SCMF_REWRITE_TIMESTAMPS) ||
+                 ((val = switch_channel_get_variable(session->channel, "rtp_rewrite_timestamps")) && switch_true(val)))) {
+               flags[SWITCH_RTP_FLAG_RAW_WRITE]++;
+       }
+
+       if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG)) {
+               smh->cng_pt = 0;
+       } else if (smh->cng_pt) {
+               flags[SWITCH_RTP_FLAG_AUTO_CNG]++;
+       }
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+       if (!strcasecmp(a_engine->read_impl.iananame, "L16")) {
+               flags[SWITCH_RTP_FLAG_BYTESWAP]++;
+       }
+#endif
+       
+       if ((flags[SWITCH_RTP_FLAG_BYTESWAP]) && (val = switch_channel_get_variable(session->channel, "rtp_disable_byteswap")) && switch_true(val)) {
+               flags[SWITCH_RTP_FLAG_BYTESWAP] = 0;
+       }
+
+       if (a_engine->rtp_session && params->reinvite) {
+               //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
+               //const char *port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
+               char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
+               switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
+
+               if (remote_host && remote_port && !strcmp(remote_host, a_engine->codec_params.remote_sdp_ip) && remote_port == a_engine->codec_params.remote_sdp_port) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
+                                                         switch_channel_get_name(session->channel));
+                       if (switch_rtp_ready(a_engine->rtp_session)) {
+                               if (a_engine->codec_params.recv_pt != a_engine->codec_params.agreed_pt) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
+                                                                 "%s Set audio receive payload in Re-INVITE for non-matching dynamic PT to %u\n", 
+                                                                         switch_channel_get_name(session->channel), a_engine->codec_params.recv_pt);
+                               
+                                       switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->codec_params.recv_pt);
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
+                                                                 "%s Setting audio receive payload in Re-INVITE to %u\n", 
+                                                                         switch_channel_get_name(session->channel), a_engine->codec_params.recv_pt);
+                                       switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->codec_params.agreed_pt);
+                               }
+
+                       }
+                       goto video;
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
+                                                         switch_channel_get_name(session->channel),
+                                                         remote_host, remote_port, a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port);
+
+                       switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->codec_params.remote_sdp_port);
+                       switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->codec_params.remote_sdp_ip);
+                       switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
+               }
+       }
+
+       if (!switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n",
+                                                 switch_channel_get_name(session->channel),
+                                                 a_engine->codec_params.local_sdp_ip,
+                                                 a_engine->codec_params.local_sdp_port,
+                                                 a_engine->codec_params.remote_sdp_ip,
+                                                 a_engine->codec_params.remote_sdp_port, a_engine->codec_params.agreed_pt, a_engine->read_impl.microseconds_per_packet / 1000);
+
+               if (switch_rtp_ready(a_engine->rtp_session)) {
+                       switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->codec_params.agreed_pt);
+
+                       if (a_engine->codec_params.recv_pt != a_engine->codec_params.agreed_pt) {
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
+                                                                 "%s Set audio receive payload to %u\n", switch_channel_get_name(session->channel), a_engine->codec_params.recv_pt);
+                               
+                               switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->codec_params.recv_pt);
+                       } else {
+                               switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->codec_params.agreed_pt);
+                       }
+
+               }
+       }
+
+       switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->codec_params.local_sdp_port);
+       switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, a_engine->codec_params.local_sdp_ip);
+       switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, tmp);
+       switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, a_engine->codec_params.adv_sdp_ip);
+
+       if (a_engine->rtp_session && params->reinvite) {
+               const char *rport = NULL;
+               switch_port_t remote_rtcp_port = 0;
+
+               
+
+               if ((rport = switch_channel_get_variable(session->channel, "sip_remote_audio_rtcp_port"))) {
+                       remote_rtcp_port = (switch_port_t)atoi(rport);
+               }
+
+               if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port,
+                                                                                 remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n",
+                                                         a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port);
+                       if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
+                               !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
+                               /* Reactivate the NAT buster flag. */
+                               switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
+                       }
+               }
+               goto video;
+       }
+
+       if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
+               switch_core_media_proxy_remote_addr(session, NULL);
+
+               memset(flags, 0, sizeof(flags));
+               flags[SWITCH_RTP_FLAG_DATAWAIT]++;
+               flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
+
+               if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
+                       !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
+                       flags[SWITCH_RTP_FLAG_AUTOADJ]++;
+               }
+               timer_name = NULL;
+
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
+                                                 "PROXY AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
+                                                 switch_channel_get_name(session->channel),
+                                                 a_engine->codec_params.remote_sdp_ip,
+                                                 a_engine->codec_params.remote_sdp_port,
+                                                 a_engine->codec_params.remote_sdp_ip,
+                                                 a_engine->codec_params.remote_sdp_port, a_engine->codec_params.agreed_pt, a_engine->read_impl.microseconds_per_packet / 1000);
+
+               if (switch_rtp_ready(a_engine->rtp_session)) {
+                       switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->codec_params.agreed_pt);
+               }
+
+       } else {
+               timer_name = smh->mparams->timer_name;
+
+               if ((var = switch_channel_get_variable(session->channel, "rtp_timer_name"))) {
+                       timer_name = (char *) var;
+               }
+       }
+
+       if (switch_channel_up(session->channel)) {
+               a_engine->rtp_session = switch_rtp_new(a_engine->codec_params.remote_sdp_ip,
+                                                                                          a_engine->codec_params.remote_sdp_port,
+                                                                                          a_engine->codec_params.remote_sdp_ip,
+                                                                                          a_engine->codec_params.remote_sdp_port,
+                                                                                          a_engine->codec_params.agreed_pt,
+                                                                                          a_engine->read_impl.samples_per_packet,
+                                                                                          a_engine->codec_params.codec_ms * 1000,
+                                                                                          flags, timer_name, &err, switch_core_session_get_pool(session));
+       }
+
+       if (switch_rtp_ready(a_engine->rtp_session)) {
+               uint8_t vad_in = (smh->mparams->vflags & VAD_IN);
+               uint8_t vad_out = (smh->mparams->vflags & VAD_OUT);
+               uint8_t inb = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND;
+               uint32_t stun_ping = 0;
+               const char *ssrc;
+
+               switch_core_media_set_rtp_session(session, SWITCH_MEDIA_TYPE_AUDIO, a_engine->rtp_session);
+
+
+               if ((ssrc = switch_channel_get_variable(session->channel, "rtp_use_ssrc"))) {
+                       uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10);
+                       switch_rtp_set_ssrc(a_engine->rtp_session, ssrc_ul);
+               }
+
+
+               switch_channel_set_flag(session->channel, CF_FS_RTP);
+
+               switch_channel_set_variable_printf(session->channel, "sip_use_pt", "%d", a_engine->codec_params.agreed_pt);
+
+               if ((val = switch_channel_get_variable(session->channel, "rtp_enable_vad_in")) && switch_true(val)) {
+                       vad_in = 1;
+               }
+               if ((val = switch_channel_get_variable(session->channel, "rtp_enable_vad_out")) && switch_true(val)) {
+                       vad_out = 1;
+               }
+
+               if ((val = switch_channel_get_variable(session->channel, "rtp_disable_vad_in")) && switch_true(val)) {
+                       vad_in = 0;
+               }
+               if ((val = switch_channel_get_variable(session->channel, "rtp_disable_vad_out")) && switch_true(val)) {
+                       vad_out = 0;
+               }
+
+               if ((smh->mparams->stun_flags & STUN_FLAG_SET) && (val = switch_channel_get_variable(session->channel, "rtp_stun_ping"))) {
+                       int ival = atoi(val);
+
+                       if (ival <= 0) {
+                               if (switch_true(val)) {
+                                       ival = 6;
+                               }
+                       }
+
+                       stun_ping = (ival * a_engine->read_impl.samples_per_second) / a_engine->read_impl.samples_per_packet;
+               }
+
+               a_engine->ssrc = switch_rtp_get_ssrc(a_engine->rtp_session);
+               switch_channel_set_variable_printf(session->channel, "rtp_use_ssrc", "%u", a_engine->ssrc);
+
+
+
+               if (smh->mparams->auto_rtp_bugs & RTP_BUG_IGNORE_MARK_BIT) {
+                       a_engine->rtp_bugs |= RTP_BUG_IGNORE_MARK_BIT;
+               }
+
+               if ((val = switch_channel_get_variable(session->channel, "rtp_manual_rtp_bugs"))) {
+                       switch_core_media_parse_rtp_bugs(&a_engine->rtp_bugs, val);
+               }
+
+               switch_rtp_intentional_bugs(a_engine->rtp_session, a_engine->rtp_bugs | smh->mparams->manual_rtp_bugs);
+
+               if ((vad_in && inb) || (vad_out && !inb)) {
+                       switch_rtp_enable_vad(a_engine->rtp_session, session, &a_engine->read_codec, SWITCH_VAD_FLAG_TALKING | SWITCH_VAD_FLAG_EVENTS_TALK | SWITCH_VAD_FLAG_EVENTS_NOTALK);
+
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP Engage VAD for %s ( %s %s )\n",
+                                                         switch_channel_get_name(switch_core_session_get_channel(session)), vad_in ? "in" : "", vad_out ? "out" : "");
+               }
+
+               if (stun_ping) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting stun ping to %s:%d\n", smh->mparams->stun_ip, stun_ping);
+                                                         
+                       switch_rtp_activate_stun_ping(a_engine->rtp_session, smh->mparams->stun_ip, smh->mparams->stun_port, stun_ping,
+                                                                                 (smh->mparams->stun_flags & STUN_FLAG_FUNNY) ? 1 : 0);
+               }
+
+               if ((val = switch_channel_get_variable(session->channel, "rtcp_audio_interval_msec")) || (val = smh->mparams->rtcp_audio_interval_msec)) {
+                       const char *rport = switch_channel_get_variable(session->channel, "sip_remote_audio_rtcp_port");
+                       switch_port_t remote_port = 0;
+                       if (rport) {
+                               remote_port = (switch_port_t)atoi(rport);
+                       }
+                       if (!strcasecmp(val, "passthru")) {
+                               switch_rtp_activate_rtcp(a_engine->rtp_session, -1, remote_port);
+                       } else {
+                               int interval = atoi(val);
+                               if (interval < 100 || interval > 5000) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
+                                                                         "Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval);
+                               } else {
+                                       switch_rtp_activate_rtcp(a_engine->rtp_session, interval, remote_port);
+                               }
+                       }
+               }
+
+               if ((val = switch_channel_get_variable(session->channel, "jitterbuffer_msec")) || (val = smh->mparams->jb_msec)) {
+                       int jb_msec = atoi(val);
+                       int maxlen = 0, max_drift = 0;
+                       char *p, *q;
+                       
+                       if ((p = strchr(val, ':'))) {
+                               p++;
+                               maxlen = atoi(p);
+                               if ((q = strchr(p, ':'))) {
+                                       q++;
+                                       max_drift = abs(atoi(q));
+                               }
+                       }
+
+                       if (jb_msec < 20 || jb_msec > 10000) {
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
+                                                                 "Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", jb_msec);
+                       } else {
+                               int qlen, maxqlen = 50;
+                               
+                               qlen = jb_msec / (a_engine->read_impl.microseconds_per_packet / 1000);
+
+                               if (qlen < 1) {
+                                       qlen = 3;
+                               }
+
+                               if (maxlen) {
+                                       maxqlen = maxlen / (a_engine->read_impl.microseconds_per_packet / 1000);
+                               }
+
+                               if (maxqlen < qlen) {
+                                       maxqlen = qlen * 5;
+                               }
+                               if (switch_rtp_activate_jitter_buffer(a_engine->rtp_session, qlen, maxqlen,
+                                                                                                         a_engine->read_impl.samples_per_packet, 
+                                                                                                         a_engine->read_impl.samples_per_second, max_drift) == SWITCH_STATUS_SUCCESS) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), 
+                                                                         SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
+                                       switch_channel_set_flag(session->channel, CF_JITTERBUFFER);
+                                       if (!switch_false(switch_channel_get_variable(session->channel, "sip_jitter_buffer_plc"))) {
+                                               switch_channel_set_flag(session->channel, CF_JITTERBUFFER_PLC);
+                                       }
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), 
+                                                                         SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
+                               }
+                               
+                       }
+               }
+
+               if ((val = switch_channel_get_variable(session->channel, "params->rtp_timeout_sec"))) {
+                       int v = atoi(val);
+                       if (v >= 0) {
+                               params->rtp_timeout_sec = v;
+                       }
+               }
+
+               if ((val = switch_channel_get_variable(session->channel, "params->rtp_hold_timeout_sec"))) {
+                       int v = atoi(val);
+                       if (v >= 0) {
+                               params->rtp_hold_timeout_sec = v;
+                       }
+               }
+
+               if (params->rtp_timeout_sec) {
+                       a_engine->max_missed_packets = (a_engine->read_impl.samples_per_second * params->rtp_timeout_sec) / a_engine->read_impl.samples_per_packet;
+
+                       switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_packets);
+                       if (!params->rtp_hold_timeout_sec) {
+                               params->rtp_hold_timeout_sec = params->rtp_timeout_sec * 10;
+                       }
+               }
+
+               if (params->rtp_hold_timeout_sec) {
+                       a_engine->max_missed_hold_packets = (a_engine->read_impl.samples_per_second * params->rtp_hold_timeout_sec) / a_engine->read_impl.samples_per_packet;
+               }
+
+               if (smh->te) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", smh->te);
+                       switch_rtp_set_telephony_event(a_engine->rtp_session, smh->te);
+                       switch_channel_set_variable_printf(session->channel, "sip_2833_send_payload", "%d", smh->te);
+               }
+
+               if (smh->recv_te) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf receive payload to %u\n", smh->recv_te);
+                       switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->recv_te);
+                       switch_channel_set_variable_printf(session->channel, "sip_2833_recv_payload", "%d", smh->recv_te);
+               }
+
+               if (a_engine->codec_params.recv_pt != a_engine->codec_params.agreed_pt) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
+                                                         "%s Set audio receive payload to %u\n", switch_channel_get_name(session->channel), a_engine->codec_params.recv_pt);
+
+                       switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->codec_params.recv_pt);
+               }
+
+               if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) ||
+                       ((val = switch_channel_get_variable(session->channel, "supress_cng")) && switch_true(val)) ||
+                       ((val = switch_channel_get_variable(session->channel, "suppress_cng")) && switch_true(val))) {
+                       smh->cng_pt = 0;
+               }
+
+               if (((val = switch_channel_get_variable(session->channel, "rtp_digit_delay")))) {
+                       int delayi = atoi(val);
+                       if (delayi < 0) delayi = 0;
+                       params->dtmf_delay = (uint32_t) delayi;
+               }
+
+
+               if (params->dtmf_delay) {
+                       switch_rtp_set_interdigit_delay(a_engine->rtp_session, params->dtmf_delay);
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
+                                                         "%s Set rtp dtmf delay to %u\n", switch_channel_get_name(session->channel), params->dtmf_delay);
+                       
+               }
+
+               if (smh->cng_pt && !switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG)) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", smh->cng_pt);
+                       switch_rtp_set_cng_pt(a_engine->rtp_session, smh->cng_pt);
+               }
+
+               switch_core_session_apply_crypto(session, SWITCH_MEDIA_TYPE_AUDIO, "rtp_secure_media_confirmed");
+
+               switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->codec_params.remote_sdp_port);
+               switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->codec_params.remote_sdp_ip);
+               switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
+
+
+               if (switch_channel_test_flag(session->channel, CF_ZRTP_PASSTHRU)) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating ZRTP PROXY MODE\n");
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Disable NOTIMER_DURING_BRIDGE\n");
+                       switch_channel_clear_flag(session->channel, CF_NOTIMER_DURING_BRIDGE);
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activating audio UDPTL mode\n");
+                       switch_rtp_udptl_mode(a_engine->rtp_session);
+               }
+
+
+       video:
+               
+               switch_core_media_check_video_codecs(session);
+
+               if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && v_engine->codec_params.rm_encoding && v_engine->codec_params.remote_sdp_port) {
+                       /******************************************************************************************/
+                       if (v_engine->rtp_session && params->reinvite) {
+                               //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
+                               //const char *port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
+                               char *remote_host = switch_rtp_get_remote_host(v_engine->rtp_session);
+                               switch_port_t remote_port = switch_rtp_get_remote_port(v_engine->rtp_session);
+                               
+
+
+                               if (remote_host && remote_port && !strcmp(remote_host, v_engine->codec_params.remote_sdp_ip) && remote_port == v_engine->codec_params.remote_sdp_port) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video params are unchanged for %s.\n",
+                                                                         switch_channel_get_name(session->channel));
+                                       goto video_up;
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video params changed for %s from %s:%d to %s:%d\n",
+                                                                         switch_channel_get_name(session->channel),
+                                                                         remote_host, remote_port, v_engine->codec_params.remote_sdp_ip, v_engine->codec_params.remote_sdp_port);
+                               }
+                       }
+
+                       if (!switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
+                                                                 "VIDEO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n", switch_channel_get_name(session->channel),
+                                                                 a_engine->codec_params.remote_sdp_ip, v_engine->codec_params.local_sdp_port, v_engine->codec_params.remote_sdp_ip,
+                                                                 v_engine->codec_params.remote_sdp_port, v_engine->codec_params.agreed_pt, a_engine->read_impl.microseconds_per_packet / 1000);
+
+                               if (switch_rtp_ready(v_engine->rtp_session)) {
+                                       switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->codec_params.agreed_pt);
+                               }
+                       }
+                       
+                       switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->codec_params.local_sdp_port);
+                       switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, a_engine->codec_params.adv_sdp_ip);
+                       switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp);
+
+
+                       if (v_engine->rtp_session && params->reinvite) {
+                               const char *rport = NULL;
+                               switch_port_t remote_rtcp_port = 0;
+
+                               params->reinvite = 0;
+
+                               if ((rport = switch_channel_get_variable(session->channel, "sip_remote_video_rtcp_port"))) {
+                                       remote_rtcp_port = (switch_port_t)atoi(rport);
+                               }
+                               
+                               if (switch_rtp_set_remote_address
+                                       (v_engine->rtp_session, v_engine->codec_params.remote_sdp_ip, v_engine->codec_params.remote_sdp_port, remote_rtcp_port, SWITCH_TRUE,
+                                        &err) != SWITCH_STATUS_SUCCESS) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err);
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n",
+                                                                         v_engine->codec_params.remote_sdp_ip, v_engine->codec_params.remote_sdp_port);
+                                       if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
+                                               !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
+                                               /* Reactivate the NAT buster flag. */
+                                               switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
+                                       }
+
+                               }
+                               goto video_up;
+                       }
+
+                       if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
+                               switch_core_media_proxy_remote_addr(session, NULL);
+
+                               memset(flags, 0, sizeof(flags));
+                               flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
+                               flags[SWITCH_RTP_FLAG_DATAWAIT]++;
+
+                               if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
+                                       !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
+                                       flags[SWITCH_RTP_FLAG_AUTOADJ]++;
+                               }
+                               timer_name = NULL;
+
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
+                                                                 "PROXY VIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
+                                                                 switch_channel_get_name(session->channel),
+                                                                 a_engine->codec_params.remote_sdp_ip,
+                                                                 v_engine->codec_params.local_sdp_port,
+                                                                 v_engine->codec_params.remote_sdp_ip,
+                                                                 v_engine->codec_params.remote_sdp_port, v_engine->codec_params.agreed_pt, v_engine->read_impl.microseconds_per_packet / 1000);
+
+                               if (switch_rtp_ready(v_engine->rtp_session)) {
+                                       switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->codec_params.agreed_pt);
+                               }
+                       } else {
+                               timer_name = smh->mparams->timer_name;
+
+                               if ((var = switch_channel_get_variable(session->channel, "rtp_timer_name"))) {
+                                       timer_name = (char *) var;
+                               }
+                       }
+
+                       /******************************************************************************************/
+
+                       if (v_engine->rtp_session) {
+                               goto video_up;
+                       }
+
+
+                       if (!v_engine->codec_params.local_sdp_port) {
+                               switch_core_media_choose_video_port(session, 1);
+                       }
+
+                       memset(flags, 0, sizeof(flags));
+                       flags[SWITCH_RTP_FLAG_DATAWAIT]++;
+                       flags[SWITCH_RTP_FLAG_RAW_WRITE]++;
+
+                       if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_PROXY_MODE) &&
+                               !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
+                               flags[SWITCH_RTP_FLAG_AUTOADJ]++;                               
+                       }
+
+                       if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
+                               flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
+                       }
+                       switch_core_media_set_video_codec(session, 0);
+
+                       flags[SWITCH_RTP_FLAG_USE_TIMER] = 0;
+                       flags[SWITCH_RTP_FLAG_NOBLOCK] = 0;
+                       flags[SWITCH_RTP_FLAG_VIDEO]++;
+
+                       v_engine->rtp_session = switch_rtp_new(a_engine->codec_params.remote_sdp_ip,
+                                                                                                                v_engine->codec_params.local_sdp_port,
+                                                                                                                v_engine->codec_params.remote_sdp_ip,
+                                                                                                                v_engine->codec_params.remote_sdp_port,
+                                                                                                                v_engine->codec_params.agreed_pt,
+                                                                                                                1, 90000, flags, NULL, &err, switch_core_session_get_pool(session));
+
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%sVIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n",
+                                                         switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) ? "PROXY " : "",
+                                                         switch_channel_get_name(session->channel),
+                                                         a_engine->codec_params.remote_sdp_ip,
+                                                         v_engine->codec_params.local_sdp_port,
+                                                         v_engine->codec_params.remote_sdp_ip,
+                                                         v_engine->codec_params.remote_sdp_port, v_engine->codec_params.agreed_pt,
+                                                         0, switch_rtp_ready(v_engine->rtp_session) ? "SUCCESS" : err);
+
+
+                       if (switch_rtp_ready(v_engine->rtp_session)) {
+                               switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->codec_params.agreed_pt);
+                               switch_core_media_set_rtp_session(session, SWITCH_MEDIA_TYPE_VIDEO, v_engine->rtp_session);
+                       }
+
+                       if (switch_rtp_ready(v_engine->rtp_session)) {
+                               const char *ssrc;
+                               switch_channel_set_flag(session->channel, CF_VIDEO);
+                               if ((ssrc = switch_channel_get_variable(session->channel, "rtp_use_video_ssrc"))) {
+                                       uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10);
+                                       switch_rtp_set_ssrc(v_engine->rtp_session, ssrc_ul);
+                               }
+
+
+
+                               if ((val = switch_channel_get_variable(session->channel, "rtp_manual_video_rtp_bugs"))) {
+                                       switch_core_media_parse_rtp_bugs(&v_engine->rtp_bugs, val);
+                               }
+                               
+                               switch_rtp_intentional_bugs(v_engine->rtp_session, v_engine->rtp_bugs | smh->mparams->manual_video_rtp_bugs);
+
+                               if (v_engine->codec_params.recv_pt != v_engine->codec_params.agreed_pt) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
+                                                                         "%s Set video receive payload to %u\n", switch_channel_get_name(session->channel), v_engine->codec_params.recv_pt);
+                                       switch_rtp_set_recv_pt(v_engine->rtp_session, v_engine->codec_params.recv_pt);
+                               }
+
+                               switch_channel_set_variable_printf(session->channel, "sip_use_video_pt", "%d", v_engine->codec_params.agreed_pt);
+                               v_engine->ssrc = switch_rtp_get_ssrc(v_engine->rtp_session);
+                               switch_channel_set_variable_printf(session->channel, "rtp_use_video_ssrc", "%u", v_engine->ssrc);
+
+                               switch_core_session_apply_crypto(session, SWITCH_MEDIA_TYPE_VIDEO, "rtp_secure_video_confirmed");
+
+
+                               if ((val = switch_channel_get_variable(session->channel, "rtcp_audio_interval_msec"))
+                                       || (val = smh->mparams->rtcp_audio_interval_msec)) {
+                                       const char *rport = switch_channel_get_variable(session->channel, "sip_remote_video_rtcp_port");
+                                       switch_port_t remote_port = 0;
+                                       if (rport) {
+                                               remote_port = (switch_port_t)atoi(rport);
+                                       }
+                                       if (!strcasecmp(val, "passthru")) {
+                                               switch_rtp_activate_rtcp(a_engine->rtp_session, -1, remote_port);
+                                       } else {
+                                               int interval = atoi(val);
+                                               if (interval < 100 || interval > 5000) {
+                                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
+                                                                                         "Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval);
+                                               } else {
+                                                       switch_rtp_activate_rtcp(a_engine->rtp_session, interval, remote_port);
+                                               }
+                                       }
+                               }
+                               if (switch_channel_test_flag(session->channel, CF_ZRTP_PASSTHRU)) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activating video UDPTL mode\n");
+                                       switch_rtp_udptl_mode(v_engine->rtp_session);
+                               }
+
+                       } else {
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", switch_str_nil(err));
+                               switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+                               goto end;
+                       }
+               }
+
+       } else {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", switch_str_nil(err));
+               switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+               status = SWITCH_STATUS_FALSE;
+               goto end;
+       }
+
+ video_up:
+
+       status = SWITCH_STATUS_SUCCESS;
+
+ end:
+
+       params->reinvite = 0;
+
+       switch_core_recovery_track(session);
+
+
+
+       return status;
+
+}
 
 
 /* For Emacs: