[Freeswitch-svn] [commit] r7717 - in freeswitch/trunk/src: . include mod/applications/mod_dptools mod/endpoints/mod_sofia

Freeswitch SVN anthm at freeswitch.org
Thu Feb 21 12:48:42 EST 2008


Author: anthm
Date: Thu Feb 21 12:48:41 2008
New Revision: 7717

Modified:
   freeswitch/trunk/src/include/switch_channel.h
   freeswitch/trunk/src/include/switch_types.h
   freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
   freeswitch/trunk/src/switch_core_io.c
   freeswitch/trunk/src/switch_core_session.c
   freeswitch/trunk/src/switch_core_state_machine.c
   freeswitch/trunk/src/switch_ivr.c
   freeswitch/trunk/src/switch_ivr_async.c
   freeswitch/trunk/src/switch_ivr_originate.c
   freeswitch/trunk/src/switch_pcm.c
   freeswitch/trunk/src/switch_rtp.c

Log:
fix sdp pass-thru of 200 OK in proxy mode aka (bypass_media=true)

Modified: freeswitch/trunk/src/include/switch_channel.h
==============================================================================
--- freeswitch/trunk/src/include/switch_channel.h	(original)
+++ freeswitch/trunk/src/include/switch_channel.h	Thu Feb 21 12:48:41 2008
@@ -474,7 +474,7 @@
 
 #define switch_channel_stop_broadcast(_channel)	if (switch_channel_test_flag(_channel, CF_BROADCAST)) switch_channel_set_flag(_channel, CF_BREAK | CF_STOP_BROADCAST)
 
-#define switch_channel_media_ready(_channel) ((switch_channel_test_flag(_channel, CF_ANSWERED) || switch_channel_test_flag(_channel, CF_EARLY_MEDIA)) && !switch_channel_test_flag(_channel, CF_BYPASS_MEDIA))
+#define switch_channel_media_ready(_channel) ((switch_channel_test_flag(_channel, CF_ANSWERED) || switch_channel_test_flag(_channel, CF_EARLY_MEDIA)) && !switch_channel_test_flag(_channel, CF_PROXY_MODE))
 
 /** @} */
 

Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h	(original)
+++ freeswitch/trunk/src/include/switch_types.h	Thu Feb 21 12:48:41 2008
@@ -109,6 +109,7 @@
 #define SWITCH_CACHE_SPEECH_HANDLES_VARIABLE "cache_speech_handles"
 #define SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME "__cache_speech_handles_obj__"
 #define SWITCH_BYPASS_MEDIA_VARIABLE "bypass_media"
+#define SWITCH_PROXY_MEDIA_VARIABLE "proxy_media"
 #define SWITCH_ENDPOINT_DISPOSITION_VARIABLE "endpoint_disposition"
 #define SWITCH_HOLD_MUSIC_VARIABLE "hold_music"
 #define SWITCH_EXPORT_VARS_VARIABLE "export_vars"
@@ -389,7 +390,8 @@
 	SWITCH_RTP_FLAG_PASS_RFC2833 = (1 << 14),
 	SWITCH_RTP_FLAG_AUTO_CNG = (1 << 15),
 	SWITCH_RTP_FLAG_SECURE_SEND_RESET = (1 << 16),
-	SWITCH_RTP_FLAG_SECURE_RECV_RESET = (1 << 17)
+	SWITCH_RTP_FLAG_SECURE_RECV_RESET = (1 << 17),
+	SWITCH_RTP_FLAG_PROXY_MEDIA = (1 << 18)
 } switch_rtp_flag_t;
 
 
@@ -666,7 +668,7 @@
 CF_TAGGED		= (1 << 10) - Channel is tagged
 CF_WINNER		= (1 << 11) - Channel is the winner
 CF_CONTROLLED	= (1 << 12) - Channel is under control
-CF_BYPASS_MEDIA		= (1 << 13) - Channel has no media
+CF_PROXY_MODE		= (1 << 13) - Channel has no media
 CF_SUSPEND		= (1 << 14) - Suspend i/o
 CF_EVENT_PARSE  = (1 << 15) - Suspend control events
 CF_REPEAT_STATE = (1 << 16) - Tell the state machine to repeat a state
@@ -697,7 +699,7 @@
 	CF_TAGGED = (1 << 10),
 	CF_WINNER = (1 << 11),
 	CF_CONTROLLED = (1 << 12),
-	CF_BYPASS_MEDIA = (1 << 13),
+	CF_PROXY_MODE = (1 << 13),
 	CF_SUSPEND = (1 << 14),
 	CF_EVENT_PARSE = (1 << 15),
 	CF_REPEAT_STATE = (1 << 16),
@@ -711,6 +713,7 @@
 	CF_RESET = (1 << 24),
 	CF_ORIGINATING = (1 << 25),
 	CF_STOP_BROADCAST = (1 << 26),
+	CF_PROXY_MEDIA = (1 << 27)
 } switch_channel_flag_t;
 
 
@@ -732,7 +735,8 @@
 	SFF_RAW_RTP = (1 << 1),
 	SFF_RTP_HEADER = (1 << 2),
 	SFF_PLC = (1 << 3),
-	SFF_RFC2833 = (1 << 4)
+	SFF_RFC2833 = (1 << 4),
+	SFF_PROXY_PACKET = (1 << 5)
 } switch_frame_flag_t;
 
 

Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	Thu Feb 21 12:48:41 2008
@@ -1228,14 +1228,18 @@
 	}
 
 	continue_on_fail = switch_channel_get_variable(caller_channel, "continue_on_fail");
