]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
compiles
authorAnthony Minessale <anthm@freeswitch.org>
Sat, 22 Dec 2012 03:30:14 +0000 (21:30 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Mon, 1 Apr 2013 02:27:15 +0000 (21:27 -0500)
src/include/switch_core_media.h
src/include/switch_types.h
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 960ab2e955941515c6598b6d58fad825d81e0f40..45c4c5fe850427836b523975c32a5456247ad2a3 100644 (file)
@@ -89,7 +89,7 @@ typedef struct switch_core_media_params_s {
        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;
 
@@ -127,10 +127,16 @@ typedef struct switch_core_media_params_s {
        char *extsipip;
        char *local_network;
 
+       char *sipip;
+
        char *sdp_username;
 
        switch_mutex_t *mutex;
-               
+
+       switch_payload_t te;//x:tp
+       switch_payload_t recv_te;//x:tp
+
+       char *adv_sdp_audio_ip;
 
 } switch_core_media_params_t;
 
@@ -188,6 +194,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_sessio
 SWITCH_DECLARE(int) switch_core_media_check_nat(switch_media_handle_t *smh, const char *network_ip);
 
 SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_session_t *session, switch_media_type_t type, int force);
+SWITCH_DECLARE(void) switch_core_media_check_dtmf_type(switch_core_session_t *session);
+SWITCH_DECLARE(void) switch_core_media_absorb_sdp(switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_session_t *session, const char *sdp_str);
+SWITCH_DECLARE(void) switch_core_media_deactivate_rtp(switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_core_media_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip);
+SWITCH_DECLARE(switch_status_t) switch_core_media_process_t38_passthru(switch_core_session_t *session, 
+                                                                                                                                          switch_core_session_t *other_session, switch_t38_options_t *t38_options);
 
 SWITCH_END_EXTERN_C
 #endif
index 52885c9a8152fe5c847c6b66f6452cc90c478dc8..f13600063a3e0c21cec763ff60ac298a202a55c9 100644 (file)
@@ -1292,6 +1292,7 @@ typedef enum {
        CF_PASS_RFC2833,
        CF_T38_PASSTHRU,
        CF_DROP_DTMF,
+       CF_REINVITE,
        /* 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 03d10a8705f866d6230df1aa2e95bc16d8a7cb2a..b514824638a0f2c8a1c95760d7ac566dc3a4f9f4 100644 (file)
@@ -195,6 +195,7 @@ typedef enum {
 typedef enum {
        PFLAG_AUTH_CALLS,
        PFLAG_AUTH_MESSAGES,
+       PFLAG_PASS_RFC2833,
        PFLAG_BLIND_REG,
        PFLAG_AUTH_ALL,
        PFLAG_FULL_ID,
@@ -286,7 +287,6 @@ typedef enum {
        TFLAG_EARLY_MEDIA,
        TFLAG_3PCC,
        TFLAG_READY,
-       TFLAG_REINVITE,
        TFLAG_REFER,
        TFLAG_NOHUP,
        TFLAG_NOSDP_REINVITE,
@@ -523,8 +523,15 @@ struct sofia_profile {
        char *shutdown_type;
        char *extrtpip;
        char *rtpip[MAX_RTPIP];
+       char *jb_msec;
+       switch_payload_t te;//x:tp
+       switch_payload_t recv_te;//x:tp
        uint32_t rtpip_index;
        uint32_t rtpip_next;
+       char *rtcp_audio_interval_msec;
+       char *rtcp_video_interval_msec;
+
+       char *sdp_username;
        char *sipip;
        char *extsipip;
        char *url;
@@ -573,7 +580,7 @@ struct sofia_profile {
        switch_core_media_flag_t media_flags[SCMF_MAX];
        unsigned int mflags;
        unsigned int ndlb;
-       unsigned int mdlb;
+       unsigned int mndlb;
        uint32_t max_calls;
        uint32_t nonce_ttl;
        nua_t *nua;
@@ -907,8 +914,6 @@ void launch_sofia_profile_thread(sofia_profile_t *profile);
 
 switch_status_t sofia_presence_chat_send(switch_event_t *message_event);
                                                                                 
-void sofia_media_tech_absorb_sdp(private_object_t *tech_pvt);
-
 /*
  * \brief Sets the "ep_codec_string" channel variable, parsing r_sdp and taing codec_string in consideration 
  * \param channel Current channel
@@ -1152,6 +1157,10 @@ void sofia_glue_fire_events(sofia_profile_t *profile);
 void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event);
 void sofia_queue_message(sofia_dispatch_event_t *de);
 void sofia_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp);
+int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip);
+
+switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, char **ip, switch_port_t *port,
+                                                                                         const char *sourceip, switch_memory_pool_t *pool);
 
 /* For Emacs:
  * Local Variables:
index ebd14049c0446bf36f9fd89a8c177a18b6dc2832..91061109c6e7cf72ab628f62f551effb53a6d2cc 100644 (file)
@@ -665,7 +665,7 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
 
        if (sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
                                                                                                                        || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
-                                                                                                                       || !strcasecmp(sip->sip_reason->re_protocol, profile->username)) && sip->sip_reason->re_cause) {
+                                                                                                                       || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) {
                tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
                cause = tech_pvt->q850_cause;
        } else {
@@ -3590,7 +3590,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                        profile->mflags = MFLAG_REFER | MFLAG_REGISTER;
                                        profile->server_rport_level = 1;
                                        profile->client_rport_level = 1;
-                                       sofia_set_pflag(profile, PFLAG_STUN_ENABLED);
                                        sofia_set_pflag(profile, PFLAG_DISABLE_100REL);
                                        profile->auto_restart = 1;
                                        sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING);
@@ -3622,7 +3621,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                        profile->nat_acl_count = 0;
                                        profile->reg_acl_count = 0;
                                        profile->proxy_acl_count = 0;
-                                       sofia_set_pflag(profile, PFLAG_STUN_ENABLED);
                                        sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID);
                                        profile->ib_calls = 0;
                                        profile->ob_calls = 0;
@@ -3851,12 +3849,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                                sofia_set_flag(profile, TFLAG_INB_NOMEDIA);
                                        } else if (!strcasecmp(var, "inbound-late-negotiation") && switch_true(val)) {
                                                sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
-                                       } else if (!strcasecmp(var, "rtp-autoflush-during-bridge")) {
-                                               if (switch_true(val)) {
-                                                       sofia_set_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE);
-                                               } else {
-                                                       sofia_clear_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE);
-                                               }
                                        } else if (!strcasecmp(var, "rtp-notimer-during-bridge")) {
                                                if (switch_true(val)) {
                                                        sofia_set_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE);
@@ -3933,7 +3925,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                                profile->max_registrations_perext = atoi(val);
                                        } else if (!strcasecmp(var, "rfc2833-pt")) {
                                                profile->te = (switch_payload_t) atoi(val);
-                                       } else if (!strcasecmp(var, "cng-pt") && !sofia_test_pflag(profile, PFLAG_SUPPRESS_CNG)) {
+                                       } else if (!strcasecmp(var, "cng-pt") && !sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG)) {
                                                profile->cng_pt = (switch_payload_t) atoi(val);
                                        } else if (!strcasecmp(var, "sip-port")) {
                                                if (!strcasecmp(val, "auto")) {
@@ -4018,7 +4010,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                                        } else if (!strcasecmp(val, "auto-nat")) {
                                                                ip = NULL;
                                                        } else if (strcasecmp(val, "auto")) {
-                                                               if (sofia_glue_ext_address_lookup(profile, NULL, &myip, &profile->extsipport, val, profile->pool) == SWITCH_STATUS_SUCCESS) {
+                                                               if (sofia_glue_ext_address_lookup(profile, &myip, &profile->extsipport, val, profile->pool) == SWITCH_STATUS_SUCCESS) {
                                                                        ip = myip;
                                                                        sofia_clear_pflag(profile, PFLAG_AUTO_NAT);
                                                                } else {
@@ -4156,7 +4148,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                                }
                                        } else if (!strcasecmp(var, "supress-cng") || !strcasecmp(var, "suppress-cng")) {
                                                if (switch_true(val)) {
-                                                       sofia_set_pflag(profile, PFLAG_SUPPRESS_CNG);
+                                                       sofia_set_media_flag(profile, SCMF_SUPPRESS_CNG);
                                                        profile->cng_pt = 0;
                                                }
                                        } else if (!strcasecmp(var, "NDLB-broken-auth-hash")) {
@@ -4197,12 +4189,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                                if (switch_true(val)) {
                                                        sofia_set_pflag(profile, PFLAG_PASS_RFC2833);
                                                }
-                                       } else if (!strcasecmp(var, "rtp-autoflush")) {
-                                               if (switch_true(val)) {
-                                                       sofia_set_pflag(profile, PFLAG_AUTOFLUSH);
-                                               } else {
-                                                       sofia_clear_pflag(profile, PFLAG_AUTOFLUSH);
-                                               }
                                        } else if (!strcasecmp(var, "rtp-autofix-timing")) {
                                                if (switch_true(val)) {
                                                        sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING);
@@ -4241,7 +4227,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                                }
                                        } else if (!strcasecmp(var, "rtp-rewrite-timestamps")) {
                                                if (switch_true(val)) {
-                                                       sofia_set_pflag(profile, PFLAG_REWRITE_TIMESTAMPS);
+                                                       sofia_set_media_flag(profile, SCMF_REWRITE_TIMESTAMPS);
                                                }
                                        } else if (!strcasecmp(var, "auth-calls")) {
                                                if (switch_true(val)) {
@@ -4522,7 +4508,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                        sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
                                }
 
-                               if ((!profile->cng_pt) && (!sofia_test_pflag(profile, PFLAG_SUPPRESS_CNG))) {
+                               if ((!profile->cng_pt) && (!sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG))) {
                                        profile->cng_pt = SWITCH_RTP_CNG_PAYLOAD;
                                }
 
@@ -4554,8 +4540,8 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                        profile->nonce_ttl = 60;
                                }
 
-                               if (!profile->username) {
-                                       profile->username = switch_core_strdup(profile->pool, "FreeSWITCH");
+                               if (!profile->sdp_username) {
+                                       profile->sdp_username = switch_core_strdup(profile->pool, "FreeSWITCH");
                                }
 
                                if (!profile->rtpip[0]) {
@@ -4843,7 +4829,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
 
                if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
                                || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
-                               || !strcasecmp(sip->sip_reason->re_protocol, profile->username)) && sip->sip_reason->re_cause) {
+                               || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) {
                        tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote Reason: %d\n", tech_pvt->q850_cause);
                } 
@@ -4861,9 +4847,9 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
                        caller_profile->network_addr = switch_core_strdup(caller_profile->pool, network_ip);
                }
 
-               tech_pvt->last_sdp_str = NULL;
+               tech_pvt->mparams->last_sdp_str = NULL;
                if (!sofia_use_soa(tech_pvt) && sip->sip_payload && sip->sip_payload->pl_data) {
-                       tech_pvt->last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
+                       tech_pvt->mparams->last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
                }
 
 
@@ -5200,9 +5186,9 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
 
                                        if (sip->sip_payload && sip->sip_payload->pl_data &&
                                                sip->sip_content_type && sip->sip_content_type->c_subtype && switch_stristr("sdp", sip->sip_content_type->c_subtype)) {
-                                               tech_pvt->remote_sdp_str = switch_core_session_strdup(tech_pvt->session, sip->sip_payload->pl_data);
-                                               r_sdp = tech_pvt->remote_sdp_str;
-                                               sofia_glue_tech_proxy_remote_addr(tech_pvt, NULL);
+                                               tech_pvt->mparams->remote_sdp_str = switch_core_session_strdup(tech_pvt->session, sip->sip_payload->pl_data);
+                                               r_sdp = tech_pvt->mparams->remote_sdp_str;
+                                               switch_core_media_proxy_remote_addr(session, NULL);
                                        }
                                        
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing %d %s to other leg\n", status, phrase);
@@ -5249,7 +5235,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
                                        
                                        if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38) {
                                                if (switch_rtp_ready(tech_pvt->rtp_session) && switch_rtp_ready(other_tech_pvt->rtp_session)) {
-                                                       sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
+                                                       switch_channel_clear_flag(tech_pvt->channel, CF_NOTIMER_DURING_BRIDGE);
                                                        switch_rtp_udptl_mode(tech_pvt->rtp_session);
                                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating T38 Passthru\n");
                                                }
@@ -5543,8 +5529,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                }
        }
 
-       if (status > 100 && status < 300 && tech_pvt && !sofia_use_soa(tech_pvt) && !r_sdp && tech_pvt->last_sdp_str) {
-               r_sdp = tech_pvt->last_sdp_str;
+       if (status > 100 && status < 300 && tech_pvt && !sofia_use_soa(tech_pvt) && !r_sdp && tech_pvt->mparams->last_sdp_str) {
+               r_sdp = tech_pvt->mparams->last_sdp_str;
        }
 
        if ((channel && (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA))) ||
@@ -5591,7 +5577,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                          switch_channel_get_name(channel), nua_callstate_name(ss_state), status);
                        goto done;
                } else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (status == 180 || status == 183) && r_sdp) {
-                       sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+                       switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
                }
 
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel %s entering state [%s][%d]\n",
@@ -5599,12 +5585,12 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
 
                if (r_sdp) {
 
-                       if (!(profile->mndlb & SM_NDLB_ALLOW_NONDUP_SDP) || (!zstr(tech_pvt->remote_sdp_str) && !strcmp(tech_pvt->remote_sdp_str, r_sdp))) {
+                       if (!(profile->mndlb & SM_NDLB_ALLOW_NONDUP_SDP) || (!zstr(tech_pvt->mparams->remote_sdp_str) && !strcmp(tech_pvt->mparams->remote_sdp_str, r_sdp))) {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Duplicate SDP\n%s\n", r_sdp);
                                is_dup_sdp = 1;
                        } else {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
-                               tech_pvt->remote_sdp_str = switch_core_session_strdup(session, r_sdp);
+                               tech_pvt->mparams->remote_sdp_str = switch_core_session_strdup(session, r_sdp);
                                switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
 
                                if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
@@ -5699,7 +5685,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
                                switch_channel_mark_pre_answered(channel);
                                sofia_set_flag(tech_pvt, TFLAG_SDP);
-                               if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) || sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
+                               if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) || switch_channel_test_flag(channel, CF_REINVITE)) {
                                        if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
                                                goto done;
                                        }
@@ -5909,7 +5895,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                if (sofia_use_soa(tech_pvt)) {
                                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                                SIPTAG_CONTACT_STR(tech_pvt->profile->url),
-                                                                               SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
+                                                                               SOATAG_USER_SDP_STR(tech_pvt->mparams->local_sdp_str),
                                                                                SOATAG_REUSE_REJECTED(1),
                                                                                SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"),
                                                                                TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
@@ -5917,7 +5903,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                                NUTAG_MEDIA_ENABLE(0),
                                                                                SIPTAG_CONTACT_STR(tech_pvt->profile->url),
-                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str), TAG_END());
+                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams->local_sdp_str), TAG_END());
                                                }
                                        }
                                } else if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
@@ -6025,7 +6011,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                if (sofia_use_soa(tech_pvt)) {
                                                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                                               SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
+                                                                                               SOATAG_USER_SDP_STR(tech_pvt->mparams->local_sdp_str),
                                                                                                SOATAG_REUSE_REJECTED(1),
                                                                                                SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"),
                                                                                                TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
@@ -6033,7 +6019,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                                                NUTAG_MEDIA_ENABLE(0),
                                                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str), TAG_END());
+                                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams->local_sdp_str), TAG_END());
                                                                }
 
                                                                switch_channel_set_flag(channel, CF_PROXY_MODE);
@@ -6046,7 +6032,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                }
 
                                                if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
-                                                       if (sofia_glue_tech_proxy_remote_addr(tech_pvt, r_sdp) == SWITCH_STATUS_SUCCESS && !is_t38) {
+                                                       if (switch_core_media_proxy_remote_addr(session, r_sdp) == SWITCH_STATUS_SUCCESS && !is_t38) {
                                                                nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
                                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed, NOT proxying re-invite.\n");
                                                                switch_core_session_rwunlock(other_session);
@@ -6110,7 +6096,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                goto done;
                                        }
 
-                                       sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+                                       switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
 
                                        if (tech_pvt->num_codecs) {
                                                match = sofia_media_negotiate_sdp(session, r_sdp);
@@ -6135,7 +6121,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                }
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
                                        } else {
-                                               sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE);
+                                               switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
                                                is_ok = 0;
                                        }
@@ -6150,7 +6136,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                        if (sofia_use_soa(tech_pvt)) {
                                                nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                        SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                       SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
+                                                                       SOATAG_USER_SDP_STR(tech_pvt->mparams->local_sdp_str),
                                                                        SOATAG_REUSE_REJECTED(1),
                                                                        SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"),
                                                                        TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
@@ -6158,7 +6144,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                        NUTAG_MEDIA_ENABLE(0),
                                                                        SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                       SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str), TAG_END());
+                                                                       SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams->local_sdp_str), TAG_END());
                                        }
                                        if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REINVITE) == SWITCH_STATUS_SUCCESS) {
                                                switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
@@ -6174,7 +6160,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                        /* sdp changed since 18X w sdp, we're supposed to ignore it but we, of course, were pressured into supporting it */
                        uint8_t match = 0;
 
-                       sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+                       switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
 
                        if (tech_pvt->num_codecs) {
                                match = sofia_media_negotiate_sdp(session, r_sdp);
@@ -6186,7 +6172,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                sofia_media_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
 
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
-                               sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+                               switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
 
                                if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error!\n");
@@ -6194,7 +6180,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                        goto done;
                                }
                        } else {
-                               sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE);
+                               switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error! %s\n", r_sdp);
                                goto done;
 
@@ -6241,13 +6227,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                }
 
                                if (match) {
-                                       sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+                                       switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
                                        if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error!\n");
                                                switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RTP ERROR");
                                                is_ok = 0;
                                        }
