[Freeswitch-svn] [commit] r2962 - in freeswitch/trunk/src: . mod/endpoints/mod_sofia

Freeswitch SVN anthm at freeswitch.org
Tue Oct 3 00:08:30 EDT 2006


Author: anthm
Date: Tue Oct  3 00:08:30 2006
New Revision: 2962

Modified:
   freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
   freeswitch/trunk/src/switch_ivr.c

Log:
adding transfer part 1

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	Tue Oct  3 00:08:30 2006
@@ -129,7 +129,8 @@
 	TFLAG_VAD = ( 1 << 13),
 	TFLAG_TIMER = (1 << 14),
 	TFLAG_READY = (1 << 15),
-	TFLAG_REINVITE = (1 << 16)
+	TFLAG_REINVITE = (1 << 16),
+	TFLAG_REFER = (1 << 17)
 } TFLAGS;
 
 static struct {
@@ -311,6 +312,14 @@
                         sip_t const *sip,
                         tagi_t tags[]);
 
+
+static void sip_i_refer(nua_t *nua,
+						sofia_profile_t *profile,
+						nua_handle_t *nh,
+						sofia_private_t *sofia_private,
+						sip_t const *sip,
+						tagi_t tags[]);
+
 static void sip_i_invite(nua_t *nua,
                          sofia_profile_t *profile,
                          nua_handle_t *nh,
@@ -1794,11 +1803,24 @@
 		break;
 	case nua_callstate_completed:
 		if (tech_pvt && r_sdp) {
+			sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0);
+			sdp_session_t *sdp;
+			uint8_t match = 0;
+
+			if (tech_pvt->num_codecs) {
+				if ((sdp = sdp_session(parser))) {
+					match = negotiate_sdp(session, sdp);
+				}
+			}
 			tech_choose_port(tech_pvt);
 			set_local_sdp(tech_pvt);
 			tech_set_codec(tech_pvt);
 			switch_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+			activate_rtp(tech_pvt);
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Processing Reinvite\n");
+			if (parser) {
+				sdp_parser_free(parser);
+			}
 		}
 		break;
 	case nua_callstate_ready:
@@ -2130,6 +2152,107 @@
 
 
 