-
-	if (switch_channel_test_flag(caller_channel, CF_BYPASS_MEDIA)
+	
+	if ((var = switch_channel_get_variable(caller_channel, SWITCH_PROXY_MEDIA_VARIABLE)) && switch_true(var)) {
+		switch_channel_set_flag(caller_channel, CF_PROXY_MEDIA);
+	}
+	
+	if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)
 		|| ((var = switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_VARIABLE)) && switch_true(var))) {
 		if (!switch_channel_test_flag(caller_channel, CF_ANSWERED)
 			&& !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
-			switch_channel_set_flag(caller_channel, CF_BYPASS_MEDIA);
+			switch_channel_set_flag(caller_channel, CF_PROXY_MODE);
 		} else {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Channel is already up, delaying point-to-point mode 'till both legs are up.\n");
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Channel is already up, delaying proxy mode 'till both legs are up.\n");
 			no_media_bridge = 1;
 		}
 	}
@@ -1292,12 +1296,12 @@
 				}
 			}
 
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Redirecting media to point-to-point mode.\n");
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Redirecting media to proxy mode.\n");
 			switch_ivr_nomedia(switch_core_session_get_uuid(session), SMF_FORCE);
 			switch_ivr_nomedia(switch_core_session_get_uuid(peer_session), SMF_FORCE);
 			switch_ivr_signal_bridge(session, peer_session);
 		} else {
-			if (switch_channel_test_flag(caller_channel, CF_BYPASS_MEDIA)) {
+			if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
 				switch_ivr_signal_bridge(session, peer_session);
 			} else {
 				switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL);

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	Thu Feb 21 12:48:41 2008
@@ -80,7 +80,7 @@
 	tech_pvt->read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
 
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s SOFIA INIT\n", switch_channel_get_name(channel));
-	if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+	if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
 		sofia_glue_tech_absorb_sdp(tech_pvt);
 	}
 
@@ -340,11 +340,17 @@
 
 	switch_set_flag_locked(tech_pvt, TFLAG_ANS);
 
-	if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+	if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
 		const char *sdp = NULL;
 		if ((sdp = switch_channel_get_variable(channel, SWITCH_B_SDP_VARIABLE))) {
 			tech_pvt->local_sdp_str = switch_core_session_strdup(session, sdp);
 		}
+		if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
+			sofia_glue_tech_patch_sdp(tech_pvt);
+			if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
+				return SWITCH_STATUS_FALSE;
+			}
+		}
 	} else {
 		if (switch_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)) {
 			switch_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION);
@@ -360,7 +366,7 @@
 			}
 		}
 
