[Freeswitch-svn] [commit] r2300 - in freeswitch/trunk/src: . include

Freeswitch SVN anthm at freeswitch.org
Tue Aug 15 15:38:15 EDT 2006


Author: anthm
Date: Tue Aug 15 15:38:14 2006
New Revision: 2300

Modified:
   freeswitch/trunk/src/include/switch_ivr.h
   freeswitch/trunk/src/switch_ivr.c

Log:
setting waypoint

Modified: freeswitch/trunk/src/include/switch_ivr.h
==============================================================================
--- freeswitch/trunk/src/include/switch_ivr.h	(original)
+++ freeswitch/trunk/src/include/switch_ivr.h	Tue Aug 15 15:38:14 2006
@@ -164,6 +164,16 @@
 													  void *buf,
 													  unsigned int buflen);
 
+/*!
+  \brief Make an outgoing call
+  \param session originating session
+  \param bleg B leg session
+  \param bridgeto the desired remote callstring
+  \return SWITCH_STATUS_SUCCESS if bleg is a running session.
+*/
+SWITCH_DECLARE(switch_status_t) switch_ivr_outcall(switch_core_session_t *session,
+                                                   switch_core_session_t **bleg,
+                                                   char *bridgeto);
 
 /*!
   \brief Bridge Audio from one session to another

Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c	(original)
+++ freeswitch/trunk/src/switch_ivr.c	Tue Aug 15 15:38:14 2006
@@ -1141,6 +1141,147 @@
 };
 
 
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_outcall(switch_core_session_t *session,
+												   switch_core_session_t **bleg,
+												   char *bridgeto)
+										  
+{
+	switch_core_session_t *peer_session;
+	switch_caller_profile_t *caller_profile, *caller_caller_profile;
+	char *chan_type, *chan_data;
+	unsigned int timelimit = 60;
+	switch_channel_t *peer_channel;
+	time_t start;
+	switch_frame_t *read_frame = NULL;
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+	switch_channel_t *caller_channel = NULL;
+
+	*bleg = NULL;
+	chan_type = strdup(bridgeto);
+		
+	if ((chan_data = strchr(chan_type, '/')) != 0) {
+		*chan_data = '\0';
+		chan_data++;
+	}
+	
+	if (session) {
+		caller_channel = switch_core_session_get_channel(session);
+		assert(caller_channel != NULL);
+		caller_caller_profile = switch_channel_get_caller_profile(caller_channel);
+
+
+		caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
+												   caller_caller_profile->username,
+												   caller_caller_profile->dialplan,
+												   caller_caller_profile->caller_id_name,
+												   caller_caller_profile->caller_id_number,
+												   caller_caller_profile->network_addr, 
+												   NULL, 
+												   NULL, 
+												   caller_caller_profile->rdnis,
+												   caller_caller_profile->source,
+												   caller_caller_profile->context,
+												   chan_data);
+	} else {
+
+		caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
+												   NULL,
+												   NULL,
+												   "FreeSWITCH",
+												   "0000000000",
+												   NULL,
+												   NULL, 
+												   NULL, 
+												   NULL,
+												   __FILE__,
+												   NULL,
+												   chan_data);
+	}
+
+
+
+	if (switch_core_session_outgoing_channel(session, chan_type, caller_profile, &peer_session, NULL) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel!\n");
+		status = SWITCH_STATUS_FALSE;
+		goto done;
+	} 
+
+	peer_channel = switch_core_session_get_channel(peer_session);
+	assert(peer_channel != NULL);
+		
+	switch_channel_add_state_handler(peer_channel, &audio_bridge_peer_state_handlers);
+
+	if (switch_core_session_runing(peer_session)) {
+		switch_channel_set_state(peer_channel, CS_RING);
+	} else {
+		switch_core_session_thread_launch(peer_session);
+	}
+
+	time(&start);
+
+	for (;;) {
+		int state = switch_channel_get_state(peer_channel);
+		if (state >= CS_RING) {
+			break;
+		}
+		
+		if (caller_channel && !switch_channel_ready(caller_channel)) {
+			break;
+		}
+		
+		if ((time(NULL) - start) > (time_t)timelimit) {
+			break;
+		}
+		switch_yield(1000);
+	}
+
+	if (caller_channel) {
+		switch_channel_pre_answer(caller_channel);
+	}
+
+	while ((!caller_channel || switch_channel_ready(caller_channel)) &&
+		   !switch_channel_test_flag(peer_channel, CF_ANSWERED) &&
+		   !switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) &&
+		   ((time(NULL) - start) < (time_t)timelimit)) {
+		
+		/* read from the channel while we wait if the audio is up on it */
+		if (session && (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA))) {
+			switch_status_t status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
+			
+			if (!SWITCH_READ_ACCEPTABLE(status)) {
+				break;
+			}
+			if (read_frame) {
+				if (switch_core_session_write_frame(session, read_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
+					break;
+				}
+			}
+
+		} else {
+			switch_yield(1000);
+		}
+
+	}
+
+	if (caller_channel && switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
+		switch_channel_answer(caller_channel);
+	}
+
+	if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
+		*bleg = peer_session;
+		status = SWITCH_STATUS_SUCCESS;
+	} else {
+		switch_channel_hangup(peer_channel, SWITCH_CAUSE_NO_ANSWER);
+		status = SWITCH_STATUS_FALSE;
+	}
+
+ done:
+	free(chan_type);
+	return status;
+}
+
+
 SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_session_t *session, 
 															   switch_core_session_t *peer_session,
 															   unsigned int timelimit,



More information about the Freeswitch-svn mailing list