-                                       sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE);
+                                       switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
                                } else {
                                        switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
                                        is_ok = 0;
@@ -6266,7 +6252,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                }
                if (tech_pvt && nh == tech_pvt->nh2) {
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Cheater Reinvite!\n");
-                       sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+                       switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
                        tech_pvt->nh = tech_pvt->nh2;
                        tech_pvt->nh2 = NULL;
                        if (sofia_glue_tech_choose_port(tech_pvt, 0) == SWITCH_STATUS_SUCCESS) {
@@ -7805,8 +7791,8 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 
 
        
-       tech_pvt->remote_ip = switch_core_session_strdup(session, network_ip);
-       tech_pvt->remote_port = network_port;
+       tech_pvt->mparams->remote_ip = switch_core_session_strdup(session, network_ip);
+       tech_pvt->mparams->remote_port = network_port;
 
        channel = tech_pvt->channel = switch_core_session_get_channel(session);
 
@@ -7827,7 +7813,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 
        if (sip->sip_contact && sip->sip_contact->m_url) {
                char tmp[35] = "";
-               const char *ipv6 = strchr(tech_pvt->remote_ip, ':');
+               const char *ipv6 = strchr(tech_pvt->mparams->remote_ip, ':');
 
                transport = sofia_glue_url2transport(sip->sip_contact->m_url);
 
@@ -7835,10 +7821,10 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
                        switch_core_session_sprintf(session,
                                                                                "sip:%s@%s%s%s:%d;transport=%s",
                                                                                sip->sip_contact->m_url->url_user,
-                                                                               ipv6 ? "[" : "", tech_pvt->remote_ip, ipv6 ? "]" : "", tech_pvt->remote_port, sofia_glue_transport2str(transport));
+                                                                               ipv6 ? "[" : "", tech_pvt->mparams->remote_ip, ipv6 ? "]" : "", tech_pvt->mparams->remote_port, sofia_glue_transport2str(transport));
 
-               switch_channel_set_variable(channel, "sip_received_ip", tech_pvt->remote_ip);
-               snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_port);
+               switch_channel_set_variable(channel, "sip_received_ip", tech_pvt->mparams->remote_ip);
+               snprintf(tmp, sizeof(tmp), "%d", tech_pvt->mparams->remote_port);
                switch_channel_set_variable(channel, "sip_received_port", tmp);
        }
 