-		if ((status = sofia_glue_tech_choose_port(tech_pvt)) != SWITCH_STATUS_SUCCESS) {
+		if ((status = sofia_glue_tech_choose_port(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
 			switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 			return status;
 		}
@@ -612,7 +618,7 @@
 
 	switch_set_flag_locked(tech_pvt, TFLAG_WRITING);
 
-	if (!switch_test_flag(frame, SFF_CNG)) {
+	if (!switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) {
 		if (tech_pvt->read_codec.implementation->encoded_bytes_per_frame) {
 			bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
 			frames = ((int) frame->datalen / bytes);
@@ -758,7 +764,7 @@
 			switch_channel_t *other_channel;
 			const char *ip = NULL, *port = NULL;
 			
-			switch_channel_set_flag(channel, CF_BYPASS_MEDIA);
+			switch_channel_set_flag(channel, CF_PROXY_MODE);
 			tech_pvt->local_sdp_str = NULL;
 			if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
 				&& (other_session = switch_core_session_locate(uuid))) {
@@ -790,11 +796,11 @@
 		{
 			uint32_t count = 0;
 
-			switch_channel_clear_flag(channel, CF_BYPASS_MEDIA);
+			switch_channel_clear_flag(channel, CF_PROXY_MODE);
 			tech_pvt->local_sdp_str = NULL;
 			if (!switch_rtp_ready(tech_pvt->rtp_session)) {
 				sofia_glue_tech_prepare_codecs(tech_pvt);
-				if ((status = sofia_glue_tech_choose_port(tech_pvt)) != SWITCH_STATUS_SUCCESS) {
+				if ((status = sofia_glue_tech_choose_port(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
 					switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 					return status;
 				}
@@ -957,10 +963,10 @@
 
 				if (!switch_strlen_zero(((char *)msg->pointer_arg))) {
 					nua_respond(tech_pvt->nh, code, reason, SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-					SOATAG_USER_SDP_STR(msg->pointer_arg),
-					SOATAG_AUDIO_AUX("cn telephone-event"),
-					NUTAG_INCLUDE_EXTRA_SDP(1),
-					TAG_END());
+								SOATAG_USER_SDP_STR(msg->pointer_arg),
+								SOATAG_AUDIO_AUX("cn telephone-event"),
+								NUTAG_INCLUDE_EXTRA_SDP(1),
+								TAG_END());
 				} else {
 					nua_respond(tech_pvt->nh, code, reason, SIPTAG_CONTACT_STR(tech_pvt->reply_contact), TAG_END());
 				}
@@ -986,11 +992,17 @@
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Asked to send early media by %s\n", msg->from);
 				
 				/* Transmit 183 Progress with SDP */
-				if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+				if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
 					const char *sdp = NULL;
 					if ((sdp = switch_channel_get_variable(channel, SWITCH_B_SDP_VARIABLE))) {
 						tech_pvt->local_sdp_str = switch_core_session_strdup(session, sdp);
 					}
+					if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
+						sofia_glue_tech_patch_sdp(tech_pvt);
+						if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
+							return SWITCH_STATUS_FALSE;
+						}
+					}
 				} else {
 					if (switch_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)) {
 						switch_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION);
@@ -1008,7 +1020,7 @@
 						}
 					}
 
-					if ((status = sofia_glue_tech_choose_port(tech_pvt)) != SWITCH_STATUS_SUCCESS) {
+					if ((status = sofia_glue_tech_choose_port(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
 						switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 						return status;
 					}

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h	Thu Feb 21 12:48:41 2008
@@ -165,7 +165,8 @@
 	TFLAG_SDP = (1 << 25),
 	TFLAG_VIDEO = (1 << 26),
 	TFLAG_TPORT_LOG = (1 << 27),
-	TFLAG_SENT_UPDATE = (1 << 28)
+	TFLAG_SENT_UPDATE = (1 << 28),
+	TFLAG_PROXY_MEDIA = (1 << 29)
 } TFLAGS;
 
 struct mod_sofia_globals {
@@ -341,6 +342,7 @@
 	char *fmtp_out;
 	char *remote_sdp_str;
 	char *local_sdp_str;
+	char *orig_local_sdp_str;
 	char *dest;
 	char *dest_to;
 	char *key;
@@ -439,7 +441,7 @@
 
 void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *profile, private_object_t *tech_pvt, const char *channame);
 
-switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt);
+switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int force);
 
 switch_status_t sofia_glue_do_invite(switch_core_session_t *session);
 
@@ -584,3 +586,4 @@
 int sofia_glue_transport_has_tls(const sofia_transport_t tp);
 const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name);
 switch_status_t sofia_glue_build_crypto(private_object_t *tech_pvt, int index, switch_rtp_crypto_key_type_t type, switch_rtp_crypto_direction_t direction);
+void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt);

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	Thu Feb 21 12:48:41 2008
@@ -971,6 +971,8 @@
 						switch_set_flag(profile, TFLAG_INB_NOMEDIA);
 					} else if (!strcasecmp(var, "inbound-late-negotiation") && switch_true(val)) {
 						switch_set_flag(profile, TFLAG_LATE_NEGOTIATION);
+					} else if (!strcasecmp(var, "inbound-proxy-media") && switch_true(val)) {
+						switch_set_flag(profile, TFLAG_PROXY_MEDIA);
 					} else if (!strcasecmp(var, "rfc2833-pt")) {
 						profile->te = (switch_payload_t) atoi(val);
 					} else if (!strcasecmp(var, "cng-pt")) {
@@ -1316,7 +1318,7 @@
 		const char *uuid;
 		switch_core_session_t *other_session;
 
-		if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+		if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
 			private_object_t *tech_pvt = switch_core_session_get_private(session);
 			switch_assert(tech_pvt != NULL);
 
@@ -1330,9 +1332,14 @@
 				const char *r_sdp = NULL;
 				switch_core_session_message_t msg = { 0 };
 			
+				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)) {
+					r_sdp = sip->sip_payload->pl_data;
+					printf("WOOT\n%s\n", r_sdp);
+				}
+
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Passing %d %s to other leg\n", status, phrase);
 				
-				tl_gets(tags, SOATAG_REMOTE_SDP_STR_REF(r_sdp), TAG_END());
 				msg.message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
 				msg.from = __FILE__;
 				msg.numeric_arg = status;
@@ -1493,7 +1500,7 @@
 			if (status == 180) {
 				switch_channel_mark_ring_ready(channel);
 				if (!switch_channel_test_flag(channel, CF_GEN_RINGBACK)) {
-					if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+					if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
 						if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
 							&& (other_session = switch_core_session_locate(uuid))) {
 							switch_core_session_message_t msg;
@@ -1510,10 +1517,15 @@
 			}
 
 			if (r_sdp) {
-				if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+				if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
 					switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
 					switch_channel_mark_pre_answered(channel);
 					switch_set_flag(tech_pvt, TFLAG_SDP);
+					if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
+						if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
+							goto done;
+						}
+					}
 					if (!switch_channel_test_flag(channel, CF_GEN_RINGBACK) && (uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
 						&& (other_session = switch_core_session_locate(uuid))) {
 						other_channel = switch_core_session_get_channel(other_session);
@@ -1526,7 +1538,9 @@
 					}
 					goto done;
 				} else {
-					if (switch_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && !switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
+					if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && !switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
+						switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA");
+					} else if (switch_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && !switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
 						switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION");
 					} else {
 						if (sofia_glue_tech_media(tech_pvt, (char *) r_sdp) != SWITCH_STATUS_SUCCESS) {
@@ -1546,7 +1560,7 @@
 	case nua_callstate_received:
 		if (tech_pvt && !switch_test_flag(tech_pvt, TFLAG_SDP)) {
 			if (r_sdp && !switch_test_flag(tech_pvt, TFLAG_SDP)) {
-				if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+				if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
 					switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOMEDIA");
 					switch_set_flag_locked(tech_pvt, TFLAG_READY);
 					if (switch_channel_get_state(channel) == CS_NEW) {
@@ -1554,6 +1568,12 @@
 					}
 					switch_set_flag(tech_pvt, TFLAG_SDP);
 					goto done;
+				} else if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
+                    switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA");
+                    switch_set_flag_locked(tech_pvt, TFLAG_READY);
+                    if (switch_channel_get_state(channel) == CS_NEW) {
+                        switch_channel_set_state(channel, CS_INIT);
+                    }
 				} else if (switch_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)) {
                     switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION");
                     switch_set_flag_locked(tech_pvt, TFLAG_READY);
@@ -1627,16 +1647,19 @@
 					switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
 				}
 			} else {
-				if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+				if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
 					goto done;
 				} else {
 					switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
-					sofia_glue_tech_choose_port(tech_pvt);
+					sofia_glue_tech_choose_port(tech_pvt, 0);
 					sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
 					switch_channel_set_state(channel, CS_HIBERNATE);
 					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_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1), TAG_END());
+								SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
+								SOATAG_AUDIO_AUX("cn telephone-event"),
+								NUTAG_INCLUDE_EXTRA_SDP(1),
+								TAG_END());
 					goto done;
 				}
 			}
