]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
This patch adds 2 important variables to the originate subsystem
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 27 Mar 2007 17:15:10 +0000 (17:15 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 27 Mar 2007 17:15:10 +0000 (17:15 +0000)
originate_retries:
This variable controls how many times the system should retry the
entire dialstring before exiting on failure (default 1)

originate_retry_sleep_ms:
This variable controls how long in milliseconds to pause between
retries (default 1000)

*NOTE* when using the , and & symbols to call sequential or simultaneous channels in conjunction with this feature,
the *entire* dialstring will be repeated as many times as you specify in ${originate_retries}

Here is an example using the bridge application to originate the call. (The feature will also work anywhere else
an origination can be made.)

<extension name="1000">
  <condition field="destination_number" expression="^1000$">
    <action application="set" data="originate_retries=10"/>
    <action application="set" data="originate_retry_sleep_ms=1000"/>
    <action application="bridge" data="sofia/$${domain}/1000@somehost.com"/>
  </condition>
</extension>

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4776 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/switch_ivr.c

index c83b6c98134d500f782393c67777599b23f6982a..3acd993e4d5a3cab7c0b9d94390d82165f07d73a 100644 (file)
@@ -2498,7 +2498,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
        switch_frame_t *read_frame = NULL;
        switch_memory_pool_t *pool = NULL;
        int r = 0, i, and_argc = 0, or_argc = 0;
-       int32_t idx = IDX_NADA;
+       int32_t sleep_ms = 1000, try =0, retries = 1, idx = IDX_NADA;
        switch_codec_t write_codec = {0};
        switch_frame_t write_frame = {0};
        uint8_t fdata[1024], pass = 0;
@@ -2512,6 +2512,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
     switch_event_t *var_event = NULL;
        uint8_t fail_on_single_reject = 0;
        uint8_t ring_ready = 0;
+       char *loop_data = NULL;
+
        write_frame.data = fdata;
        
        *bleg = NULL;
@@ -2605,7 +2607,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
         }
     }
 
-       // When using the AND operator, the fail_on_single_reject flage may be set in order to indicate that a single
+       // When using the AND operator, the fail_on_single_reject flag may be set in order to indicate that a single
        // rejections should terminate the attempt rather than a timeout, answer, or rejection by all.
        if ((var = switch_event_get_header(var_event, "fail_on_single_reject")) && switch_true(var)) {
                fail_on_single_reject = 1;
@@ -2619,6 +2621,28 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
         early_ok = 0;
     }
 
+    if ((var_val = switch_event_get_header(var_event, "originate_retries")) && switch_true(var_val)) {
+               int32_t tmp;
+               tmp = atoi(var_val);
+               if (tmp > 0 && tmp < 101) {
+                       retries = tmp;
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, 
+                                                         "Invalid originate_retries setting of %d ignored, value must be between 1 and 100\n", tmp);
+               }
+    }
+
+    if ((var_val = switch_event_get_header(var_event, "originate_retry_sleep_ms")) && switch_true(var_val)) {
+               int32_t tmp;
+               tmp = atoi(var_val);
+               if (tmp > 500 && tmp < 60000) {
+                       sleep_ms = tmp;
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, 
+                                                         "Invalid originate_retry_sleep_ms setting of %d ignored, value must be between 500 and 60000\n", tmp);
+               }
+    }
+       
     if (!cid_name_override) {
         cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
     }
@@ -2628,517 +2652,528 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
     }
                                                         
 
-       or_argc = switch_separate_string(data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0])));
-
-       if (caller_channel && or_argc > 1 && !ringback_data) {
-               switch_channel_ring_ready(caller_channel);
-               sent_ring = 1;
-       }
-
-       for (r = 0; r < or_argc; r++) {
-               uint32_t hups;
-        reason = SWITCH_CAUSE_UNALLOCATED;
-               memset(peer_names, 0, sizeof(peer_names));
-               peer_session = NULL;
-               memset(peer_sessions, 0, sizeof(peer_sessions));
-               memset(peer_channels, 0, sizeof(peer_channels));
-               memset(caller_profiles, 0, sizeof(caller_profiles));
-               chan_type = NULL;
-               chan_data = NULL;
-               peer_channel = NULL;
-               start = 0;
-               read_frame = NULL;
-               pool = NULL;
-               pass = 0;
-               file = NULL;
-               key = NULL;
-               var = NULL;
-               to = 0;
 
-               and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
-       
-               if (caller_channel && !sent_ring && and_argc > 1 && !ringback_data) {
+       for (try = 0; try < retries; try++) {
+               switch_safe_free(loop_data);
+               assert(loop_data = strdup(data));
+               or_argc = switch_separate_string(loop_data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0])));
+               
+               if (caller_channel && or_argc > 1 && !ringback_data) {
                        switch_channel_ring_ready(caller_channel);
                        sent_ring = 1;
                }
 