@@ -8039,7 +8025,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
                                                                                        "sip:%s@%s%s%s:%d;transport=%s",
                                                                                        user, ipv6 ? "[" : "", host, ipv6 ? "]" : "", port, sofia_glue_transport2str(transport));
 
-                       if (sofia_glue_check_nat(profile, tech_pvt->remote_ip)) {
+                       if (sofia_glue_check_nat(profile, tech_pvt->mparams->remote_ip)) {
                                url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_public_url : profile->public_url;
                                check_nat = 1;
                        } else {
@@ -8079,7 +8065,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 
                } else {
                        const char *url = NULL;
-                       if (sofia_glue_check_nat(profile, tech_pvt->remote_ip)) {
+                       if (sofia_glue_check_nat(profile, tech_pvt->mparams->remote_ip)) {
                                url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_public_url : profile->public_url;
                        } else {
                                url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_url : profile->url;
@@ -8101,7 +8087,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
                }
        }
 
-       if (sofia_glue_check_nat(profile, tech_pvt->remote_ip)) {
+       if (sofia_glue_check_nat(profile, tech_pvt->mparams->remote_ip)) {
                tech_pvt->user_via = sofia_glue_create_external_via(session, profile, tech_pvt->transport);
                nua_set_hparams(tech_pvt->nh, SIPTAG_VIA_STR(tech_pvt->user_via), TAG_END());
        }
index 767400f4d4d02addad136d73fb75a145bc00b0f0..7e2df4067ad2c6b39b1c610937ee679f82bfc755 100644 (file)
 switch_cache_db_handle_t *_sofia_glue_get_db_handle(sofia_profile_t *profile, const char *file, const char *func, int line);
 #define sofia_glue_get_db_handle(_p) _sofia_glue_get_db_handle(_p, __FILE__, __SWITCH_FUNC__, __LINE__)
 
-void sofia_glue_set_udptl_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *t38_options, int insist)
-{
-       char buf[2048] = "";
-       char max_buf[128] = "";
-       char max_data[128] = "";
-       const char *ip;
-       uint32_t port;
-       const char *family = "IP4";
-       const char *username;
-       const char *bit_removal_on = "a=T38FaxFillBitRemoval\n";
-       const char *bit_removal_off = "";
-       
-       const char *mmr_on = "a=T38FaxTranscodingMMR\n";
-       const char *mmr_off = "";
-
-       const char *jbig_on = "a=T38FaxTranscodingJBIG\n";
-       const char *jbig_off = "";
-       const char *var;
-       int broken_boolean;
-
-       switch_assert(tech_pvt);
-       switch_assert(t38_options);
-
-       ip = t38_options->local_ip;
-       port = t38_options->local_port;
-       username = tech_pvt->profile->username;
-
-       //sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
-
-       var = switch_channel_get_variable(tech_pvt->channel, "t38_broken_boolean");
-       
-       broken_boolean = switch_true(var);
-
-       if (!ip) {
-               if (!(ip = tech_pvt->adv_sdp_audio_ip)) {
-                       ip = tech_pvt->proxy_sdp_audio_ip;
-               }
-       }
-
-       if (!ip) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO IP!\n", switch_channel_get_name(tech_pvt->channel));
-               return;
-       }
-
-       if (!port) {
-               if (!(port = tech_pvt->adv_sdp_audio_port)) {
-                       port = tech_pvt->proxy_sdp_audio_port;
-               }
-       }
-       
-       if (!port) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO PORT!\n", switch_channel_get_name(tech_pvt->channel));
-               return;
-       }
-
-       if (!tech_pvt->owner_id) {
-               tech_pvt->owner_id = (uint32_t) switch_epoch_time_now(NULL) - port;
-       }
-
-       if (!tech_pvt->session_id) {
-               tech_pvt->session_id = tech_pvt->owner_id;
-       }
-
-       tech_pvt->session_id++;
-
-       family = strchr(ip, ':') ? "IP6" : "IP4";
-
-
-       switch_snprintf(buf, sizeof(buf),
-                                       "v=0\n"
-                                       "o=%s %010u %010u IN %s %s\n"
-                                       "s=%s\n"
-                                       "c=IN %s %s\n"
-                                       "t=0 0\n", username, tech_pvt->owner_id, tech_pvt->session_id, family, ip, username, family, ip);
-
-       if (t38_options->T38FaxMaxBuffer) {
-               switch_snprintf(max_buf, sizeof(max_buf), "a=T38FaxMaxBuffer:%d\n", t38_options->T38FaxMaxBuffer);
-       };
-
-       if (t38_options->T38FaxMaxDatagram) {
-               switch_snprintf(max_data, sizeof(max_data), "a=T38FaxMaxDatagram:%d\n", t38_options->T38FaxMaxDatagram);
-       };
-
-
-       
-
-       if (broken_boolean) {
-               bit_removal_on = "a=T38FaxFillBitRemoval:1\n";
-               bit_removal_off = "a=T38FaxFillBitRemoval:0\n";
-
-               mmr_on = "a=T38FaxTranscodingMMR:1\n";
-               mmr_off = "a=T38FaxTranscodingMMR:0\n";
-
-               jbig_on = "a=T38FaxTranscodingJBIG:1\n";
-               jbig_off = "a=T38FaxTranscodingJBIG:0\n";
-
-       }
-       
-
-       switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-                                       "m=image %d udptl t38\n"
-                                       "a=T38FaxVersion:%d\n"
-                                       "a=T38MaxBitRate:%d\n"
-                                       "%s"
-                                       "%s"
-                                       "%s"
-                                       "a=T38FaxRateManagement:%s\n"
-                                       "%s"
-                                       "%s"
-                                       "a=T38FaxUdpEC:%s\n",
-                                       //"a=T38VendorInfo:%s\n",
-                                       port,
-                                       t38_options->T38FaxVersion,
-                                       t38_options->T38MaxBitRate,
-                                       t38_options->T38FaxFillBitRemoval ? bit_removal_on : bit_removal_off,
-                                       t38_options->T38FaxTranscodingMMR ? mmr_on : mmr_off,
-                                       t38_options->T38FaxTranscodingJBIG ? jbig_on : jbig_off,
-                                       t38_options->T38FaxRateManagement,
-                                       max_buf,
-                                       max_data,
-                                       t38_options->T38FaxUdpEC
-                                       //t38_options->T38VendorInfo ? t38_options->T38VendorInfo : "0 0 0"
-                                       );
-
-
-
-       if (insist) {
-               switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "m=audio 0 RTP/AVP 19\n");
-       }
-
-       sofia_media_tech_set_local_sdp(tech_pvt, buf, SWITCH_TRUE);
-
-
-       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s image media sdp:\n%s\n",
-                                         switch_channel_get_name(tech_pvt->channel), tech_pvt->local_sdp_str);
 
+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));
 }
 
-
 private_object_t *sofia_glue_new_pvt(switch_core_session_t *session)
 {
        private_object_t *tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t));
@@ -222,7 +92,7 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
 
        tech_pvt->profile = profile;
 
-       tech_pvt->rtpip = switch_core_session_strdup(session, profile->rtpip[profile->rtpip_next++]);
+       tech_pvt->mparams->rtpip = switch_core_session_strdup(session, profile->rtpip[profile->rtpip_next++]);
        if (profile->rtpip_next >= profile->rtpip_index) {
                profile->rtpip_next = 0;
        }
@@ -234,12 +104,12 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
        if (tech_pvt->bte) {
                tech_pvt->recv_te = tech_pvt->te = tech_pvt->bte;
        } else if (!tech_pvt->te) {
-               tech_pvt->recv_te = tech_pvt->te = profile->te;
+               tech_pvt->mparams->recv_te = tech_pvt->mparams->te = profile->te;
        }
 
        tech_pvt->dtmf_type = tech_pvt->profile->dtmf_type;
 
-       if (!sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG)) {
+       if (!sofia_test_media_flag(tech_pvt->profile, SCMF_SUPPRESS_CNG)) {
                if (tech_pvt->bcng_pt) {
                        tech_pvt->cng_pt = tech_pvt->bcng_pt;
                } else if (!tech_pvt->cng_pt) {
@@ -254,7 +124,13 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
                switch_channel_set_flag(tech_pvt->channel, CF_TRACKABLE);
        }
 
-       sofia_glue_check_dtmf_type(tech_pvt);
+
+       if (profile->flags[PFLAG_PASS_RFC2833]) {
+               switch_channel_set_flag(tech_pvt->channel, CF_PASS_RFC2833);
+       }
+
+       
+       switch_core_media_check_dtmf_type(session);
        switch_channel_set_cap(tech_pvt->channel, CC_MEDIA_ACK);
        switch_channel_set_cap(tech_pvt->channel, CC_BYPASS_MEDIA);
        switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA);
@@ -273,9 +149,12 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
        tech_pvt->mparams->extsipip = profile->extsipip;
        tech_pvt->mparams->local_network = profile->local_network;
        tech_pvt->mparams->mutex = tech_pvt->sofia_mutex;
+       tech_pvt->mparams->sipip = profile->sipip;
+       tech_pvt->mparams->jb_msec = profile->jb_msec;
+       tech_pvt->mparams->rtcp_audio_interval_msec = profile->rtcp_audio_interval_msec;
+       tech_pvt->mparams->rtcp_video_interval_msec = profile->rtcp_video_interval_msec;
 
-       
-       switch_media_handle_create(&tech_pvt->media_handle, session, &tech_pvt->mparams);
+       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);
 
 
@@ -289,6 +168,71 @@ 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, 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 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;
+
+               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 (!*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;
+       } 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;
@@ -769,7 +713,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                return status;
        }
 
-       if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->local_sdp_str)) {
+       if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->mparams->local_sdp_str)) {
                sofia_media_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
        }
 
@@ -816,7 +760,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
 
                        sipip = tech_pvt->profile->sipip;
 