@@ -1656,7 +1679,7 @@
 			uint8_t match = 0;
 
 			if (r_sdp) { 
-				if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+				if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
 					if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
 						&& (other_session = switch_core_session_locate(uuid))) {
 						switch_core_session_message_t msg = { 0 };
@@ -1681,7 +1704,7 @@
 						}
 					}
 					if (match) {
-						if (sofia_glue_tech_choose_port(tech_pvt) != SWITCH_STATUS_SUCCESS) {
+						if (sofia_glue_tech_choose_port(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
 							goto done;
 						}
 						sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
@@ -1713,7 +1736,7 @@
 			switch_set_flag_locked(tech_pvt, TFLAG_REINVITE);
 			tech_pvt->nh = tech_pvt->nh2;
 			tech_pvt->nh2 = NULL;
-			if (sofia_glue_tech_choose_port(tech_pvt) == SWITCH_STATUS_SUCCESS) {
+			if (sofia_glue_tech_choose_port(tech_pvt, 0) == SWITCH_STATUS_SUCCESS) {
 				if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
 					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cheater Reinvite RTP Error!\n");
 					switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
@@ -1740,10 +1763,15 @@
 				r_sdp = (const char *) switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
 			}
 			if (r_sdp && !switch_test_flag(tech_pvt, TFLAG_SDP)) {
-				if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+				if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
 					switch_set_flag_locked(tech_pvt, TFLAG_ANS);
 					switch_set_flag_locked(tech_pvt, TFLAG_SDP);
 					switch_channel_mark_answered(channel);
+					if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
+						if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
+							goto done;
+						}
+					}
 					if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
 						&& (other_session = switch_core_session_locate(uuid))) {
 						other_channel = switch_core_session_get_channel(other_session);
@@ -1770,7 +1798,7 @@
 
 					if (match) {
 						switch_set_flag_locked(tech_pvt, TFLAG_ANS);
-						if (sofia_glue_tech_choose_port(tech_pvt) == SWITCH_STATUS_SUCCESS) {
+						if (sofia_glue_tech_choose_port(tech_pvt, 0) == SWITCH_STATUS_SUCCESS) {
 							if (sofia_glue_activate_rtp(tech_pvt, 0) == SWITCH_STATUS_SUCCESS) {
 								switch_channel_mark_answered(channel);
 							} else {
@@ -1863,7 +1891,7 @@
 		goto done;
 	}
 
-	if (switch_channel_test_flag(channel_a, CF_BYPASS_MEDIA)) {
+	if (switch_channel_test_flag(channel_a, CF_PROXY_MODE)) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Transfer on bypass media not allowed.\n");
 		nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
 				   NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"), SIPTAG_EVENT_STR(etmp), TAG_END());
@@ -2558,7 +2586,11 @@
 	switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "INBOUND CALL");
 
 	if (switch_test_flag(tech_pvt, TFLAG_INB_NOMEDIA)) {
-		switch_channel_set_flag(channel, CF_BYPASS_MEDIA);
+		switch_channel_set_flag(channel, CF_PROXY_MODE);
+	}
+
+	if (switch_test_flag(tech_pvt, TFLAG_PROXY_MEDIA)) {
+		switch_channel_set_flag(channel, CF_PROXY_MEDIA);
 	}
 
 	if (!tech_pvt->call_id && sip->sip_call_id && sip->sip_call_id->i_id) {

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	Thu Feb 21 12:48:41 2008
@@ -54,7 +54,7 @@
 		use_cng = 0;
 	}
 
-	if (!force && !ip && !sr && switch_channel_test_flag(tech_pvt->channel, CF_BYPASS_MEDIA)) {
+	if (!force && !ip && !sr && (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA))) {
 		return;
 	}
 
@@ -321,7 +321,7 @@
 	const char *abs, *codec_string = NULL;
 	const char *ocodec = NULL;
 
-	if (switch_channel_test_flag(tech_pvt->channel, CF_BYPASS_MEDIA)) {
+	if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
 		goto end;
 	}
 
@@ -475,15 +475,22 @@
 	return NULL;
 }
 
-switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt)
+switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int force)
 {
 	char *ip = tech_pvt->profile->rtpip;
 	switch_port_t sdp_port;
 	char tmp[50];
 
-	if (switch_channel_test_flag(tech_pvt->channel, CF_BYPASS_MEDIA) || tech_pvt->adv_sdp_audio_port) {
-		return SWITCH_STATUS_SUCCESS;
+	if (!force) {
+		if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || 
+			switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) || tech_pvt->adv_sdp_audio_port) {
+			return SWITCH_STATUS_SUCCESS;
+		}
 	}
+	if (tech_pvt->adv_sdp_audio_port) {
+		switch_rtp_release_port(tech_pvt->adv_sdp_audio_ip, tech_pvt->adv_sdp_audio_port);
+	}
+
 
 	tech_pvt->local_sdp_audio_ip = ip;
 	if (!(tech_pvt->local_sdp_audio_port = switch_rtp_request_port(tech_pvt->profile->rtpip))) {
@@ -515,7 +522,7 @@
 	switch_port_t sdp_port;
 	char tmp[50];
 
-	if (switch_channel_test_flag(tech_pvt->channel, CF_BYPASS_MEDIA) || tech_pvt->adv_sdp_video_port) {
+	if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) || tech_pvt->adv_sdp_video_port) {
 		return SWITCH_STATUS_SUCCESS;
 	}
 
@@ -678,6 +685,119 @@
 	return new_uri;
 }
 
+static switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt) {
+	char rip[128] = "";
+	char rp[128] = "";
+	char *p, *ip_ptr = NULL, *port_ptr = NULL;
+	int x;
+
+	if (switch_strlen_zero(tech_pvt->remote_sdp_str)) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if ((p = (char *)switch_stristr("c=IN IP4 ", tech_pvt->remote_sdp_str))) {
+		ip_ptr = p + 9;
+	}
+
+	if ((p = (char *)switch_stristr("m=audio ", tech_pvt->remote_sdp_str))) {
+		port_ptr = p + 8;
+	}
+	
+	if (!(ip_ptr && port_ptr)) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	p = ip_ptr;
+	x = 0;
+	while(x < sizeof(rip) && p && *p && ((*p >= '0' && *p <= '9') || *p == '.')) {
+		rip[x++] = *p;
+		p++;
+	}
+
+	p = port_ptr;
+	x = 0;
+	while(x < sizeof(rp) && p && *p && (*p >= '0' && *p <= '9')) {
+		rp[x++] = *p;
+		p++;
+	}
+
+	tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, rip);
+	tech_pvt->remote_sdp_audio_port = (switch_port_t) atoi(rp);
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+
+void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt)
+{
+	switch_size_t len;
+	char *p, *q, *ip_ptr = NULL, *port_ptr = NULL;
+	int x;
+
+	if (switch_strlen_zero(tech_pvt->local_sdp_str)) {
+		return;
+	}
+
+	if (!switch_strlen_zero(tech_pvt->orig_local_sdp_str)) {
+		return;
+	}
+
+	len = strlen(tech_pvt->local_sdp_str) + 256;
+	
+	if ((p = (char *)switch_stristr("c=IN IP4 ", tech_pvt->local_sdp_str))) {
+		ip_ptr = p + 9;
+	}
+
+	if ((p = (char *)switch_stristr("m=audio ", tech_pvt->local_sdp_str))) {
+		port_ptr = p + 8;
+	}
+	
+	if (!(ip_ptr && port_ptr)) {
+		return;
+	}
+
+	if (sofia_glue_tech_choose_port(tech_pvt, 1) != SWITCH_STATUS_SUCCESS) {
+		return;
+	}
+
+	tech_pvt->orig_local_sdp_str = tech_pvt->local_sdp_str;
+	tech_pvt->local_sdp_str = switch_core_session_alloc(tech_pvt->session, len);
+	
+	q = tech_pvt->local_sdp_str;
+	p = tech_pvt->orig_local_sdp_str;
+
+	while (p && *p) {
+		if (p == ip_ptr) {
+			strncpy(q, tech_pvt->adv_sdp_audio_ip, strlen(tech_pvt->adv_sdp_audio_ip));
+			q += strlen(tech_pvt->adv_sdp_audio_ip);
+			x = 0;
+			while(p && *p && ((*p >= '0' && *p <= '9') || *p == '.')) {
+				p++;
+			}
+
+		} else if (p == port_ptr) {
+			char port_buf[25] = "";
+			
+			switch_snprintf(port_buf, sizeof(port_buf), "%u", tech_pvt->adv_sdp_audio_port);
+			strncpy(q, port_buf, strlen(port_buf));
+			q += strlen(port_buf);
+			x = 0;
+			while(p && *p && (*p >= '0' && *p <= '9')) {
+				p++;
+			}
+		}
+
+		*q++ = *p++;
+	}
+	
+	tech_pvt->iananame = switch_core_session_strdup(tech_pvt->session, "NO-NAME");
+
+	tech_pvt->rm_rate = 8000;
+	tech_pvt->codec_ms = 20;
+	
+}
+
+
 switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
 {
 	char *alert_info = NULL;
@@ -725,7 +845,7 @@
 
 	max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE);
 
