]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
setting waypoint
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 15 Aug 2006 19:38:14 +0000 (19:38 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 15 Aug 2006 19:38:14 +0000 (19:38 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2300 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_ivr.h
src/switch_ivr.c

index b04703e581d5d6b26a3757d80ddaaa0e8619419e..b7ae95afd89aabde2f28bddb49e245b2e87bfc12 100644 (file)
@@ -164,6 +164,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
                                                                                                          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
index af427eade6fdfd1bc16ebb06493d0b9b7aa4d019..d1bc77584686227a4d704aed70ba40ae56ddc6f5 100644 (file)
@@ -1141,6 +1141,147 @@ static const switch_state_handler_table_t audio_bridge_peer_state_handlers = {
 };
 
 
+
+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,