-                       if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
+                       if (!zstr(tech_pvt->mparams->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip)) {
                                sipip = tech_pvt->profile->extsipip;
                        }
 
@@ -856,7 +800,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                }
 
                if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT)) {
-                       if (!zstr(tech_pvt->remote_ip) && !zstr(tech_pvt->profile->extsipip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
+                       if (!zstr(tech_pvt->mparams->remote_ip) && !zstr(tech_pvt->profile->extsipip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip)) {
                                rpid_domain = tech_pvt->profile->extsipip;
                        } else {
                                rpid_domain = tech_pvt->profile->sipip;
@@ -890,7 +834,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                        }
                }
 
-               if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
+               if (!zstr(tech_pvt->mparams->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip)) {
                        tech_pvt->user_via = sofia_glue_create_external_via(session, tech_pvt->profile, tech_pvt->transport);
                }
 
@@ -905,7 +849,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                                char *ip_addr = tech_pvt->profile->sipip;
                                char *ipv6;
 
-                               if ( !zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip ) ) {
+                               if ( !zstr(tech_pvt->mparams->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip ) ) {
                                        ip_addr = tech_pvt->profile->extsipip;
                                }
 
@@ -922,7 +866,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                                if (sofia_glue_transport_has_tls(tech_pvt->transport)) {
                                        tech_pvt->invite_contact = tech_pvt->profile->tls_url;
                                } else {
-                                       if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
+                                       if (!zstr(tech_pvt->mparams->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip)) {
                                                tech_pvt->invite_contact = tech_pvt->profile->public_url;
                                        } else {
                                                tech_pvt->invite_contact = tech_pvt->profile->url;
@@ -1190,7 +1134,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
 
        if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
                if (switch_rtp_ready(tech_pvt->rtp_session)) {
-                       sofia_glue_tech_proxy_remote_addr(tech_pvt, NULL);
+                       switch_core_media_proxy_remote_addr(session, NULL);
                }
                sofia_media_tech_patch_sdp(tech_pvt);
        }
@@ -1231,7 +1175,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                tech_pvt->nh->nh_has_invite = 1;
        }
 
-       if ((mp = sofia_media_get_multipart(session, SOFIA_MULTIPART_PREFIX, tech_pvt->local_sdp_str, &mp_type))) {
+       if ((mp = sofia_media_get_multipart(session, SOFIA_MULTIPART_PREFIX, tech_pvt->mparams->local_sdp_str, &mp_type))) {
                sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
        }
 
@@ -1241,16 +1185,16 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                tech_pvt->session_refresher = nua_no_refresher;
        }
 
-       if (tech_pvt->local_sdp_str) {
+       if (tech_pvt->mparams->local_sdp_str) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
-                                                 "Local SDP:\n%s\n", tech_pvt->local_sdp_str);
+                                                 "Local SDP:\n%s\n", tech_pvt->mparams->local_sdp_str);
        }
 
        if (sofia_use_soa(tech_pvt)) {
                nua_invite(tech_pvt->nh,
                                   NUTAG_AUTOANSWER(0),
-                                  //TAG_IF(zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(0)),
-                                  //TAG_IF(!zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(1)),
+                                  //TAG_IF(zstr(tech_pvt->mparams->local_sdp_str), NUTAG_AUTOACK(0)),
+                                  //TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), NUTAG_AUTOACK(1)),
                                   // The code above is breaking things...... grrr WE need this because we handle our own acks and there are 3pcc cases in there too
                                   NUTAG_AUTOACK(0),
                                   NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
@@ -1274,16 +1218,16 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                                   TAG_IF(!zstr(route), SIPTAG_ROUTE_STR(route)),
                                   TAG_IF(tech_pvt->profile->minimum_session_expires, NUTAG_MIN_SE(tech_pvt->profile->minimum_session_expires)),
                                   TAG_IF(cseq, SIPTAG_CSEQ(cseq)),
-                                  TAG_IF(zstr(tech_pvt->local_sdp_str), SIPTAG_PAYLOAD_STR("")),
-                                  TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_ADDRESS(tech_pvt->adv_sdp_audio_ip)),
-                                  TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str)),
-                                  TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_REUSE_REJECTED(1)),
-                                  TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_ORDERED_USER(1)),
-                                  TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE)),
-                                  TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL)),
+                                  TAG_IF(zstr(tech_pvt->mparams->local_sdp_str), SIPTAG_PAYLOAD_STR("")),
+                                  TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_ADDRESS(tech_pvt->mparams->adv_sdp_audio_ip)),
+                                  TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_USER_SDP_STR(tech_pvt->mparams->local_sdp_str)),
+                                  TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_REUSE_REJECTED(1)),
+                                  TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_ORDERED_USER(1)),
+                                  TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE)),
+                                  TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL)),
                                   TAG_IF(rep, SIPTAG_REPLACES_STR(rep)),
                                   TAG_IF(!require_timer, NUTAG_TIMER_AUTOREQUIRE(0)),
-                                  TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_HOLD(holdstr)), TAG_END());
+                                  TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_HOLD(holdstr)), TAG_END());
        } else {
                nua_invite(tech_pvt->nh,
                                   NUTAG_AUTOANSWER(0),
@@ -1312,7 +1256,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                                   TAG_IF(cseq, SIPTAG_CSEQ(cseq)),
                                   NUTAG_MEDIA_ENABLE(0),
                                   SIPTAG_CONTENT_TYPE_STR(mp_type ? mp_type : "application/sdp"),
-                                  SIPTAG_PAYLOAD_STR(mp ? mp : tech_pvt->local_sdp_str), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), SOATAG_HOLD(holdstr), TAG_END());
+                                  SIPTAG_PAYLOAD_STR(mp ? mp : tech_pvt->mparams->local_sdp_str), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), SOATAG_HOLD(holdstr), TAG_END());
        }
 
        sofia_glue_free_destination(dst);
@@ -1334,7 +1278,7 @@ void sofia_glue_do_xfer_invite(switch_core_session_t *session)
        switch_mutex_lock(tech_pvt->sofia_mutex);
        caller_profile = switch_channel_get_caller_profile(channel);
 
-       if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
+       if (!zstr(tech_pvt->mparams->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip)) {
                sipip = tech_pvt->profile->extsipip;
                contact_url = tech_pvt->profile->public_url;
        } else {
@@ -1356,8 +1300,8 @@ void sofia_glue_do_xfer_invite(switch_core_session_t *session)
                nua_invite(tech_pvt->nh2,
                                   SIPTAG_CONTACT_STR(contact_url),
                                   TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
-                                  SOATAG_ADDRESS(tech_pvt->adv_sdp_audio_ip),
-                                  SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
+                                  SOATAG_ADDRESS(tech_pvt->mparams->adv_sdp_audio_ip),
+                                  SOATAG_USER_SDP_STR(tech_pvt->mparams->local_sdp_str),
                                   SOATAG_REUSE_REJECTED(1),
                                   SOATAG_ORDERED_USER(1),
                                   SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), TAG_END());
@@ -1417,42 +1361,6 @@ void sofia_glue_set_rtp_stats(private_object_t *tech_pvt)
        }
 }
 