-	if ((status = sofia_glue_tech_choose_port(tech_pvt)) != SWITCH_STATUS_SUCCESS) {
+	if ((status = sofia_glue_tech_choose_port(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
 		return status;
 	}
 
@@ -793,17 +913,17 @@
 			}
 		}
 
-	        if (!sofia_test_pflag(tech_pvt->profile, PFLAG_TLS) && sofia_glue_transport_has_tls(tech_pvt->transport)) {
-        	        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "TLS not supported by profile\n");
+		if (!sofia_test_pflag(tech_pvt->profile, PFLAG_TLS) && sofia_glue_transport_has_tls(tech_pvt->transport)) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "TLS not supported by profile\n");
 			return SWITCH_STATUS_FALSE;
-	        }
+		}
 
-		if (switch_strlen_zero(tech_pvt->invite_contact))
-		{
-			if (sofia_glue_transport_has_tls(tech_pvt->transport))
+		if (switch_strlen_zero(tech_pvt->invite_contact)) {
+			if (sofia_glue_transport_has_tls(tech_pvt->transport)) {
 				tech_pvt->invite_contact = tech_pvt->profile->tls_url;
-			else
+			} else {
 				tech_pvt->invite_contact = tech_pvt->profile->url;
+			}
 		}
 
 		url_str = sofia_overcome_sip_uri_weakness(session, url, tech_pvt->transport, SWITCH_TRUE);
@@ -835,6 +955,7 @@
 		} else if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)) {
 			priv = "full";
 		}