-               for (i = 0; i < and_argc; i++) {
-               
-                       chan_type = peer_names[i];
-                       if ((chan_data = strchr(chan_type, '/')) != 0) {
-                               *chan_data = '\0';
-                               chan_data++;
+               for (r = 0; r < or_argc; r++) {
+                       uint32_t hups;
+                       reason = SWITCH_CAUSE_UNALLOCATED;
+                       memset(peer_names, 0, sizeof(peer_names));
+                       peer_session = NULL;
+                       memset(peer_sessions, 0, sizeof(peer_sessions));
+                       memset(peer_channels, 0, sizeof(peer_channels));
+                       memset(caller_profiles, 0, sizeof(caller_profiles));
+                       chan_type = NULL;
+                       chan_data = NULL;
+                       peer_channel = NULL;
+                       start = 0;
+                       read_frame = NULL;
+                       pool = NULL;
+                       pass = 0;
+                       file = NULL;
+                       key = NULL;
+                       var = NULL;
+                       to = 0;
+                       
+                       if (try > 0) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Originate attempt %d/%d in %d ms\n", try + 1, retries, sleep_ms);
+                               switch_yield(sleep_ms * 1000);
                        }
-       
-                       if (session) {
-                               if (!switch_channel_ready(caller_channel)) {
-                                       status = SWITCH_STATUS_FALSE;
-                                       goto done;
-                               }
 
-                               caller_caller_profile = caller_profile_override ? caller_profile_override : switch_channel_get_caller_profile(caller_channel);
-                
-                               if (!cid_name_override) {
-                                       cid_name_override = caller_caller_profile->caller_id_name;
-                               }
-                               if (!cid_num_override) {
-                                       cid_num_override = caller_caller_profile->caller_id_number;
-                               }
+                       and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
+       
+                       if (caller_channel && !sent_ring && and_argc > 1 && !ringback_data) {
+                               switch_channel_ring_ready(caller_channel);
+                               sent_ring = 1;
+                       }
 
-                               caller_profiles[i] = switch_caller_profile_new(switch_core_session_get_pool(session),
-                                                                                                                          caller_caller_profile->username,
-                                                                                                                          caller_caller_profile->dialplan,
-                                                                                                                          cid_name_override,
-                                                                                                                          cid_num_override,
-                                                                                                                          caller_caller_profile->network_addr,
-                                                                                                                          NULL,
-                                                                                                                          NULL,
-                                                                                                                          caller_caller_profile->rdnis,
-                                                                                                                          caller_caller_profile->source,
-                                                                                                                          caller_caller_profile->context,
-                                                                                                                          chan_data);
-                               caller_profiles[i]->flags = caller_caller_profile->flags;
-                               pool = NULL;
-                       } else {
-                               if (!cid_name_override) {
-                                       cid_name_override = "FreeSWITCH";
-                               }
-                               if (!cid_num_override) {
-                                       cid_num_override = "0000000000";
+                       for (i = 0; i < and_argc; i++) {
+               
+                               chan_type = peer_names[i];
+                               if ((chan_data = strchr(chan_type, '/')) != 0) {
+                                       *chan_data = '\0';
+                                       chan_data++;
                                }
+       
+                               if (session) {
+                                       if (!switch_channel_ready(caller_channel)) {
+                                               status = SWITCH_STATUS_FALSE;
+                                               goto done;
+                                       }
 
-                               if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
-                                       status = SWITCH_STATUS_TERM;
-                                       goto done;
-                               }
+                                       caller_caller_profile = caller_profile_override ? caller_profile_override : switch_channel_get_caller_profile(caller_channel);
+                
+                                       if (!cid_name_override) {
+                                               cid_name_override = caller_caller_profile->caller_id_name;
+                                       }
+                                       if (!cid_num_override) {
+                                               cid_num_override = caller_caller_profile->caller_id_number;
+                                       }
 
-                               if (caller_profile_override) {
-                                       caller_profiles[i] = switch_caller_profile_new(pool,
-                                                                                                                                  caller_profile_override->username,
-                                                                                                                                  caller_profile_override->dialplan,
-                                                                                                                                  caller_profile_override->caller_id_name,
-                                                                                                                                  caller_profile_override->caller_id_number,
-                                                                                                                                  caller_profile_override->network_addr, 
-                                                                                                                                  caller_profile_override->ani,
-                                                                                                                                  caller_profile_override->aniii,
-                                                                                                                                  caller_profile_override->rdnis,
-                                                                                                                                  caller_profile_override->source,
-                                                                                                                                  caller_profile_override->context,
-                                                                                                                                  chan_data);
-                               } else {
-                                       caller_profiles[i] = switch_caller_profile_new(pool,
-                                                                                                                                  NULL,
-                                                                                                                                  NULL,
+                                       caller_profiles[i] = switch_caller_profile_new(switch_core_session_get_pool(session),
+                                                                                                                                  caller_caller_profile->username,
+                                                                                                                                  caller_caller_profile->dialplan,
                                                                                                                                   cid_name_override,
                                                                                                                                   cid_num_override,
+                                                                                                                                  caller_caller_profile->network_addr,
                                                                                                                                   NULL,
-                                                                                                                                  NULL, 
-                                                                                                                                  NULL,
-                                                                                                                                  NULL,
-                                                                                                                                  __FILE__,
                                                                                                                                   NULL,
+                                                                                                                                  caller_caller_profile->rdnis,
+                                                                                                                                  caller_caller_profile->source,
+                                                                                                                                  caller_caller_profile->context,
                                                                                                                                   chan_data);
+                                       caller_profiles[i]->flags = caller_caller_profile->flags;
+                                       pool = NULL;
+                               } else {
+                                       if (!cid_name_override) {
+                                               cid_name_override = "FreeSWITCH";
+                                       }
+                                       if (!cid_num_override) {
+                                               cid_num_override = "0000000000";
+                                       }
+
+                                       if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
+                                               status = SWITCH_STATUS_TERM;
+                                               goto done;
+                                       }
+
+                                       if (caller_profile_override) {
+                                               caller_profiles[i] = switch_caller_profile_new(pool,
+                                                                                                                                          caller_profile_override->username,
+                                                                                                                                          caller_profile_override->dialplan,
+                                                                                                                                          caller_profile_override->caller_id_name,
+                                                                                                                                          caller_profile_override->caller_id_number,
+                                                                                                                                          caller_profile_override->network_addr, 
+                                                                                                                                          caller_profile_override->ani,
+                                                                                                                                          caller_profile_override->aniii,
+                                                                                                                                          caller_profile_override->rdnis,
+                                                                                                                                          caller_profile_override->source,
+                                                                                                                                          caller_profile_override->context,
+                                                                                                                                          chan_data);
+                                       } else {
+                                               caller_profiles[i] = switch_caller_profile_new(pool,
+                                                                                                                                          NULL,
+                                                                                                                                          NULL,
+                                                                                                                                          cid_name_override,
+                                                                                                                                          cid_num_override,
+                                                                                                                                          NULL,
+                                                                                                                                          NULL, 
+                                                                                                                                          NULL,
+                                                                                                                                          NULL,
+                                                                                                                                          __FILE__,
+                                                                                                                                          NULL,
+                                                                                                                                          chan_data);
+                                       }
                                }
-                       }
 
-                       if ((reason = switch_core_session_outgoing_channel(session, chan_type, caller_profiles[i], &peer_sessions[i], &pool)) != SWITCH_CAUSE_SUCCESS) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! cause: %s\n", switch_channel_cause2str(reason));
-                               if (pool) {
-                                       switch_core_destroy_memory_pool(&pool);
+                               if ((reason = switch_core_session_outgoing_channel(session, chan_type, caller_profiles[i], &peer_sessions[i], &pool)) != SWITCH_CAUSE_SUCCESS) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! cause: %s\n", switch_channel_cause2str(reason));
+                                       if (pool) {
+                                               switch_core_destroy_memory_pool(&pool);
+                                       }
+                                       caller_profiles[i] = NULL;
+                                       peer_channels[i] = NULL;
+                                       peer_sessions[i] = NULL;
+                                       continue;
                                }
-                               caller_profiles[i] = NULL;
-                               peer_channels[i] = NULL;
-                               peer_sessions[i] = NULL;
-                               continue;
-                       }
                        
-                       switch_core_session_read_lock(peer_sessions[i]);
-                       pool = NULL;
+                               switch_core_session_read_lock(peer_sessions[i]);
+                               pool = NULL;
        
-                       peer_channels[i] = switch_core_session_get_channel(peer_sessions[i]);
-                       assert(peer_channels[i] != NULL);
+                               peer_channels[i] = switch_core_session_get_channel(peer_sessions[i]);
+                               assert(peer_channels[i] != NULL);
 
-                       if (!table) {
-                               table = &originate_state_handlers;
-                       }
+                               if (!table) {
+                                       table = &originate_state_handlers;
+                               }
 
-                       if (table) {
-                               switch_channel_add_state_handler(peer_channels[i], table);
-                       }
+                               if (table) {
+                                       switch_channel_add_state_handler(peer_channels[i], table);
+                               }
 
-                       if (switch_core_session_running(peer_sessions[i])) {
-                               switch_channel_set_state(peer_channels[i], CS_RING);
-                       } else {
-                               switch_core_session_thread_launch(peer_sessions[i]);
+                               if (switch_core_session_running(peer_sessions[i])) {
+                                       switch_channel_set_state(peer_channels[i], CS_RING);
+                               } else {
+                                       switch_core_session_thread_launch(peer_sessions[i]);
+                               }
                        }
-               }
 
-               time(&start);
+                       time(&start);
 
-               for (;;) {
-                       uint32_t valid_channels = 0;
-                       for (i = 0; i < and_argc; i++) {
-                               int state;
+                       for (;;) {
+                               uint32_t valid_channels = 0;
+                               for (i = 0; i < and_argc; i++) {
+                                       int state;
 
-                               if (!peer_channels[i]) {
-                                       continue;
-                               }
-                               valid_channels++;
-                               state = switch_channel_get_state(peer_channels[i]);
+                                       if (!peer_channels[i]) {
+                                               continue;
+                                       }
+                                       valid_channels++;
+                                       state = switch_channel_get_state(peer_channels[i]);
                        
-                               if (state >= CS_HANGUP) {
-                                       goto notready;
-                               } else if (state >= CS_RING) {
-                                       goto endfor1;
-                               }
+                                       if (state >= CS_HANGUP) {
+                                               goto notready;
+                                       } else if (state >= CS_RING) {
+                                               goto endfor1;
+                                       }
                
-                               if (caller_channel && !switch_channel_ready(caller_channel)) {
-                                       goto notready;
-                               }
+                                       if (caller_channel && !switch_channel_ready(caller_channel)) {
+                                               goto notready;
+                                       }
                                
-                               if ((time(NULL) - start) > (time_t)timelimit_sec) {
-                                       to++;
-                                       idx = IDX_CANCEL;
-                                       goto notready;
+                                       if ((time(NULL) - start) > (time_t)timelimit_sec) {
+                                               to++;
+                                               idx = IDX_CANCEL;
+                                               goto notready;
+                                       }
+                                       switch_yield(1000);
                                }
-                               switch_yield(1000);
-                       }
 
-                       if (valid_channels == 0) {
-                               status = SWITCH_STATUS_GENERR;
-                               goto done;
-                       }
-
-               }
-       endfor1:
+                               if (valid_channels == 0) {
+                                       status = SWITCH_STATUS_GENERR;
+                                       goto done;
+                               }
 
-               if (ringback_data && !switch_channel_test_flag(caller_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
-                       switch_channel_pre_answer(caller_channel);
-               }
+                       }
+               endfor1:
 
-               if (session && (read_codec = switch_core_session_get_read_codec(session)) && 
-                       (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
+                       if (ringback_data && !switch_channel_test_flag(caller_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
+                               switch_channel_pre_answer(caller_channel);
+                       }
 
-                       if (!(pass = (uint8_t)switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
-                               if (switch_core_codec_init(&write_codec,
-                                                                                  "L16",
-                                                                                  NULL,
-                                                                                  read_codec->implementation->samples_per_second,
-                                                                                  read_codec->implementation->microseconds_per_frame / 1000,
-                                                                                  1,
-                                                                                  SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
-                                                                                  NULL,
-                                                                                  pool) == SWITCH_STATUS_SUCCESS) {
+                       if (session && (read_codec = switch_core_session_get_read_codec(session)) && 
+                               (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
+
+                               if (!(pass = (uint8_t)switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
+                                       if (switch_core_codec_init(&write_codec,
+                                                                                          "L16",
+                                                                                          NULL,
+                                                                                          read_codec->implementation->samples_per_second,
+                                                                                          read_codec->implementation->microseconds_per_frame / 1000,
+                                                                                          1,
+                                                                                          SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+                                                                                          NULL,
+                                                                                          pool) == SWITCH_STATUS_SUCCESS) {
                                        
                                        
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
-                                                                         read_codec->implementation->samples_per_second,
-                                                                         read_codec->implementation->microseconds_per_frame / 1000);
-                                       write_frame.codec = &write_codec;
-                                       write_frame.datalen = read_codec->implementation->bytes_per_frame;
-                                       write_frame.samples = write_frame.datalen / 2;
-                                       memset(write_frame.data, 255, write_frame.datalen);
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
+                                                                                 read_codec->implementation->samples_per_second,
+                                                                                 read_codec->implementation->microseconds_per_frame / 1000);
+                                               write_frame.codec = &write_codec;
+                                               write_frame.datalen = read_codec->implementation->bytes_per_frame;
+                                               write_frame.samples = write_frame.datalen / 2;
+                                               memset(write_frame.data, 255, write_frame.datalen);
                                        
-                                       if (ringback_data) {
-                                               char *tmp_data = NULL;
+                                               if (ringback_data) {
+                                                       char *tmp_data = NULL;
                                                
-                                               switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
-                                               switch_buffer_create_dynamic(&ringback.loop_buffer, 512, 1024, 0);
+                                                       switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
+                                                       switch_buffer_create_dynamic(&ringback.loop_buffer, 512, 1024, 0);
 
-                                               if (*ringback_data == '/') {
-                                                       char *ext;
+                                                       if (*ringback_data == '/') {
+                                                               char *ext;
                                                        
-                                                       if ((ext = strrchr(ringback_data, '.'))) {
-                                                               switch_core_session_set_read_codec(session, &write_codec);
-                                                               ext++;
-                                                       } else {
-                                                               ringback.asis++;
-                                                               write_frame.codec = read_codec;
-                                                               ext = read_codec->implementation->iananame;
-                                                               tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
-                                                               ringback_data = tmp_data;
-                                                       }
+                                                               if ((ext = strrchr(ringback_data, '.'))) {
+                                                                       switch_core_session_set_read_codec(session, &write_codec);
+                                                                       ext++;
+                                                               } else {
+                                                                       ringback.asis++;
+                                                                       write_frame.codec = read_codec;
+                                                                       ext = read_codec->implementation->iananame;
+                                                                       tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
+                                                                       ringback_data = tmp_data;
+                                                               }
 
-                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
-
-                                                       ringback.fhb.channels = read_codec->implementation->number_of_channels;
-                                                       ringback.fhb.samplerate = read_codec->implementation->samples_per_second;
-                                                       if (switch_core_file_open(&ringback.fhb,
-                                                                                                         ringback_data,
-                                                                                                         read_codec->implementation->number_of_channels,
-                                                                                                         read_codec->implementation->samples_per_second,
-                                                                                                         SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
-                                                                                                         switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
-                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing File\n");
-                                                               switch_safe_free(tmp_data);
-                                                               goto notready;
-                                                       }
-                                                       ringback.fh = &ringback.fhb;
+                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
+
+                                                               ringback.fhb.channels = read_codec->implementation->number_of_channels;
+                                                               ringback.fhb.samplerate = read_codec->implementation->samples_per_second;
+                                                               if (switch_core_file_open(&ringback.fhb,
+                                                                                                                 ringback_data,
+                                                                                                                 read_codec->implementation->number_of_channels,
+                                                                                                                 read_codec->implementation->samples_per_second,
+                                                                                                                 SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
+                                                                                                                 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+                                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing File\n");
+                                                                       switch_safe_free(tmp_data);
+                                                                       goto notready;
+                                                               }
+                                                               ringback.fh = &ringback.fhb;
 
                                                        
-                                               } else {
-                                                       teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
-                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
-                                                       //ringback.ts.debug = 1;
-                                                       //ringback.ts.debug_stream = switch_core_get_console();
-                                                       if (teletone_run(&ringback.ts, ringback_data)) {
-                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
-                                                               teletone_destroy_session(&ringback.ts);
-                                                               switch_buffer_destroy(&ringback.audio_buffer);
-                                                               switch_buffer_destroy(&ringback.loop_buffer);
-                                                               ringback_data = NULL;
+                                                       } else {
+                                                               teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
+                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
+                                                               //ringback.ts.debug = 1;
+                                                               //ringback.ts.debug_stream = switch_core_get_console();
+                                                               if (teletone_run(&ringback.ts, ringback_data)) {
+                                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
+                                                                       teletone_destroy_session(&ringback.ts);
+                                                                       switch_buffer_destroy(&ringback.audio_buffer);
+                                                                       switch_buffer_destroy(&ringback.loop_buffer);
+                                                                       ringback_data = NULL;
+                                                               }
                                                        }
+                                                       switch_safe_free(tmp_data);
                                                }
-                                               switch_safe_free(tmp_data);
+                                       } else {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error!");
+                                               switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE);
+                                               read_codec = NULL;
                                        }
-                               } else {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error!");
-                                       switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE);
-                                       read_codec = NULL;
                                }
                        }
-               }
         
-        if (ringback_data) {
-            early_ok = 0;
-        }
-
-        while ((!caller_channel || switch_channel_ready(caller_channel)) && 
-                          check_channel_status(peer_channels, peer_sessions, and_argc, &idx, &hups, file, key, early_ok, &ring_ready)) {
-
-                       // When the AND operator is being used, and fail_on_single_reject is set, a hangup indicates that the call should fail.
-                       if ((to = (uint8_t)((time(NULL) - start) >= (time_t)timelimit_sec)) || (fail_on_single_reject && hups)) {
-                               idx = IDX_CANCEL;
-                               goto notready;
+                       if (ringback_data) {
+                               early_ok = 0;
                        }
 
-                       if (peer_sessions[0] && switch_core_session_dequeue_message(peer_sessions[0], &message) == SWITCH_STATUS_SUCCESS) {
-                               if (session && !ringback_data && or_argc == 1 && and_argc == 1) { /* when there is only 1 channel to call and bridge and no ringback */
-                                       switch_core_session_receive_message(session, message);
+                       while ((!caller_channel || switch_channel_ready(caller_channel)) && 
+                                  check_channel_status(peer_channels, peer_sessions, and_argc, &idx, &hups, file, key, early_ok, &ring_ready)) {
+
+                               // When the AND operator is being used, and fail_on_single_reject is set, a hangup indicates that the call should fail.
+                               if ((to = (uint8_t)((time(NULL) - start) >= (time_t)timelimit_sec)) || (fail_on_single_reject && hups)) {
+                                       idx = IDX_CANCEL;
+                                       goto notready;
                                }
+
+                               if (peer_sessions[0] && switch_core_session_dequeue_message(peer_sessions[0], &message) == SWITCH_STATUS_SUCCESS) {
+                                       if (session && !ringback_data && or_argc == 1 && and_argc == 1) { /* when there is only 1 channel to call and bridge and no ringback */
+                                               switch_core_session_receive_message(session, message);
+                                       }
                                
-                               if (switch_test_flag(message, SCSMF_DYNAMIC)) {
-                                       switch_safe_free(message);
-                               } else {
-                                       message = NULL;
+                                       if (switch_test_flag(message, SCSMF_DYNAMIC)) {
+                                               switch_safe_free(message);
+                                       } else {
+                                               message = NULL;
+                                       }
                                }
-                       }
 
-                       /* 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_NOMEDIA)) && 
-                               (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);
+                               /* 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_NOMEDIA)) && 
+                                       (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 (!SWITCH_READ_ACCEPTABLE(status)) {
+                                               break;
+                                       }
                                
-                               if (ring_ready && read_frame && !pass && !switch_test_flag(read_frame, SFF_CNG) && read_frame->datalen > 1) {
-                                       if (ringback.fh) {
-                                               uint8_t abuf[1024];
-                                               switch_size_t mlen, olen;
-                                               unsigned int pos = 0;
-
-                                               if (ringback.asis) {
-                                                       mlen = read_frame->datalen;
-                                               } else {
-                                                       mlen = read_frame->datalen  / 2;
-                                               }
+                                       if (ring_ready && read_frame && !pass && !switch_test_flag(read_frame, SFF_CNG) && read_frame->datalen > 1) {
+                                               if (ringback.fh) {
+                                                       uint8_t abuf[1024];
+                                                       switch_size_t mlen, olen;
+                                                       unsigned int pos = 0;
+
+                                                       if (ringback.asis) {
+                                                               mlen = read_frame->datalen;
+                                                       } else {
+                                                               mlen = read_frame->datalen  / 2;
+                                                       }
 
-                                               olen = mlen;
-                                               switch_core_file_read(ringback.fh, abuf, &olen);
-                                               
-                                               if (olen == 0) {
                                                        olen = mlen;
-                                                       ringback.fh->speed = 0;
-                                                       switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
                                                        switch_core_file_read(ringback.fh, abuf, &olen);
+                                               
                                                        if (olen == 0) {
+                                                               olen = mlen;
+                                                               ringback.fh->speed = 0;
+                                                               switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
+                                                               switch_core_file_read(ringback.fh, abuf, &olen);
+                                                               if (olen == 0) {
+                                                                       break;
+                                                               }
+                                                       }
+                                                       write_frame.data = abuf;
+                                                       write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2);
+                                                       if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
                                                                break;
                                                        }
-                                               }
-                                               write_frame.data = abuf;
-                                               write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2);
-                                               if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
-                                                       break;
-                                               }
-                                       } else if (ringback.audio_buffer) {
-                                               if ((write_frame.datalen = (uint32_t)switch_buffer_read(ringback.audio_buffer,
-                                                                                                                                                               write_frame.data,
-                                                                                                                                                               write_frame.codec->implementation->bytes_per_frame)) <= 0) {
-                                                       switch_buffer_t *tmp;
-                                                       tmp = ringback.audio_buffer;
-                                                       ringback.audio_buffer = ringback.loop_buffer;
-                                                       ringback.loop_buffer = tmp;
+                                               } else if (ringback.audio_buffer) {
                                                        if ((write_frame.datalen = (uint32_t)switch_buffer_read(ringback.audio_buffer,
                                                                                                                                                                        write_frame.data,
                                                                                                                                                                        write_frame.codec->implementation->bytes_per_frame)) <= 0) {
-                                                               break;
+                                                               switch_buffer_t *tmp;
+                                                               tmp = ringback.audio_buffer;
+                                                               ringback.audio_buffer = ringback.loop_buffer;
+                                                               ringback.loop_buffer = tmp;
+                                                               if ((write_frame.datalen = (uint32_t)switch_buffer_read(ringback.audio_buffer,
+                                                                                                                                                                               write_frame.data,
+                                                                                                                                                                               write_frame.codec->implementation->bytes_per_frame)) <= 0) {
+                                                                       break;
+                                                               }
                                                        }
                                                }
-                                       }
 
-                                       if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
-                                               break;
-                                       }
-                                       if (ringback.loop_buffer) {
-                                               switch_buffer_write(ringback.loop_buffer, write_frame.data, write_frame.datalen);
+                                               if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
+                                                       break;
+                                               }
+                                               if (ringback.loop_buffer) {
+                                                       switch_buffer_write(ringback.loop_buffer, write_frame.data, write_frame.datalen);
+                                               }
                                        }
-                               }
 
-                       } else {
-                               switch_yield(1000);
-                       }
+                               } else {
+                                       switch_yield(1000);
+                               }
                
-               }
-
-       notready:
+                       }
 
-               if (caller_channel && !switch_channel_ready(caller_channel)) {
-                       idx = IDX_CANCEL;
-               }
+               notready:
 
-               if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
-                       switch_core_session_reset(session);
-               }
+                       if (caller_channel && !switch_channel_ready(caller_channel)) {
+                               idx = IDX_CANCEL;
+                       }
 
-               for (i = 0; i < and_argc; i++) {
-                       if (!peer_channels[i]) {
-                               continue;
+                       if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
+                               switch_core_session_reset(session);
                        }
-                       if (i != idx) {
-                               if (idx == IDX_CANCEL) {
-                                       if (to) {
-                                               reason = SWITCH_CAUSE_NO_ANSWER;
-                    } else {
-                        reason = SWITCH_CAUSE_ORIGINATOR_CANCEL;
-                    }
-                               } else {
-                                       if (to) {
-                                               reason = SWITCH_CAUSE_NO_ANSWER;
-                                       } else if (and_argc > 1) {
-                                               reason = SWITCH_CAUSE_LOSE_RACE;
+
+                       for (i = 0; i < and_argc; i++) {
+                               if (!peer_channels[i]) {
+                                       continue;
+                               }
+                               if (i != idx) {
+                                       if (idx == IDX_CANCEL) {
+                                               if (to) {
+                                                       reason = SWITCH_CAUSE_NO_ANSWER;
+                                               } else {
+                                                       reason = SWITCH_CAUSE_ORIGINATOR_CANCEL;
+                                               }
                                        } else {
-                                               reason = SWITCH_CAUSE_NO_ANSWER;
+                                               if (to) {
+                                                       reason = SWITCH_CAUSE_NO_ANSWER;
+                                               } else if (and_argc > 1) {
+                                                       reason = SWITCH_CAUSE_LOSE_RACE;
+                                               } else {
+                                                       reason = SWITCH_CAUSE_NO_ANSWER;
+                                               }
                                        }
-                               }
 
                                
-                               switch_channel_hangup(peer_channels[i], reason);
+                                       switch_channel_hangup(peer_channels[i], reason);
+                               }
                        }
-               }
 
 
-               if (idx > IDX_NADA) {
-                       peer_session = peer_sessions[idx];
-                       peer_channel = peer_channels[idx];
-               } else {
-                       status = SWITCH_STATUS_FALSE;
-                       goto done;
-               }
+                       if (idx > IDX_NADA) {
+                               peer_session = peer_sessions[idx];
+                               peer_channel = peer_channels[idx];
+                       } else {
+                               status = SWITCH_STATUS_FALSE;
+                               goto done;
+                       }
 
-               if (caller_channel) {
-                       if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
-                               switch_channel_answer(caller_channel);
-                       } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
-                               switch_channel_pre_answer(caller_channel);
+                       if (caller_channel) {
+                               if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
+                                       switch_channel_answer(caller_channel);
+                               } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
+                                       switch_channel_pre_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 {
-                       status = SWITCH_STATUS_FALSE;
-               }
+                       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 {
+                               status = SWITCH_STATUS_FALSE;
+                       }
 
-       done:
-               *cause = SWITCH_CAUSE_UNALLOCATED;
+               done:
+                       *cause = SWITCH_CAUSE_UNALLOCATED;
         
-        if (var_event) {
-                       if (peer_channel && !caller_channel) { /* install the vars from the {} params */
-                switch_event_header_t *header;
-                for (header = var_event->headers; header; header = header->next) {
-                    switch_channel_set_variable(peer_channel, header->name, header->value);
-                }
-            }
-            switch_event_destroy(&var_event);
-        }
+                       if (var_event) {
+                               if (peer_channel && !caller_channel) { /* install the vars from the {} params */
+                                       switch_event_header_t *header;
+                                       for (header = var_event->headers; header; header = header->next) {
+                                               switch_channel_set_variable(peer_channel, header->name, header->value);
+                                       }
+                               }
+                               switch_event_destroy(&var_event);
+                       }
 
-               if (status == SWITCH_STATUS_SUCCESS) {
-                       if (caller_channel) {
-                               switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted");
-                       } 
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Success: [%s]\n", switch_channel_get_name(peer_channel));
-            *cause = SWITCH_CAUSE_SUCCESS;
+                       if (status == SWITCH_STATUS_SUCCESS) {
+                               if (caller_channel) {
+                                       switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted");
+                               
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Success: [%s]\n", switch_channel_get_name(peer_channel));
+                               *cause = SWITCH_CAUSE_SUCCESS;
             
-               } else {
-                       if (peer_channel) {
-                               *cause = switch_channel_get_cause(peer_channel);
                        } else {
-                               for (i = 0; i < and_argc; i++) {
-                                       if (!peer_channels[i]) {
-                                               continue;
+                               if (peer_channel) {
+                                       *cause = switch_channel_get_cause(peer_channel);
+                               } else {
+                                       for (i = 0; i < and_argc; i++) {
+                                               if (!peer_channels[i]) {
+                                                       continue;
+                                               }
+                                               *cause = switch_channel_get_cause(peer_channels[i]);
+                                               break;
                                        }
-                    *cause = switch_channel_get_cause(peer_channels[i]);
-                                       break;
                                }
-                       }
 
-            if (!*cause) {
-                if (reason) {
-                    *cause = reason;
-                } else if (caller_channel) {
-                    *cause = switch_channel_get_cause(caller_channel);
-                } else {
-                    *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
-                }
-            }
+                               if (!*cause) {
+                                       if (reason) {
+                                               *cause = reason;
+                                       } else if (caller_channel) {
+                                               *cause = switch_channel_get_cause(caller_channel);
+                                       } else {
+                                               *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+                                       }
+                               }
 
-                       if (idx == IDX_CANCEL) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Cancelled by originator termination Cause: %d [%s]\n",
-                                                                 *cause, switch_channel_cause2str(*cause));
+                               if (idx == IDX_CANCEL) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Cancelled by originator termination Cause: %d [%s]\n",
+                                                                         *cause, switch_channel_cause2str(*cause));
                 
-                       } else {
-                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Error Cause: %d [%s]\n",
-                                                                 *cause, switch_channel_cause2str(*cause));
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Error Cause: %d [%s]\n",
+                                                                         *cause, switch_channel_cause2str(*cause));
+                               }
                        }
-               }
         
-        if (caller_channel) {
-            switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause));
-        }
-
-               if (!pass && write_codec.implementation) {
-                       switch_core_codec_destroy(&write_codec);
-               }
+                       if (caller_channel) {
+                               switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause));
+                       }
 
-               if (ringback.fh) {
-                       switch_core_file_close(ringback.fh);
-                       ringback.fh = NULL;
-                       if (read_codec && !ringback.asis) {
-                               switch_core_session_set_read_codec(session, read_codec);
-                               switch_core_session_reset(session);
+                       if (!pass && write_codec.implementation) {
+                               switch_core_codec_destroy(&write_codec);
                        }
-               } else if (ringback.audio_buffer) {
-                       teletone_destroy_session(&ringback.ts);
-                       switch_buffer_destroy(&ringback.audio_buffer);
-                       switch_buffer_destroy(&ringback.loop_buffer);
-               }
 
-               for (i = 0; i < and_argc; i++) {
-                       if (!peer_channels[i]) {
-                               continue;
+                       if (ringback.fh) {
+                               switch_core_file_close(ringback.fh);
+                               ringback.fh = NULL;
+                               if (read_codec && !ringback.asis) {
+                                       switch_core_session_set_read_codec(session, read_codec);
+                                       switch_core_session_reset(session);
+                               }
+                       } else if (ringback.audio_buffer) {
+                               teletone_destroy_session(&ringback.ts);
+                               switch_buffer_destroy(&ringback.audio_buffer);
+                               switch_buffer_destroy(&ringback.loop_buffer);
                        }
-                       switch_core_session_rwunlock(peer_sessions[i]);
-               }
 
-               if (status == SWITCH_STATUS_SUCCESS) {
-                       break;
+                       for (i = 0; i < and_argc; i++) {
+                               if (!peer_channels[i]) {
+                                       continue;
+                               }
+                               switch_core_session_rwunlock(peer_sessions[i]);
+                       }
+                       
+                       if (status == SWITCH_STATUS_SUCCESS) {
+                               goto outer_for;
+                       }
                }
        }
-
+ outer_for:
+       switch_safe_free(loop_data);
        switch_safe_free(odata);
        return status;
 }