-void sofia_glue_deactivate_rtp(private_object_t *tech_pvt)
-{
-       int loops = 0;
-       if (switch_rtp_ready(tech_pvt->rtp_session)) {
-               while (loops < 10 && (sofia_test_flag(tech_pvt, TFLAG_READING) || sofia_test_flag(tech_pvt, TFLAG_WRITING))) {
-                       switch_yield(10000);
-                       loops++;
-               }
-       }
-
-       if (tech_pvt->video_rtp_session) {
-               switch_rtp_destroy(&tech_pvt->video_rtp_session);
-       } else if (tech_pvt->local_sdp_video_port) {
-               switch_rtp_release_port(tech_pvt->rtpip, tech_pvt->local_sdp_video_port);
-       }
-
-
-       if (tech_pvt->local_sdp_video_port > 0 && !zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
-               switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_video_port, SWITCH_NAT_UDP);
-               switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_video_port + 1, SWITCH_NAT_UDP);
-       }
-
-
-       if (tech_pvt->rtp_session) {
-               switch_rtp_destroy(&tech_pvt->rtp_session);
-       } else if (tech_pvt->local_sdp_audio_port) {
-               switch_rtp_release_port(tech_pvt->rtpip, tech_pvt->local_sdp_audio_port);
-       }
-
-       if (tech_pvt->local_sdp_audio_port > 0 && !zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
-               switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_audio_port, SWITCH_NAT_UDP);
-               switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_audio_port + 1, SWITCH_NAT_UDP);
-       }
-
-}
-
 /* map sip responses to QSIG cause codes ala RFC4497 section 8.4.4 */
 switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status)
 {
@@ -1903,7 +1811,7 @@ int sofia_recover_callback(switch_core_session_t *session)
        switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
        switch_mutex_init(&tech_pvt->sofia_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
 
-       tech_pvt->remote_ip = (char *) switch_channel_get_variable(channel, "sip_network_ip");
+       tech_pvt->mparams->remote_ip = (char *) switch_channel_get_variable(channel, "sip_network_ip");
        tech_pvt->remote_port = atoi(switch_str_nil(switch_channel_get_variable(channel, "sip_network_port")));
        tech_pvt->caller_profile = switch_channel_get_caller_profile(channel);
 
@@ -1963,7 +1871,7 @@ int sofia_recover_callback(switch_core_session_t *session)
        switch_core_session_get_recovery_crypto_key(session, SWITCH_MEDIA_TYPE_VIDEO, "srtp_remote_video_crypto_key");
 
        if ((tmp = switch_channel_get_variable(channel, "sip_local_sdp_str"))) {
-               tech_pvt->local_sdp_str = switch_core_session_strdup(session, tmp);
+               tech_pvt->mparams->local_sdp_str = switch_core_session_strdup(session, tmp);
        }
 
        if ((tmp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE))) {
@@ -2018,7 +1926,7 @@ int sofia_recover_callback(switch_core_session_t *session)
                        
                        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->mparams->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);
 
                        if (!zstr(ip)) {
@@ -2027,7 +1935,7 @@ int sofia_recover_callback(switch_core_session_t *session)
                        }
 
                        if (!zstr(a_ip)) {
-                               tech_pvt->adv_sdp_audio_ip = switch_core_session_strdup(session, a_ip);
+                               tech_pvt->mparams->adv_sdp_audio_ip = switch_core_session_strdup(session, a_ip);
                        }
 
                        if (r_ip && r_port) {
index 6b66806b80b0552187cdbfa51ce004965c7169af..d5e07843882ebd57079e6dfd1dd3a558b6d6c376 100644 (file)
 
 
 
-void sofia_media_tech_absorb_sdp(private_object_t *tech_pvt)
-{
-       const char *sdp_str;
-
-       if ((sdp_str = switch_channel_get_variable(tech_pvt->channel, SWITCH_B_SDP_VARIABLE))) {
-               sdp_parser_t *parser;
-               sdp_session_t *sdp;
-               sdp_media_t *m;
-               sdp_connection_t *connection;
-
-               if ((parser = sdp_parse(NULL, sdp_str, (int) strlen(sdp_str), 0))) {
-                       if ((sdp = sdp_session(parser))) {
-                               for (m = sdp->sdp_media; m; m = m->m_next) {
-                                       if (m->m_type != sdp_media_audio || !m->m_port) {
-                                               continue;
-                                       }
-
-                                       connection = sdp->sdp_connection;
-                                       if (m->m_connections) {
-                                               connection = m->m_connections;
-                                       }
-
-                                       if (connection) {
-                                               tech_pvt->proxy_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, connection->c_address);
-                                       }
-                                       tech_pvt->proxy_sdp_audio_port = (switch_port_t) m->m_port;
-                                       if (tech_pvt->proxy_sdp_audio_ip && tech_pvt->proxy_sdp_audio_port) {
-                                               break;
-                                       }
-                               }
-                       }
-                       sdp_parser_free(parser);
-               }
-               sofia_media_tech_set_local_sdp(tech_pvt, sdp_str, SWITCH_TRUE);
-       }
-}
-
-
-
 void sofia_media_proxy_codec(switch_core_session_t *session, const char *r_sdp)
 {
        sdp_media_t *m;
@@ -141,7 +102,7 @@ uint8_t sofia_media_negotiate_sdp(switch_core_session_t *session, const char *r_
        uint8_t t, p = 0;
        private_object_t *tech_pvt = switch_core_session_get_private(session);
 
-       if ((t = switch_core_media_negotiate_sdp(session, r_sdp, &p, sofia_test_flag(tech_pvt, TFLAG_REINVITE), 
+       if ((t = switch_core_media_negotiate_sdp(session, r_sdp, &p, switch_channel_test_flag(tech_pvt->channel, CF_REINVITE), 
                                                                           tech_pvt->profile->codec_flags, tech_pvt->profile->te))) {
                sofia_set_flag_locked(tech_pvt, TFLAG_SDP);
        }
@@ -155,16 +116,18 @@ uint8_t sofia_media_negotiate_sdp(switch_core_session_t *session, const char *r_
 
 switch_status_t sofia_media_activate_rtp(private_object_t *tech_pvt)
 {
-       int ok;
+       switch_status_t status;
 
        switch_mutex_lock(tech_pvt->sofia_mutex);
+       status = switch_core_media_activate_rtp(tech_pvt->session);
        switch_mutex_unlock(tech_pvt->sofia_mutex);
 
-       if (ok) {
+       if (status == SWITCH_STATUS_SUCCESS) {
                sofia_set_flag(tech_pvt, TFLAG_RTP);
                sofia_set_flag(tech_pvt, TFLAG_IO);
        }
 
+       return status;
 }
 
 
@@ -511,279 +474,15 @@ void sofia_media_tech_prepare_codecs(private_object_t *tech_pvt)
 }
 
 
-void sofia_media_tech_patch_sdp(private_object_t *tech_pvt)
+void sofia_media_deactivate_rtp(private_object_t *tech_pvt)
 {
-       switch_size_t len;
-       char *p, *q, *pe, *qe;
-       int has_video = 0, has_audio = 0, has_ip = 0;
-       char port_buf[25] = "";
-       char vport_buf[25] = "";
-       char *new_sdp;
-       int bad = 0;
-
-       if (zstr(tech_pvt->local_sdp_str)) {
-               return;
-       }
-
-       len = strlen(tech_pvt->local_sdp_str) * 2;
-
-       if (switch_channel_test_flag(tech_pvt->channel, CF_ANSWERED) &&
-               (switch_stristr("sendonly", tech_pvt->local_sdp_str) || switch_stristr("0.0.0.0", tech_pvt->local_sdp_str))) {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Skip patch on hold SDP\n");
-               return;
-       }
-
-       if (zstr(tech_pvt->adv_sdp_audio_ip) || !tech_pvt->adv_sdp_audio_port) {
-               if (sofia_glue_tech_choose_port(tech_pvt, 1) != SWITCH_STATUS_SUCCESS) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "%s I/O Error\n",
-                                                         switch_channel_get_name(tech_pvt->channel));
-                       return;
-               }
-               tech_pvt->iananame = switch_core_session_strdup(tech_pvt->session, "PROXY");
-               tech_pvt->rm_rate = 8000;
-               tech_pvt->codec_ms = 20;
-       }
-
-       new_sdp = switch_core_session_alloc(tech_pvt->session, len);
-       switch_snprintf(port_buf, sizeof(port_buf), "%u", tech_pvt->adv_sdp_audio_port);
-
-
-       p = tech_pvt->local_sdp_str;
-       q = new_sdp;
-       pe = p + strlen(p);
-       qe = q + len - 1;
-
-
-       while (p && *p) {
-               if (p >= pe) {
-                       bad = 1;
-                       goto end;
-               }
-
-               if (q >= qe) {
-                       bad = 2;
-                       goto end;
-               }
-
-               if (tech_pvt->adv_sdp_audio_ip && !strncmp("c=IN IP", p, 7)) {
-                       strncpy(q, p, 7);
-                       p += 7;
-                       q += 7;
-                       strncpy(q, strchr(tech_pvt->adv_sdp_audio_ip, ':') ? "6 " : "4 ", 2);
-                       p +=2;
-                       q +=2;                  
-                       strncpy(q, tech_pvt->adv_sdp_audio_ip, strlen(tech_pvt->adv_sdp_audio_ip));
-                       q += strlen(tech_pvt->adv_sdp_audio_ip);
-
-                       while (p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'A' && *p <= 'F') || (*p >= 'a' && *p <= 'f'))) {
-                               if (p >= pe) {
-                                       bad = 3;
-                                       goto end;
-                               }
-                               p++;
-                       }
-
-                       has_ip++;
-
-               } else if (!strncmp("o=", p, 2)) {
-                       char *oe = strchr(p, '\n');
-                       switch_size_t len;
-
-                       if (oe) {
-                               const char *family = "IP4";
-                               char o_line[1024] = "";
-
-                               if (oe >= pe) {
-                                       bad = 5;
-                                       goto end;
-                               }
-
-                               len = (oe - p);
-                               p += len;
-
-
-                               family = strchr(tech_pvt->profile->sipip, ':') ? "IP6" : "IP4";
-
-                               if (!tech_pvt->owner_id) {
-                                       tech_pvt->owner_id = (uint32_t) switch_epoch_time_now(NULL) * 31821U + 13849U;
-                               }
-
-                               if (!tech_pvt->session_id) {
-                                       tech_pvt->session_id = tech_pvt->owner_id;
-                               }
-
-                               tech_pvt->session_id++;
-
-
-                               snprintf(o_line, sizeof(o_line), "o=%s %010u %010u IN %s %s\n",
-                                                tech_pvt->profile->username, tech_pvt->owner_id, tech_pvt->session_id, family, tech_pvt->profile->sipip);
-
-                               strncpy(q, o_line, strlen(o_line));
-                               q += strlen(o_line) - 1;
-
-                       }
-
-               } else if (!strncmp("s=", p, 2)) {
-                       char *se = strchr(p, '\n');
-                       switch_size_t len;
-
-                       if (se) {
-                               char s_line[1024] = "";
-
-                               if (se >= pe) {
-                                       bad = 5;
-                                       goto end;
-                               }
-
-                               len = (se - p);
-                               p += len;
-
-                               snprintf(s_line, sizeof(s_line), "s=%s\n", tech_pvt->profile->username);
-
-                               strncpy(q, s_line, strlen(s_line));
-                               q += strlen(s_line) - 1;
-
-                       }
-
-               } else if ((!strncmp("m=audio ", p, 8) && *(p + 8) != '0') || (!strncmp("m=image ", p, 8) && *(p + 8) != '0')) {
-                       strncpy(q, p, 8);
-                       p += 8;
-
-                       if (p >= pe) {
-                               bad = 4;
-                               goto end;
-                       }
-
-
-                       q += 8;
-
-                       if (q >= qe) {
-                               bad = 5;
-                               goto end;
-                       }
-
-
-                       strncpy(q, port_buf, strlen(port_buf));
-                       q += strlen(port_buf);
-
-                       if (q >= qe) {
-                               bad = 6;
-                               goto end;
-                       }
-
-                       while (p && *p && (*p >= '0' && *p <= '9')) {
-                               if (p >= pe) {
-                                       bad = 7;
-                                       goto end;
-                               }
-                               p++;
-                       }
-
-                       has_audio++;
-
-               } else if (!strncmp("m=video ", p, 8) && *(p + 8) != '0') {
-                       if (!has_video) {
-                               sofia_glue_tech_choose_video_port(tech_pvt, 1);
-                               tech_pvt->video_rm_encoding = "PROXY-VID";
-                               tech_pvt->video_rm_rate = 90000;
-                               tech_pvt->video_codec_ms = 0;
-                               switch_snprintf(vport_buf, sizeof(vport_buf), "%u", tech_pvt->adv_sdp_video_port);
-                               if (switch_channel_media_ready(tech_pvt->channel) && !switch_rtp_ready(tech_pvt->video_rtp_session)) {
-                                       switch_channel_set_flag(tech_pvt->channel, CF_VIDEO_POSSIBLE);
-                                       sofia_set_flag(tech_pvt, TFLAG_REINVITE);
-                                       sofia_media_activate_rtp(tech_pvt);
-                               }
-                       }
-
-                       strncpy(q, p, 8);
-                       p += 8;
-
-                       if (p >= pe) {
-                               bad = 8;
-                               goto end;
-                       }
-
-                       q += 8;
-
-                       if (q >= qe) {
-                               bad = 9;
-                               goto end;
-                       }
-
-                       strncpy(q, vport_buf, strlen(vport_buf));
-                       q += strlen(vport_buf);
-
-                       if (q >= qe) {
-                               bad = 10;
-                               goto end;
-                       }
-
-                       while (p && *p && (*p >= '0' && *p <= '9')) {
-
-                               if (p >= pe) {
-                                       bad = 11;
-                                       goto end;
-                               }
-
-                               p++;
-                       }
-
-                       has_video++;
-               }
-
-               while (p && *p && *p != '\n') {
-
-                       if (p >= pe) {
-                               bad = 12;
-                               goto end;
-                       }
-
-                       if (q >= qe) {
-                               bad = 13;
-                               goto end;
-                       }
-
-                       *q++ = *p++;
-               }
-
-               if (p >= pe) {
-                       bad = 14;
-                       goto end;
-               }
-
-               if (q >= qe) {
-                       bad = 15;
-                       goto end;
-               }
-
-               *q++ = *p++;
-
-       }
-
- end:
-
-       if (bad) {
-               return;
+       int loops = 0;
+       while (loops < 10 && (sofia_test_flag(tech_pvt, TFLAG_READING) || sofia_test_flag(tech_pvt, TFLAG_WRITING))) {
+               switch_yield(10000);
+               loops++;
        }
 
-
-       if (switch_channel_down(tech_pvt->channel) || sofia_test_flag(tech_pvt, TFLAG_BYE)) {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s too late.\n", switch_channel_get_name(tech_pvt->channel));
-               return;
-       }
-
-
-       if (!has_ip && !has_audio) {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s SDP has no audio in it.\n%s\n",
-                                                 switch_channel_get_name(tech_pvt->channel), tech_pvt->local_sdp_str);
-               return;
-       }
-
-
-       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s Patched SDP\n---\n%s\n+++\n%s\n",
-                                         switch_channel_get_name(tech_pvt->channel), tech_pvt->local_sdp_str, new_sdp);
-
-       sofia_media_tech_set_local_sdp(tech_pvt, new_sdp, SWITCH_FALSE);
+       switch_core_media_deactivate_rtp(tech_pvt->session);
 
 }
 
index 3429f014ee37940073a32ee7e7ec3dac97040cea..95184e38ca436c668fc9b289c666adc56d92e743 100644 (file)
@@ -139,8 +139,6 @@ struct switch_media_handle_s {
        int payload_space;//x:tp
        char *origin;//x:tp
        int hold_laps;//x:tp
-       switch_payload_t te;//x:tp
-       switch_payload_t recv_te;//x:tp
        switch_payload_t cng_pt;//x:tp
        switch_core_media_dtmf_t dtmf_type;//x:tp
        const switch_codec_implementation_t *negotiated_codecs[SWITCH_MAX_CODECS];//x:tp
@@ -1883,7 +1881,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                                }
 
                                if ((pass == 2 && switch_media_handle_test_media_flag(smh, SCMF_T38_PASSTHRU)) 
-                                       || !reinvite ||
+                                       || !switch_channel_test_flag(session->channel, CF_REINVITE) ||
                                        
                                        switch_channel_test_flag(session->channel, CF_PROXY_MODE) || 
                                        switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) || 
@@ -2001,7 +1999,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                        x = 0;
 
                        if (a_engine->codec_params.rm_encoding && !(switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || 
-                                                                                                               switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))) { // && !reinvite) {
+                                                                                                               switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))) { // && !switch_channel_test_flag(session->channel, CF_REINVITE)) {
                                char *remote_host = a_engine->codec_params.remote_sdp_ip;
                                switch_port_t remote_port = a_engine->codec_params.remote_sdp_port;
                                int same = 0;
@@ -2216,7 +2214,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                                        
                                        if (!switch_true(mirror) && 
                                                switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && 
-                                               (!reinvite || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) {
+                                               (!switch_channel_test_flag(session->channel, CF_REINVITE) || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) {
                                                switch_core_media_get_offered_pt(session, mimp, &a_engine->codec_params.recv_pt);
                                        }
                                        
@@ -2242,14 +2240,14 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 
                        if (best_te) {
                                if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
-                                       te = smh->te = (switch_payload_t) best_te;
+                                       te = smh->mparams->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 (a_engine->rtp_session) {
                                                switch_rtp_set_telephony_event(a_engine->rtp_session, (switch_payload_t) best_te);
                                                switch_channel_set_variable_printf(session->channel, "sip_2833_send_payload", "%d", best_te);
                                        }
                                } else {
-                                       te = smh->recv_te = smh->te = (switch_payload_t) best_te;
+                                       te = smh->mparams->recv_te = smh->mparams->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 (a_engine->rtp_session) {
                                                switch_rtp_set_telephony_event(a_engine->rtp_session, te);
@@ -2264,11 +2262,11 @@ 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, "No 2833 in SDP.  Disable 2833 dtmf and switch to INFO\n");
                                        switch_channel_set_variable(session->channel, "dtmf_type", "info");
                                        smh->dtmf_type = DTMF_INFO;
-                                       te = smh->recv_te = smh->te = 0;
+                                       te = smh->mparams->recv_te = smh->mparams->te = 0;
                                } else {
                                        switch_channel_set_variable(session->channel, "dtmf_type", "none");
                                        smh->dtmf_type = DTMF_NONE;
-                                       te = smh->recv_te = smh->te = 0;
+                                       te = smh->mparams->recv_te = smh->mparams->te = 0;
                                }
                        }
 
@@ -2699,7 +2697,7 @@ SWITCH_DECLARE(int) switch_core_media_check_nat(switch_media_handle_t *smh, cons
 }
 
 //?
-SWITCH_DECLARE(switch_status_t) sofia_glue_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip)
+SWITCH_DECLARE(switch_status_t) switch_core_media_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip)
                                                                                                                          
 {
        char *error = "";
@@ -2816,6 +2814,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio
                return SWITCH_STATUS_FALSE;
        }
 