+
 		if (switch_test_flag(caller_profile, SWITCH_CPF_SCREEN)) {
 			screen = "yes";
 		}
@@ -908,6 +1029,10 @@
 		}
 	}
 
+	if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
+		sofia_glue_tech_patch_sdp(tech_pvt);
+	}
+
 	nua_invite(tech_pvt->nh,
 			   NUTAG_AUTOANSWER(0),
 			   NUTAG_SESSION_TIMER(session_timeout),
@@ -1265,11 +1390,11 @@
 	char tmp[50];
 	uint32_t rtp_timeout_sec = tech_pvt->profile->rtp_timeout_sec;
 	uint32_t rtp_hold_timeout_sec = tech_pvt->profile->rtp_hold_timeout_sec;
-	
-	switch_assert(tech_pvt != NULL);
+	char *timer_name;
 
+	switch_assert(tech_pvt != NULL);
 
-	if (switch_channel_test_flag(tech_pvt->channel, CF_BYPASS_MEDIA)) {
+	if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE)) {
 		return SWITCH_STATUS_SUCCESS;
 	}
 
@@ -1346,6 +1471,16 @@
         goto video;
 	}
 
+	if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
+		if ((status = sofia_glue_tech_proxy_remote_addr(tech_pvt)) != SWITCH_STATUS_SUCCESS) {
+			return status;
+		}
+		flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_PROXY_MEDIA | SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_DATAWAIT);
+		timer_name = NULL;
+	} else {
+		timer_name = tech_pvt->profile->timer_name;
+	}
+
 	tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip,
 										   tech_pvt->local_sdp_audio_port,
 										   tech_pvt->remote_sdp_audio_ip,
@@ -1354,7 +1489,7 @@
 										   tech_pvt->read_codec.implementation->samples_per_frame,
 										   tech_pvt->codec_ms * 1000,
 										   (switch_rtp_flag_t) flags,
-										   tech_pvt->profile->timer_name,
+										   timer_name,
 										   &err,
 										   switch_core_session_get_pool(tech_pvt->session));
 	
@@ -1519,7 +1654,7 @@
 	}
 
 	if (match) {
-		if (sofia_glue_tech_choose_port(tech_pvt) != SWITCH_STATUS_SUCCESS) {
+		if (sofia_glue_tech_choose_port(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
 			return SWITCH_STATUS_FALSE;
 		}
 		if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
@@ -2006,7 +2141,7 @@
 
 		if (!switch_test_flag(tech_pvt, TFLAG_CHANGE_MEDIA) && (switch_channel_test_flag(other_channel, CF_OUTBOUND) &&
 																switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND) &&
-																switch_channel_test_flag(tech_pvt->channel, CF_BYPASS_MEDIA))) {
+																switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE))) {
 			switch_ivr_nomedia(val, SMF_FORCE);
 			switch_set_flag_locked(tech_pvt, TFLAG_CHANGE_MEDIA);
 		}

Modified: freeswitch/trunk/src/switch_core_io.c
==============================================================================
--- freeswitch/trunk/src/switch_core_io.c	(original)
+++ freeswitch/trunk/src/switch_core_io.c	Thu Feb 21 12:48:41 2008
@@ -130,6 +130,12 @@
 	switch_assert(session != NULL);
 	switch_assert(*frame != NULL);
 