+/*---------------------------------------*/
+static void sip_i_refer(nua_t *nua,
+						sofia_profile_t *profile,
+						nua_handle_t *nh,
+						sofia_private_t *sofia_private,
+						sip_t const *sip,
+						tagi_t tags[])
+{
+	/* Incoming refer */
+	sip_from_t const *from;
+	sip_to_t const *to;
+	sip_refer_to_t const *refer_to;
+	char *refer_to_str;
+	switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
+
+	if (session) {
+		private_object_t *tech_pvt = NULL;
+#ifdef this_was_done
+		char *dest;
+		private_object_t *ntech_pvt;
+		switch_core_session_t *nsession;
+		switch_channel_t *channel, *nchannel;
+		switch_caller_profile_t *caller_profile = NULL, *outbound_profile = NULL;
+#endif
+
+		tech_pvt = switch_core_session_get_private(session);
+		from = sip->sip_from;
+		to = sip->sip_to;
+		refer_to = sip->sip_refer_to;
+
+
+		if ((refer_to_str = sip_header_as_string(tech_pvt->home, (sip_header_t*)refer_to))) {
+			char *exten = switch_core_session_strdup(session, refer_to_str);
+			char *p;
+
+			if ((p = strchr(exten, ':'))) {
+				*p++ = '\0';
+				exten = p;
+			}
+
+			if ((p = strchr(exten, '@'))) {
+				switch_channel_t *channel = switch_core_session_get_channel(session);
+				char *br;
+				
+				*p = '\0';
+				if ((br = switch_channel_get_variable(channel, "BRIDGETO"))) {
+					switch_core_session_t *bsession;
+					
+					if ((bsession = switch_core_session_locate(br))) {
+						switch_ivr_session_transfer(bsession, exten, profile->dialplan, profile->context);
+						switch_core_session_rwunlock(bsession);
+					}
+				}
+
+
+			}
+
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "refer to " URL_PRINT_FORMAT " from %s%s" URL_PRINT_FORMAT " to %s\n", 
+							  URL_PRINT_ARGS(from->a_url),
+							  from->a_display ? from->a_display : "", from->a_display ? " " : "",
+							  URL_PRINT_ARGS(from->a_url),
+							  refer_to_str
+							  );
+			
+			su_free(tech_pvt->home, refer_to_str);
+		}
+
+#ifdef this_was_done
+		if (!(nsession = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n");
+			goto done;
+		}
+
+		if (!(ntech_pvt = (struct private_object *) switch_core_session_alloc(nsession, sizeof(*ntech_pvt)))) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n");
+			terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
+			goto done;
+		}
+		ntech_pvt->dest = switch_core_session_strdup(nsession, refer_to_str);
+		dest = ntech_pvt->dest + 4;
+		channel = switch_core_session_get_channel(session);
+		outbound_profile = switch_channel_get_caller_profile(channel);
+		nchannel = switch_core_session_get_channel(nsession);
+		attach_private(nsession, profile, ntech_pvt, dest);	
+		caller_profile = switch_caller_profile_clone(nsession, outbound_profile);
+		caller_profile->destination_number = switch_core_session_strdup(nsession, dest);
+		switch_channel_set_caller_profile(nchannel, caller_profile);
+		switch_channel_set_flag(nchannel, CF_OUTBOUND);
+		switch_set_flag_locked(ntech_pvt, TFLAG_OUTBOUND);
+		switch_set_flag_locked(ntech_pvt, TFLAG_REFER);
+		switch_channel_set_state(nchannel, CS_INIT);
+		switch_channel_set_variable(channel, "endpoint_disposition", "OUTBOUND_REFER");
+		switch_core_session_thread_launch(nsession);
+#endif
+
+		//done:
+		return;
+	}
+
+}
+
 static void sip_i_invite(nua_t *nua, 
 						 sofia_profile_t *profile,
 						 nua_handle_t *nh, 
@@ -2138,6 +2261,7 @@
 						 tagi_t tags[])
 {
 	switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
+	//refer_handle_t *refer = sofia_private ? sofia_private->refer : NULL;
 	char key[128] = "";
 
 	if (!session) {
@@ -2155,8 +2279,8 @@
 			sip_to_t const *to = sip->sip_to;
 			char *displayname;
 			char username[256];
+			char *url_user = (char *) from->a_url->url_user;
 
-
 			if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
 				terminate_session(&session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
@@ -2167,17 +2291,25 @@
 				tech_pvt->key = switch_core_session_strdup(session, key);
 			}
 
-			displayname = switch_core_session_strdup(session, (char *) from->a_display);
-			if (*displayname == '"') {
-				char *p;
+			if (switch_strlen_zero(url_user)) {
+				url_user = "service";
+			}
+			
+			if (!switch_strlen_zero(from->a_display)) {
+				displayname = switch_core_session_strdup(session, (char *) from->a_display);
+				if (*displayname == '"') {
+					char *p;
 				
-				displayname++;
-				if ((p = strchr(displayname, '"'))) {
-					*p = '\0';
+					displayname++;
+					if ((p = strchr(displayname, '"'))) {
+						*p = '\0';
+					}
 				}
+			} else {
+				displayname = url_user;
 			}
 			
-			snprintf(username, sizeof(username), "%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
+			snprintf(username, sizeof(username), "%s@%s", url_user, (char *) from->a_url->url_host);
 			attach_private(session, profile, tech_pvt, username);
 
 			snprintf(username, sizeof(username), "sip:%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
@@ -2231,6 +2363,7 @@
 {
 	outbound_reg_t *oreg = NULL;
 	sip_www_authenticate_t const *authenticate = NULL;
+	switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
 
 	if (sofia_private) {
 		if (sofia_private->oreg) {
@@ -2239,10 +2372,23 @@
 			/* NOTE
 			   this is a linked list, when nua_identity comes 
 			   we need to actually pick the right one...
-			 */
+			*/
 			oreg = profile->registrations;
 		}
 	} 
+
+
+	if (session) {
+		private_object_t *tech_pvt;
+		if ((tech_pvt = switch_core_session_get_private(session)) && switch_test_flag(tech_pvt, TFLAG_REFER)) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "received reply from refer\n");
+			
+			if (status == 200) {
+				//crap
+			}
+			return;
+		}
+	}
 	
 	if (!oreg) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No authentication available!\n");
@@ -2303,6 +2449,7 @@
 	struct private_object *tech_pvt = NULL;
 	auth_res_t auth_res = AUTH_FORBIDDEN;
 	switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
+	
 
 	if (session) {
 		if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
@@ -2312,10 +2459,9 @@
 		tech_pvt = switch_core_session_get_private(session);
 	}
 
-
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d][%s] %s\n",
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d][%s] session: %s\n",
 					  nua_event_name (event), status, phrase,
-					  session ? switch_channel_get_name(switch_core_session_get_channel(session)) : "no session"
+					  session ? switch_channel_get_name(switch_core_session_get_channel(session)) : "n/a"
 					  );
 
 	if ((profile->pflags & PFLAG_AUTH_ALL) && tech_pvt && tech_pvt->key && sip) {
@@ -2410,7 +2556,7 @@
 		break;
 
 	case nua_i_refer:
-		//sip_i_refer(nua, profile, nh, sofia_private, sip, tags);
+		sip_i_refer(nua, profile, nh, sofia_private, sip, tags);
 		break;
      
 	case nua_r_subscribe:
@@ -2539,6 +2685,7 @@
 				   NUTAG_AUTOALERT(0),
 				   //NUTAG_AUTOTRYING(0),
 				   NUTAG_ALLOW("REGISTER"),
+				   NUTAG_ALLOW("REFER"),
 				   SIPTAG_SUPPORTED_STR("100rel, precondition"),
 				   TAG_END());
 				   
@@ -2770,7 +2917,7 @@
 				}
 
 				if (!profile->dialplan) {
-					profile->dialplan = switch_core_strdup(profile->pool, "default");
+					profile->dialplan = switch_core_strdup(profile->pool, "XML");
 				}
 
 				if (!profile->sipdomain) {

Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c	(original)
+++ freeswitch/trunk/src/switch_ivr.c	Tue Oct  3 00:08:30 2006
@@ -1372,6 +1372,7 @@
 	msg.from = __FILE__;
 	switch_core_session_receive_message(session_a, &msg);
 
+	switch_channel_set_variable(chan_a, "BRIDGETO", NULL);
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a));
 
 	switch_channel_clear_flag(chan_a, CF_BRIDGED);
@@ -2110,6 +2111,9 @@
 		switch_core_session_receive_message(session, &msg);
 
 		if (switch_core_session_read_lock(peer_session) == SWITCH_STATUS_SUCCESS) {
+			switch_channel_set_variable(caller_channel, "BRIDGETO", switch_core_session_get_uuid(peer_session));
+			switch_channel_set_variable(peer_channel, "BRIDGETO", switch_core_session_get_uuid(session));
+
 			switch_channel_set_private(peer_channel, "_bridge_", other_audio_thread);
 			switch_channel_set_state(peer_channel, CS_LOOPBACK);
 			audio_bridge_thread(NULL, (void *) this_audio_thread);



More information about the Freeswitch-svn mailing list