+       engine->codec_params.local_sdp_ip = smh->mparams->rtpip;
+       
+
        sdp_port = engine->codec_params.local_sdp_port;
 
        /* Check if NAT is detected  */
@@ -2832,7 +2833,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio
                }
 
                if (use_ip) {
-                       if (sofia_glue_ext_address_lookup(session, &lookup_rtpip, &sdp_port, use_ip) != SWITCH_STATUS_SUCCESS) {
+                       if (switch_core_media_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 {
@@ -2849,16 +2850,72 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio
        }
 
        engine->codec_params.adv_sdp_port = sdp_port;
-       switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, engine->codec_params.adv_sdp_ip);
-       switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, "%d", sdp_port);
+       engine->codec_params.adv_sdp_ip = smh->mparams->adv_sdp_audio_ip = smh->mparams->extrtpip = switch_core_session_strdup(session, use_ip);
+
+
+       if (type == SWITCH_MEDIA_TYPE_AUDIO) {
+               switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, engine->codec_params.local_sdp_ip);
+               switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, "%d", sdp_port);
+               switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, engine->codec_params.adv_sdp_ip);
+       } else {
+               switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, 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(void) switch_core_media_deactivate_rtp(switch_core_session_t *session)
+{
+       switch_rtp_engine_t *a_engine, *v_engine;
+       switch_media_handle_t *smh;
+
+       if (!(smh = session->media_handle)) {
+               return;
+       }
+
+       a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
+       v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
+
+
+       if (switch_rtp_ready(a_engine->rtp_session)) {
+
+       }
+
+       if (v_engine->rtp_session) {
+               switch_rtp_destroy(&v_engine->rtp_session);
+       } else if (v_engine->codec_params.local_sdp_port) {
+               switch_rtp_release_port(smh->mparams->rtpip, v_engine->codec_params.local_sdp_port);
+       }
+
+
+       if (v_engine->codec_params.local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) && 
+               switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
+               switch_nat_del_mapping((switch_port_t) v_engine->codec_params.local_sdp_port, SWITCH_NAT_UDP);
+               switch_nat_del_mapping((switch_port_t) v_engine->codec_params.local_sdp_port + 1, SWITCH_NAT_UDP);
+       }
+
+
+       if (a_engine->rtp_session) {
+               switch_rtp_destroy(&a_engine->rtp_session);
+       } else if (a_engine->codec_params.local_sdp_port) {
+               switch_rtp_release_port(smh->mparams->rtpip, a_engine->codec_params.local_sdp_port);
+       }
+
+       if (a_engine->codec_params.local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) && 
+               switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
+               switch_nat_del_mapping((switch_port_t) a_engine->codec_params.local_sdp_port, SWITCH_NAT_UDP);
+               switch_nat_del_mapping((switch_port_t) a_engine->codec_params.local_sdp_port + 1, SWITCH_NAT_UDP);
+       }
+
+}
+
+
 
 
 //?
-SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_session_t *session, switch_core_media_params_t *params)
+SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_session_t *session)
 
 {
        const char *err = NULL;
@@ -2897,7 +2954,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                goto end;
        }
 