+	if (switch_test_flag(*frame, SFF_PROXY_PACKET)) {
+		/* Fast PASS! */
+		status = SWITCH_STATUS_SUCCESS;
+		goto done;
+	} 
+
 	if (switch_test_flag(*frame, SFF_CNG)) {
 		status = SWITCH_STATUS_SUCCESS;
 		if (!session->bugs) {
@@ -465,6 +471,11 @@
 		return SWITCH_STATUS_SUCCESS;
 	}
 
+	if (switch_test_flag(frame, SFF_PROXY_PACKET)) {
+		/* Fast PASS! */
+		return perform_write(session, frame, timeout, flag, stream_id);
+	}
+
 	if (switch_test_flag(frame, SFF_CNG)) {
 		if (switch_channel_test_flag(session->channel, CF_ACCEPT_CNG)) {
 			return perform_write(session, frame, timeout, flag, stream_id);

Modified: freeswitch/trunk/src/switch_core_session.c
==============================================================================
--- freeswitch/trunk/src/switch_core_session.c	(original)
+++ freeswitch/trunk/src/switch_core_session.c	Thu Feb 21 12:48:41 2008
@@ -306,8 +306,12 @@
 				switch_channel_set_variable(peer_channel, SWITCH_B_SDP_VARIABLE, val);
 			}
 
-			if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
-				switch_channel_set_flag(peer_channel, CF_BYPASS_MEDIA);
+			if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
+				switch_channel_set_flag(peer_channel, CF_PROXY_MODE);
+			}
+
+			if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
+				switch_channel_set_flag(peer_channel, CF_PROXY_MEDIA);
 			}
 
 			if (profile) {
@@ -1031,7 +1035,7 @@
 			goto done;
 		}
 
-		if (switch_channel_test_flag(session->channel, CF_BYPASS_MEDIA) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
+		if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application %s Cannot be used with NO_MEDIA mode!\n",
 							  extension->current_application->application_name);
 			status = SWITCH_STATUS_FALSE;

Modified: freeswitch/trunk/src/switch_core_state_machine.c
==============================================================================
--- freeswitch/trunk/src/switch_core_state_machine.c	(original)
+++ freeswitch/trunk/src/switch_core_state_machine.c	Thu Feb 21 12:48:41 2008
@@ -153,7 +153,7 @@
 			return;
 		}
 		
-		if (switch_channel_test_flag(session->channel, CF_BYPASS_MEDIA) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
+		if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
 			switch_ivr_media(session->uuid_str, SMF_NONE);
 			nomedia++;
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Application %s Requires media on channel %s!\n",

Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c	(original)
+++ freeswitch/trunk/src/switch_ivr.c	Thu Feb 21 12:48:41 2008
@@ -753,7 +753,7 @@
 			swap = 1;
 		}
 
-		if (switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+		if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
 			status = SWITCH_STATUS_SUCCESS;
 			switch_core_session_receive_message(session, &msg);
 
@@ -805,7 +805,7 @@
 			swap = 1;
 		}
 
-		if ((flags & SMF_FORCE) || !switch_channel_test_flag(channel, CF_BYPASS_MEDIA)) {
+		if ((flags & SMF_FORCE) || !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
 			switch_core_session_receive_message(session, &msg);
 
 			if ((flags & SMF_REBRIDGE) && (other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)) &&

Modified: freeswitch/trunk/src/switch_ivr_async.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_async.c	(original)
+++ freeswitch/trunk/src/switch_ivr_async.c	Thu Feb 21 12:48:41 2008
@@ -1696,7 +1696,7 @@
 
 	mypath = strdup(path);
 
-	if ((nomedia = switch_channel_test_flag(channel, CF_BYPASS_MEDIA))) {
+	if ((nomedia = switch_channel_test_flag(channel, CF_PROXY_MODE))) {
 		switch_ivr_media(uuid, SMF_REBRIDGE);
 	}
 		

Modified: freeswitch/trunk/src/switch_ivr_originate.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_originate.c	(original)
+++ freeswitch/trunk/src/switch_ivr_originate.c	Thu Feb 21 12:48:41 2008
@@ -278,7 +278,8 @@
 	}
 		
 	
-	if (read_codec && (ringback_data || !switch_channel_test_flag(caller_channel, CF_BYPASS_MEDIA))) {
+	if (read_codec && (ringback_data || 
+					   (!(switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA))))) {
 		if (!(pass = (uint8_t) switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
 			if (switch_core_codec_init(&write_codec,
 									   "L16",
@@ -915,7 +916,8 @@
 			}
 
 			if (session && (read_codec = switch_core_session_get_read_codec(session)) &&
-				(ringback_data || !switch_channel_test_flag(caller_channel, CF_BYPASS_MEDIA))) {
+				(ringback_data || 
+				 (!(switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA))))) {
 
 				if (!(pass = (uint8_t) switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
 					if (switch_core_codec_init(&write_codec,
@@ -1027,7 +1029,8 @@
 				}
 
 				/* read from the channel while we wait if the audio is up on it */
-				if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_BYPASS_MEDIA)) &&
+				if (session && (ringback_data || 
+								!(switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && switch_channel_test_flag(caller_channel, CF_PROXY_MODE))) &&
 					(switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA))) {
 					switch_status_t tstatus = switch_core_session_read_frame(session, &read_frame, 1000, 0);
 					
@@ -1085,7 +1088,8 @@
 				idx = IDX_CANCEL;
 			}
 
-			if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_BYPASS_MEDIA))) {
+			if (session && (ringback_data || !(switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && 
+											   switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)))) {
 				switch_core_session_reset(session, SWITCH_FALSE);
 			}
 

Modified: freeswitch/trunk/src/switch_pcm.c
==============================================================================
--- freeswitch/trunk/src/switch_pcm.c	(original)
+++ freeswitch/trunk/src/switch_pcm.c	Thu Feb 21 12:48:41 2008
@@ -93,6 +93,39 @@
 }
 
 
+
+static switch_status_t switch_nn_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
+{
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t switch_nn_encode(switch_codec_t *codec,
+										 switch_codec_t *other_codec,
+										 void *decoded_data,
+										 uint32_t decoded_data_len,
+										 uint32_t decoded_rate, void *encoded_data, uint32_t * encoded_data_len, uint32_t * encoded_rate,
+										 unsigned int *flag)
+{
+	/* NOOP indicates that the audio in is already the same as the audio out, so no conversion was necessary. */
+	return SWITCH_STATUS_NOOP;
+}
+
+static switch_status_t switch_nn_decode(switch_codec_t *codec,
+										 switch_codec_t *other_codec,
+										 void *encoded_data,
+										 uint32_t encoded_data_len,
+										 uint32_t encoded_rate, void *decoded_data, uint32_t * decoded_data_len, uint32_t * decoded_rate,
+										 unsigned int *flag)
+{
+	return SWITCH_STATUS_NOOP;
+}
+
+static switch_status_t switch_nn_destroy(switch_codec_t *codec)
+{
+	return SWITCH_STATUS_SUCCESS;
+}
+
+
 static switch_status_t switch_g711u_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
 {
 	int encoding, decoding;
@@ -261,12 +294,20 @@
 SWITCH_MODULE_LOAD_FUNCTION(core_pcm_load)
 {
 	switch_codec_interface_t *codec_interface;
-    int mpf = 10000, spf = 80, bpf = 160, ebpf = 160, bps = 128000, rate = 8000, counta, countb;
+    int mpf = 10000, spf = 80, bpf = 160, ebpf = 160, bps = 128000, rate = 8000, counta = 1, countb = 12;
     switch_payload_t ianacode[4] = { 0, 10, 117, 119 };
 
 	/* connect my internal structure to the blank pointer passed to me */
-	*module_interface = switch_loadable_module_create_module_interface(pool, "PCM");
+	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
+
+	SWITCH_ADD_CODEC(codec_interface, "NO-NAME PASS-THROUGH");
+	switch_core_codec_add_implementation(pool, codec_interface,
+										 SWITCH_CODEC_TYPE_AUDIO, 0, "NO-NAME", NULL, 8000, 8000, 0,
+										 20000, 160, 320, 320, 1, 1, 12,
+										 switch_nn_init, switch_nn_encode, switch_nn_decode, switch_nn_destroy);
+	
 	SWITCH_ADD_CODEC(codec_interface, "RAW Signed Linear (16 bit)");
+
     for (counta = 1; counta <= 3; counta++) {
         for (countb = 12; countb > 0; countb--) {
             switch_core_codec_add_implementation(pool, codec_interface,
@@ -292,6 +333,8 @@
                                          40000, 441, 882, 882, 1, 1, 1,
                                          switch_raw_init, switch_raw_encode, switch_raw_decode, switch_raw_destroy);
     
+
+
 	/* indicate that the module should continue to be loaded */
 
 	mod_g711_load(module_interface, pool);

Modified: freeswitch/trunk/src/switch_rtp.c
==============================================================================
--- freeswitch/trunk/src/switch_rtp.c	(original)
+++ freeswitch/trunk/src/switch_rtp.c	Thu Feb 21 12:48:41 2008
@@ -688,8 +688,8 @@
 	if (!switch_strlen_zero(timer_name)) {
 		if (switch_core_timer_init(&rtp_session->timer, timer_name, ms_per_packet / 1000, samples_per_interval, pool) ==
 			SWITCH_STATUS_SUCCESS) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting timer [%s] %d bytes per %dms\n", timer_name, samples_per_interval,
-							  ms_per_packet);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, 
+							  "Starting timer [%s] %d bytes per %dms\n", timer_name, samples_per_interval, ms_per_packet);
 		} else {
 			memset(&rtp_session->timer, 0, sizeof(rtp_session->timer));
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error starting timer [%s], async RTP disabled\n", timer_name);
@@ -1038,6 +1038,13 @@
 
 		bytes = sizeof(rtp_msg_t);
 		status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock, 0, (void *) &rtp_session->recv_msg, &bytes);
+
+		if (bytes && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) {
+			/* Fast PASS! */
+			*flags |= SFF_PROXY_PACKET;
+			ret = (int) bytes;
+			goto end;
+		}
 		
 		if (!SWITCH_STATUS_IS_BREAK(status) && rtp_session->timer.interval) {
 			switch_core_timer_step(&rtp_session->timer);
@@ -1785,11 +1792,26 @@
 	uint32_t len, ts = 0;
 	switch_payload_t payload;
 	rtp_msg_t *send_msg = NULL;
-
+	
 	if (!switch_rtp_ready(rtp_session) || !rtp_session->remote_addr) {
 		return -1;
 	}
 
+	if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) {
+		switch_size_t bytes;
+		
+		/* Fast PASS! */
+		if (!switch_test_flag(frame, SFF_PROXY_PACKET)) {
+			return 0;
+		}
+		bytes = frame->packetlen;
+		if (switch_socket_sendto(rtp_session->sock, rtp_session->remote_addr, 0, frame->packet, &bytes) != SWITCH_STATUS_SUCCESS) {
+			return -1;
+		}
+		return (int) bytes;
+	}
+
+
 	fwd = (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_RAW_WRITE) && switch_test_flag(frame, SFF_RAW_RTP)) ? 1 : 0;
 
 	switch_assert(frame != NULL);



More information about the Freeswitch-svn mailing list