-       if (!params->reinvite) {
+       if (!switch_channel_test_flag(session->channel, CF_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;
@@ -2908,7 +2965,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                } 
        }
 
-       if ((status = switch_core_media_set_codec(session, 0, params->codec_flags)) != SWITCH_STATUS_SUCCESS) {
+       if ((status = switch_core_media_set_codec(session, 0, smh->mparams->codec_flags)) != SWITCH_STATUS_SUCCESS) {
                goto end;
        }
 
@@ -2952,7 +3009,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                flags[SWITCH_RTP_FLAG_BYTESWAP] = 0;
        }
 
-       if (a_engine->rtp_session && params->reinvite) {
+       if (a_engine->rtp_session && switch_channel_test_flag(session->channel, CF_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);
@@ -3016,7 +3073,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
        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) {
+       if (a_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) {
                const char *rport = NULL;
                switch_port_t remote_rtcp_port = 0;
 
@@ -3232,40 +3289,40 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                if ((val = switch_channel_get_variable(session->channel, "params->rtp_timeout_sec"))) {
                        int v = atoi(val);
                        if (v >= 0) {
-                               params->rtp_timeout_sec = v;
+                               smh->mparams->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;
+                               smh->mparams->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;
+               if (smh->mparams->rtp_timeout_sec) {
+                       a_engine->max_missed_packets = (a_engine->read_impl.samples_per_second * smh->mparams->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 (!smh->mparams->rtp_hold_timeout_sec) {
+                               smh->mparams->rtp_hold_timeout_sec = smh->mparams->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->mparams->rtp_hold_timeout_sec) {
+                       a_engine->max_missed_hold_packets = (a_engine->read_impl.samples_per_second * smh->mparams->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->mparams->te) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", smh->mparams->te);
+                       switch_rtp_set_telephony_event(a_engine->rtp_session, smh->mparams->te);
+                       switch_channel_set_variable_printf(session->channel, "sip_2833_send_payload", "%d", smh->mparams->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 (smh->mparams->recv_te) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf receive payload to %u\n", smh->mparams->recv_te);
+                       switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->mparams->recv_te);
+                       switch_channel_set_variable_printf(session->channel, "sip_2833_recv_payload", "%d", smh->mparams->recv_te);
                }
 
                if (a_engine->codec_params.recv_pt != a_engine->codec_params.agreed_pt) {
@@ -3284,14 +3341,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                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;
+                       smh->mparams->dtmf_delay = (uint32_t) delayi;
                }
 
 
-               if (params->dtmf_delay) {
-                       switch_rtp_set_interdigit_delay(a_engine->rtp_session, params->dtmf_delay);
+               if (smh->mparams->dtmf_delay) {
+                       switch_rtp_set_interdigit_delay(a_engine->rtp_session, smh->mparams->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);
+                                                         "%s Set rtp dtmf delay to %u\n", switch_channel_get_name(session->channel), smh->mparams->dtmf_delay);
                        
                }
 
@@ -3322,7 +3379,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
 
                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) {
+                       if (v_engine->rtp_session && switch_channel_test_flag(session->channel, CF_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);
@@ -3357,11 +3414,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                        switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp);
 
 
-                       if (v_engine->rtp_session && params->reinvite) {
+                       if (v_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) {
                                const char *rport = NULL;
                                switch_port_t remote_rtcp_port = 0;
 
-                               params->reinvite = 0;
+                               switch_channel_clear_flag(session->channel, CF_REINVITE);
 
                                if ((rport = switch_channel_get_variable(session->channel, "sip_remote_video_rtcp_port"))) {
                                        remote_rtcp_port = (switch_port_t)atoi(rport);
@@ -3540,7 +3597,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
 
  end:
 
-       params->reinvite = 0;
+       switch_channel_clear_flag(session->channel, CF_REINVITE);
 
        switch_core_recovery_track(session);
 
@@ -3609,8 +3666,8 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
                switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->ianacodes[i]);
        }
 
-       if (smh->dtmf_type == DTMF_2833 && smh->te > 95) {
-               switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->te);
+       if (smh->dtmf_type == DTMF_2833 && smh->mparams->te > 95) {
+               switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->mparams->te);
        }
                
        if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && cng_type && use_cng) {
@@ -3679,8 +3736,8 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
 
 
        if ((smh->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || 
-                switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->te > 95) {
-               switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", smh->te, smh->te);
+                switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) {
+               switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", smh->mparams->te, smh->mparams->te);
        }
 
        if (secure) {
@@ -3878,7 +3935,7 @@ void sofia_media_set_local_sdp(switch_core_session_t *session, const char *ip, s
                        smh->ianacodes[i] = imp->ianacode;
                        
                        if (smh->ianacodes[i] > 64) {
-                               if (smh->dtmf_type == DTMF_2833 && smh->te > 95 && smh->te == smh->payload_space) {
+                               if (smh->dtmf_type == DTMF_2833 && smh->mparams->te > 95 && smh->mparams->te == smh->payload_space) {
                                        smh->payload_space++;
                                }
                                if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) &&
@@ -3978,8 +4035,8 @@ void sofia_media_set_local_sdp(switch_core_session_t *session, const char *ip, s
                switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", a_engine->codec_params.pt);
 
                if ((smh->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || 
-                        switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->te > 95) {
-                       switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", smh->te);
+                        switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) {
+                       switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", smh->mparams->te);
                }
                
                if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && smh->cng_pt && use_cng) {
@@ -4001,8 +4058,8 @@ void sofia_media_set_local_sdp(switch_core_session_t *session, const char *ip, s
 
                if ((smh->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || 
                         switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))
-                       && smh->te > 95) {
-                       switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", smh->te, smh->te);
+                       && smh->mparams->te > 95) {
+                       switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", smh->mparams->te, smh->mparams->te);
                }
                if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && smh->cng_pt && use_cng) {
                        switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d CN/8000\n", smh->cng_pt);
@@ -4262,6 +4319,491 @@ void sofia_media_set_local_sdp(switch_core_session_t *session, const char *ip, s
        switch_safe_free(buf);
 }
 
+//?
+SWITCH_DECLARE(void) switch_core_media_absorb_sdp(switch_core_session_t *session)
+{
+       const char *sdp_str;
+       switch_rtp_engine_t *a_engine;
+       switch_media_handle_t *smh;
+
+       if (!(smh = session->media_handle)) {
+               return;
+       }
+
+       a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
+
+       if ((sdp_str = switch_channel_get_variable(session->channel, SWITCH_B_SDP_VARIABLE))) {
+               sdp_parser_t *parser;
+               sdp_session_t *sdp;
+               sdp_media_t *m;
+               sdp_connection_t *connection;
+
+               if ((parser = sdp_parse(NULL, sdp_str, (int) strlen(sdp_str), 0))) {
+                       if ((sdp = sdp_session(parser))) {
+                               for (m = sdp->sdp_media; m; m = m->m_next) {
+                                       if (m->m_type != sdp_media_audio || !m->m_port) {
+                                               continue;
+                                       }
+
+                                       connection = sdp->sdp_connection;
+                                       if (m->m_connections) {
+                                               connection = m->m_connections;
+                                       }
+
+                                       if (connection) {
+                                               a_engine->codec_params.proxy_sdp_ip = switch_core_session_strdup(session, connection->c_address);
+                                       }
+                                       a_engine->codec_params.proxy_sdp_port = (switch_port_t) m->m_port;
+                                       if (a_engine->codec_params.proxy_sdp_ip && a_engine->codec_params.proxy_sdp_port) {
+                                               break;
+                                       }
+                               }
+                       }
+                       sdp_parser_free(parser);
+               }
+               switch_core_media_set_local_sdp(session, sdp_str, SWITCH_TRUE);
+       }
+}
+
+
+//?
+SWITCH_DECLARE(void) switch_core_media_set_image_sdp(switch_core_session_t *session, switch_t38_options_t *t38_options, int insist)
+{
+       char buf[2048] = "";
+       char max_buf[128] = "";
+       char max_data[128] = "";
+       const char *ip;
+       uint32_t port;
+       const char *family = "IP4";
+       const char *username;
+       const char *bit_removal_on = "a=T38FaxFillBitRemoval\n";
+       const char *bit_removal_off = "";
+       
+       const char *mmr_on = "a=T38FaxTranscodingMMR\n";
+       const char *mmr_off = "";
+
+       const char *jbig_on = "a=T38FaxTranscodingJBIG\n";
+       const char *jbig_off = "";
+       const char *var;
+       int broken_boolean;
+       switch_media_handle_t *smh;
+       switch_rtp_engine_t *a_engine;
+
+       if (!(smh = session->media_handle)) {
+               return;
+       }
+
+       a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
+
+
+       switch_assert(t38_options);
+
+       ip = t38_options->local_ip;
+       port = t38_options->local_port;
+       username = smh->mparams->sdp_username;
+
+       //sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
+
+       var = switch_channel_get_variable(session->channel, "t38_broken_boolean");
+       
+       broken_boolean = switch_true(var);
+
+
+       if (!ip) {
+               if (!(ip = a_engine->codec_params.adv_sdp_ip)) {
+                       ip = a_engine->codec_params.proxy_sdp_ip;
+               }
+       }
+
+       if (!ip) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO IP!\n", switch_channel_get_name(session->channel));
+               return;
+       }
+
+       if (!port) {
+               if (!(port = a_engine->codec_params.adv_sdp_port)) {
+                       port = a_engine->codec_params.proxy_sdp_port;
+               }
+       }
+
+       if (!port) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO PORT!\n", switch_channel_get_name(session->channel));
+               return;
+       }
+
+       if (!smh->owner_id) {
+               smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) - port;
+       }
+
+       if (!smh->session_id) {
+               smh->session_id = smh->owner_id;
+       }
+
+       smh->session_id++;
+
+       family = strchr(ip, ':') ? "IP6" : "IP4";
+
+
+       switch_snprintf(buf, sizeof(buf),
+                                       "v=0\n"
+                                       "o=%s %010u %010u IN %s %s\n"
+                                       "s=%s\n" "c=IN %s %s\n" "t=0 0\n", username, smh->owner_id, smh->session_id, family, ip, username, family, ip);
+
+       if (t38_options->T38FaxMaxBuffer) {
+               switch_snprintf(max_buf, sizeof(max_buf), "a=T38FaxMaxBuffer:%d\n", t38_options->T38FaxMaxBuffer);
+       };
+
+       if (t38_options->T38FaxMaxDatagram) {
+               switch_snprintf(max_data, sizeof(max_data), "a=T38FaxMaxDatagram:%d\n", t38_options->T38FaxMaxDatagram);
+       };
+
+
+       
+
+       if (broken_boolean) {
+               bit_removal_on = "a=T38FaxFillBitRemoval:1\n";
+               bit_removal_off = "a=T38FaxFillBitRemoval:0\n";
+
+               mmr_on = "a=T38FaxTranscodingMMR:1\n";
+               mmr_off = "a=T38FaxTranscodingMMR:0\n";
+
+               jbig_on = "a=T38FaxTranscodingJBIG:1\n";
+               jbig_off = "a=T38FaxTranscodingJBIG:0\n";
+
+       }
+       
+
+       switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                                       "m=image %d udptl t38\n"
+                                       "a=T38FaxVersion:%d\n"
+                                       "a=T38MaxBitRate:%d\n"
+                                       "%s"
+                                       "%s"
+                                       "%s"
+                                       "a=T38FaxRateManagement:%s\n"
+                                       "%s"
+                                       "%s"
+                                       "a=T38FaxUdpEC:%s\n",
+                                       //"a=T38VendorInfo:%s\n",
+                                       port,
+                                       t38_options->T38FaxVersion,
+                                       t38_options->T38MaxBitRate,
+                                       t38_options->T38FaxFillBitRemoval ? bit_removal_on : bit_removal_off,
+                                       t38_options->T38FaxTranscodingMMR ? mmr_on : mmr_off,
+                                       t38_options->T38FaxTranscodingJBIG ? jbig_on : jbig_off,
+                                       t38_options->T38FaxRateManagement,
+                                       max_buf,
+                                       max_data,
+                                       t38_options->T38FaxUdpEC
+                                       //t38_options->T38VendorInfo ? t38_options->T38VendorInfo : "0 0 0"
+                                       );
+
+
+
+       if (insist) {
+               switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "m=audio 0 RTP/AVP 19\n");
+       }
+
+       switch_core_media_set_local_sdp(session, buf, SWITCH_TRUE);
+
+
+       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s image media sdp:\n%s\n",
+                                         switch_channel_get_name(session->channel), smh->mparams->local_sdp_str);
+
+
+}
+
+
+
+//?
+SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session)
+{
+       switch_size_t len;
+       char *p, *q, *pe, *qe;
+       int has_video = 0, has_audio = 0, has_ip = 0;
+       char port_buf[25] = "";
+       char vport_buf[25] = "";
+       char *new_sdp;
+       int bad = 0;
+       switch_media_handle_t *smh;
+       switch_rtp_engine_t *a_engine, *v_engine;
+
+       if (!(smh = session->media_handle)) {
+               return;
+       }
+
+       a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
+       v_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
+
+       if (zstr(smh->mparams->local_sdp_str)) {
+               return;
+       }
+
+       len = strlen(smh->mparams->local_sdp_str) * 2;
+
+       if (switch_channel_test_flag(session->channel, CF_ANSWERED) &&
+               (switch_stristr("sendonly", smh->mparams->local_sdp_str) || switch_stristr("0.0.0.0", smh->mparams->local_sdp_str))) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Skip patch on hold SDP\n");
+               return;
+       }
+
+       if (zstr(a_engine->codec_params.local_sdp_ip) || !a_engine->codec_params.local_sdp_port) {
+               if (switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 1) != SWITCH_STATUS_SUCCESS) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s I/O Error\n",
+                                                         switch_channel_get_name(session->channel));
+                       return;
+               }
+               a_engine->codec_params.iananame = switch_core_session_strdup(session, "PROXY");
+               a_engine->codec_params.rm_rate = 8000;
+               a_engine->codec_params.codec_ms = 20;
+       }
+
+       new_sdp = switch_core_session_alloc(session, len);
+       switch_snprintf(port_buf, sizeof(port_buf), "%u", a_engine->codec_params.local_sdp_port);
+
+
+       p = smh->mparams->local_sdp_str;
+       q = new_sdp;
+       pe = p + strlen(p);
+       qe = q + len - 1;
+
+
+       while (p && *p) {
+               if (p >= pe) {
+                       bad = 1;
+                       goto end;
+               }
+
+               if (q >= qe) {
+                       bad = 2;
+                       goto end;
+               }
+
+               if (a_engine->codec_params.local_sdp_ip && !strncmp("c=IN IP", p, 7)) {
+                       strncpy(q, p, 7);
+                       p += 7;
+                       q += 7;
+                       strncpy(q, strchr(a_engine->codec_params.local_sdp_ip, ':') ? "6 " : "4 ", 2);
+                       p +=2;
+                       q +=2;                  
+                       strncpy(q, a_engine->codec_params.local_sdp_ip, strlen(a_engine->codec_params.local_sdp_ip));
+                       q += strlen(a_engine->codec_params.local_sdp_ip);
+
+                       while (p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'A' && *p <= 'F') || (*p >= 'a' && *p <= 'f'))) {
+                               if (p >= pe) {
+                                       bad = 3;
+                                       goto end;
+                               }
+                               p++;
+                       }
+
+                       has_ip++;
+
+               } else if (!strncmp("o=", p, 2)) {
+                       char *oe = strchr(p, '\n');
+                       switch_size_t len;
+
+                       if (oe) {
+                               const char *family = "IP4";
+                               char o_line[1024] = "";
+
+                               if (oe >= pe) {
+                                       bad = 5;
+                                       goto end;
+                               }
+
+                               len = (oe - p);
+                               p += len;
+
+
+                               family = strchr(smh->mparams->sipip, ':') ? "IP6" : "IP4";
+
+                               if (!smh->owner_id) {
+                                       smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) * 31821U + 13849U;
+                               }
+
+                               if (!smh->session_id) {
+                                       smh->session_id = smh->owner_id;
+                               }
+
+                               smh->session_id++;
+
+
+                               snprintf(o_line, sizeof(o_line), "o=%s %010u %010u IN %s %s\n",
+                                                smh->mparams->sdp_username, smh->owner_id, smh->session_id, family, smh->mparams->sipip);
+
+                               strncpy(q, o_line, strlen(o_line));
+                               q += strlen(o_line) - 1;
+
+                       }
+
+               } else if (!strncmp("s=", p, 2)) {
+                       char *se = strchr(p, '\n');
+                       switch_size_t len;
+
+                       if (se) {
+                               char s_line[1024] = "";
+
+                               if (se >= pe) {
+                                       bad = 5;
+                                       goto end;
+                               }
+
+                               len = (se - p);
+                               p += len;
+
+                               snprintf(s_line, sizeof(s_line), "s=%s\n", smh->mparams->sdp_username);
+
+                               strncpy(q, s_line, strlen(s_line));
+                               q += strlen(s_line) - 1;
+
+                       }
+
+               } else if ((!strncmp("m=audio ", p, 8) && *(p + 8) != '0') || (!strncmp("m=image ", p, 8) && *(p + 8) != '0')) {
+                       strncpy(q, p, 8);
+                       p += 8;
+
+                       if (p >= pe) {
+                               bad = 4;
+                               goto end;
+                       }
+
+
+                       q += 8;
+
+                       if (q >= qe) {
+                               bad = 5;
+                               goto end;
+                       }
+
+
+                       strncpy(q, port_buf, strlen(port_buf));
+                       q += strlen(port_buf);
+
+                       if (q >= qe) {
+                               bad = 6;
+                               goto end;
+                       }
+
+                       while (p && *p && (*p >= '0' && *p <= '9')) {
+                               if (p >= pe) {
+                                       bad = 7;
+                                       goto end;
+                               }
+                               p++;
+                       }
+
+                       has_audio++;
+
+               } else if (!strncmp("m=video ", p, 8) && *(p + 8) != '0') {
+                       if (!has_video) {
+                               switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1);
+                               v_engine->codec_params.rm_encoding = "PROXY-VID";
+                               v_engine->codec_params.rm_rate = 90000;
+                               v_engine->codec_params.codec_ms = 0;
+                               switch_snprintf(vport_buf, sizeof(vport_buf), "%u", v_engine->codec_params.adv_sdp_port);
+                               if (switch_channel_media_ready(session->channel) && !switch_rtp_ready(v_engine->rtp_session)) {
+                                       switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE);
+                                       switch_channel_set_flag(session->channel, CF_REINVITE);
+                                       switch_core_media_activate_rtp(session);
+                               }
+                       }
+
+                       strncpy(q, p, 8);
+                       p += 8;
+
+                       if (p >= pe) {
+                               bad = 8;
+                               goto end;
+                       }
+
+                       q += 8;
+
+                       if (q >= qe) {
+                               bad = 9;
+                               goto end;
+                       }
+
+                       strncpy(q, vport_buf, strlen(vport_buf));
+                       q += strlen(vport_buf);
+
+                       if (q >= qe) {
+                               bad = 10;
+                               goto end;
+                       }
+
+                       while (p && *p && (*p >= '0' && *p <= '9')) {
+
+                               if (p >= pe) {
+                                       bad = 11;
+                                       goto end;
+                               }
+
+                               p++;
+                       }
+
+                       has_video++;
+               }
+
+               while (p && *p && *p != '\n') {
+
+                       if (p >= pe) {
+                               bad = 12;
+                               goto end;
+                       }
+
+                       if (q >= qe) {
+                               bad = 13;
+                               goto end;
+                       }
+
+                       *q++ = *p++;
+               }
+
+               if (p >= pe) {
+                       bad = 14;
+                       goto end;
+               }
+
+               if (q >= qe) {
+                       bad = 15;
+                       goto end;
+               }
+
+               *q++ = *p++;
+
+       }
+
+ end:
+
+       if (bad) {
+               return;
+       }
+
+
+       if (switch_channel_down(session->channel)) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s too late.\n", switch_channel_get_name(session->channel));
+               return;
+       }
+
+
+       if (!has_ip && !has_audio) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SDP has no audio in it.\n%s\n",
+                                                 switch_channel_get_name(session->channel), smh->mparams->local_sdp_str);
+               return;
+       }
+
+
+       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Patched SDP\n---\n%s\n+++\n%s\n",
+                                         switch_channel_get_name(session->channel), smh->mparams->local_sdp_str, new_sdp);
+
+       switch_core_media_set_local_sdp(session, new_sdp, SWITCH_FALSE);
+
+}
+
+
+
+
 
 /* For Emacs:
  * Local Variables: