RTS API Documentation  1.10.11
Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
switch_ivr_originate.c File Reference
#include <switch.h>
+ Include dependency graph for switch_ivr_originate.c:

Go to the source code of this file.

Data Structures

struct  switch_dial_leg_list_s
 
struct  switch_dial_leg_s
 
struct  switch_dial_handle_s
 
struct  switch_dial_handle_list_s
 
struct  originate_status_t
 
struct  originate_global_t
 
struct  key_collect
 
struct  ringback
 
struct  enterprise_originate_handle_t
 
struct  ent_originate_ringback
 
struct  early_state
 

Macros

#define QUOTED_ESC_COMMA   1
 
#define UNQUOTED_ESC_COMMA   2
 
#define MAX_PEERS   128
 
#define peer_eligible(_peer)
 

Typedefs

typedef struct ringback ringback_t
 
typedef struct early_state early_state_t
 

Enumerations

enum  abort_t {
  IDX_XFER = -5, IDX_KEY_CANCEL = -4, IDX_TIMEOUT = -3, IDX_CANCEL = -2,
  IDX_NADA = -1
}
 

Functions

static switch_status_t originate_on_consume_media_transmit (switch_core_session_t *session)
 
static switch_status_t originate_on_routing (switch_core_session_t *session)
 
static switch_status_t switch_dial_handle_dup (switch_dial_handle_t **handle, switch_dial_handle_t *todup)
 
static void *SWITCH_THREAD_FUNC collect_thread_run (switch_thread_t *thread, void *obj)
 
static void launch_collect_thread (struct key_collect *collect)
 
static int check_per_channel_timeouts (originate_global_t *oglobals, int max, time_t start, switch_call_cause_t *force_reason)
 
static switch_bool_t monitor_callback (switch_core_session_t *session, const char *app, const char *data)
 
static void inherit_codec (switch_channel_t *caller_channel, switch_core_session_t *session)
 
static uint8_t check_channel_status (originate_global_t *oglobals, uint32_t len, switch_call_cause_t *force_reason, time_t start)
 
static int teletone_handler (teletone_generation_session_t *ts, teletone_tone_map_t *map)
 
switch_status_t switch_ivr_wait_for_answer (switch_core_session_t *session, switch_core_session_t *peer_session)
 
void switch_process_import (switch_core_session_t *session, switch_channel_t *peer_channel, const char *varname, const char *prefix)
 
static switch_status_t setup_ringback (originate_global_t *oglobals, originate_status_t *originate_status, int len, const char *ringback_data, ringback_t *ringback, switch_frame_t *write_frame, switch_codec_t *write_codec)
 
static void *SWITCH_THREAD_FUNC enterprise_originate_thread (switch_thread_t *thread, void *obj)
 
static void *SWITCH_THREAD_FUNC enterprise_originate_ringback_thread (switch_thread_t *thread, void *obj)
 
switch_status_t switch_ivr_enterprise_originate (switch_core_session_t *session, switch_core_session_t **bleg, switch_call_cause_t *cause, const char *bridgeto, uint32_t timelimit_sec, const switch_state_handler_table_t *table, const char *cid_name_override, const char *cid_num_override, switch_caller_profile_t *caller_profile_override, switch_event_t *ovars, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause, switch_dial_handle_list_t *hl)
 
static void *SWITCH_THREAD_FUNC early_thread_run (switch_thread_t *thread, void *obj)
 
static void wait_for_cause (switch_channel_t *channel)
 
switch_status_t switch_ivr_originate (switch_core_session_t *session, switch_core_session_t **bleg, switch_call_cause_t *cause, const char *bridgeto, uint32_t timelimit_sec, const switch_state_handler_table_t *table, const char *cid_name_override, const char *cid_num_override, switch_caller_profile_t *caller_profile_override, switch_event_t *ovars, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause, switch_dial_handle_t *dh)
 Make an outgoing call. More...
 
switch_status_t switch_dial_handle_list_create (switch_dial_handle_list_t **hl)
 
static switch_status_t switch_dial_handle_list_add_handle (switch_dial_handle_list_t *hl, switch_dial_handle_t *handle)
 
switch_status_t switch_dial_handle_list_create_handle (switch_dial_handle_list_t *hl, switch_dial_handle_t **handle)
 
void switch_dial_handle_list_destroy (switch_dial_handle_list_t **hl)
 
void switch_dial_handle_list_add_global_var (switch_dial_handle_list_t *hl, const char *var, const char *val)
 
void switch_dial_handle_list_add_global_var_printf (switch_dial_handle_list_t *hl, const char *var, const char *fmt,...)
 
switch_status_t switch_dial_handle_create (switch_dial_handle_t **handle)
 
void switch_dial_handle_destroy (switch_dial_handle_t **handle)
 
void switch_dial_handle_add_leg_list (switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP)
 
void switch_dial_leg_list_add_leg_printf (switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *fmt,...)
 
void switch_dial_leg_list_add_leg (switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *dial_string)
 
void switch_dial_handle_add_global_var (switch_dial_handle_t *handle, const char *var, const char *val)
 
void switch_dial_handle_add_global_var_printf (switch_dial_handle_t *handle, const char *var, const char *fmt,...)
 
switch_status_t switch_dial_handle_add_leg_var (switch_dial_leg_t *leg, const char *var, const char *val)
 
switch_status_t switch_dial_handle_add_leg_var_printf (switch_dial_leg_t *leg, const char *var, const char *fmt,...)
 
int switch_dial_handle_get_total (switch_dial_handle_t *handle)
 
int switch_dial_handle_get_peers (switch_dial_handle_t *handle, int idx, char **array, int max)
 
int switch_dial_handle_get_vars (switch_dial_handle_t *handle, int idx, switch_event_t **array, int max)
 
switch_event_tswitch_dial_handle_get_global_vars (switch_dial_handle_t *handle)
 
switch_event_tswitch_dial_leg_get_vars (switch_dial_leg_t *leg)
 
const char * switch_dial_leg_get_var (switch_dial_leg_t *leg, const char *key)
 
static switch_status_t vars_serialize_json_obj (switch_event_t *event, cJSON **json)
 
static switch_status_t leg_serialize_json_obj (switch_dial_leg_t *leg, cJSON **json)
 
static switch_status_t leg_list_serialize_json_obj (switch_dial_leg_list_t *ll, cJSON **json)
 
switch_status_t switch_dial_handle_serialize_json_obj (switch_dial_handle_t *handle, cJSON **json)
 
switch_status_t switch_dial_handle_serialize_json (switch_dial_handle_t *handle, char **str)
 
switch_status_t switch_dial_handle_create_json_obj (switch_dial_handle_t **handle, cJSON *json)
 
switch_status_t switch_dial_handle_create_json (switch_dial_handle_t **handle, const char *handle_string)
 
switch_status_t switch_dial_handle_list_serialize_json_obj (switch_dial_handle_list_t *hl, cJSON **json)
 
switch_status_t switch_dial_handle_list_serialize_json (switch_dial_handle_list_t *hl, char **str)
 
switch_status_t switch_dial_handle_list_create_json_obj (switch_dial_handle_list_t **hl, cJSON *handle_list_json)
 
switch_status_t switch_dial_handle_list_create_json (switch_dial_handle_list_t **hl, const char *handle_list_string)
 
static switch_status_t o_bridge_on_dtmf (switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
 
switch_status_t switch_ivr_enterprise_orig_and_bridge (switch_core_session_t *session, const char *data, switch_dial_handle_list_t *hl, switch_call_cause_t *cause)
 
switch_status_t switch_ivr_orig_and_bridge (switch_core_session_t *session, const char *data, switch_dial_handle_t *dh, switch_call_cause_t *cause)
 

Variables

static const switch_state_handler_table_t originate_state_handlers
 

Macro Definition Documentation

◆ MAX_PEERS

#define MAX_PEERS   128

◆ peer_eligible

#define peer_eligible (   _peer)
Value:
(_peer && !(switch_channel_test_flag(_peer, CF_TRANSFER) || \
switch_channel_test_flag(_peer, CF_REDIRECT) || \
switch_channel_test_flag(_peer, CF_BRIDGED) || \
switch_channel_get_state(_peer) == CS_RESET || \
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.

Definition at line 2047 of file switch_ivr_originate.c.

Referenced by switch_ivr_originate(), and wait_for_cause().

◆ QUOTED_ESC_COMMA

#define QUOTED_ESC_COMMA   1

Definition at line 35 of file switch_ivr_originate.c.

Referenced by switch_ivr_originate().

◆ UNQUOTED_ESC_COMMA

#define UNQUOTED_ESC_COMMA   2

Definition at line 36 of file switch_ivr_originate.c.

Referenced by switch_ivr_originate().

Typedef Documentation

◆ early_state_t

typedef struct early_state early_state_t

Definition at line 1894 of file switch_ivr_originate.c.

◆ ringback_t

typedef struct ringback ringback_t

Definition at line 906 of file switch_ivr_originate.c.

Enumeration Type Documentation

◆ abort_t

enum abort_t
Enumerator
IDX_XFER 
IDX_KEY_CANCEL 
IDX_TIMEOUT 
IDX_CANCEL 
IDX_NADA 

Definition at line 170 of file switch_ivr_originate.c.

Function Documentation

◆ check_channel_status()

static uint8_t check_channel_status ( originate_global_t oglobals,
uint32_t  len,
switch_call_cause_t force_reason,
time_t  start 
)
static

Definition at line 470 of file switch_ivr_originate.c.

References originate_global_t::bridge_early_media, originate_status_t::caller_profile, originate_global_t::cancel_timeout, CF_ANSWERED, CF_BRIDGED, CF_CHANNEL_SWAP, CF_CONSUME_ON_ORIGINATE, CF_EARLY_MEDIA, CF_EARLY_OK, CF_ORIGINATING, CF_PARK, CF_PICKUP, CF_REDIRECT, CF_RING_READY, CF_TAGGED, CF_THREAD_SLEEPING, CF_TRANSFER, CF_WINNER, CF_XFER_ZOMBIE, originate_global_t::confirm_read_timeout, key_collect::confirm_read_timeout, originate_global_t::confirm_timeout, CS_HANGUP, CS_RESET, originate_status_t::early_media, originate_global_t::early_ok, originate_global_t::error_file, key_collect::error_file, originate_global_t::file, key_collect::file, originate_global_t::hups, originate_global_t::idx, IDX_NADA, originate_global_t::ignore_early_media, originate_global_t::ignore_ring_ready, inherit_codec(), key, originate_global_t::key, key_collect::key, launch_collect_thread(), monitor_callback(), originate_global_t::monitor_early_media_fail, originate_global_t::monitor_early_media_ring, originate_global_t::monitor_early_media_ring_total, originate_global_t::originate_status, originate_status_t::peer_channel, originate_status_t::peer_session, originate_status_t::per_channel_progress_timelimit_sec, originate_status_t::per_channel_timelimit_sec, originate_global_t::progress, originate_global_t::return_ring_ready, originate_status_t::ring_ready, originate_global_t::ring_ready, originate_global_t::ringback_ok, originate_global_t::sending_ringback, originate_global_t::sent_ring, originate_global_t::session, key_collect::session, switch_assert, SWITCH_CAUSE_NO_PICKUP, SWITCH_CAUSE_PICKED_OFF, switch_channel_answer, switch_channel_api_on(), switch_channel_audio_sync, SWITCH_CHANNEL_CHANNEL_LOG, switch_channel_clear_flag(), switch_channel_down_nosig, switch_channel_execute_on(), switch_channel_get_caller_profile(), switch_channel_get_cause(), switch_channel_get_name(), switch_channel_get_state(), switch_channel_get_variable, switch_channel_hangup, SWITCH_CHANNEL_LOG, switch_channel_media_ready, switch_channel_pass_callee_id(), switch_channel_ready, switch_channel_ring_ready, switch_channel_ring_ready_value, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_private(), switch_channel_set_variable, switch_channel_test_flag(), switch_channel_up, switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_get_name, switch_core_session_get_uuid(), switch_core_session_locate, switch_core_session_messages_waiting(), switch_core_session_rwunlock(), switch_core_session_strdup, switch_core_session_wake_session_thread(), switch_epoch_time_now(), switch_is_number(), switch_ivr_parse_all_events(), switch_ivr_tone_detect_session(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_safe_free, switch_separate_string(), switch_snprintf(), originate_status_t::tagged, TIME_T_FMT, and zstr.

Referenced by switch_ivr_originate().

471 {
472 
473  uint32_t i;
474  uint8_t rval = 0;
475  switch_channel_t *caller_channel = NULL;
476  int pindex = -1;
477  char bug_key[256] = "";
478  int send_ringback = 0;
479  uint8_t ring_ready_val = 0;
480  int pickups_without_timelimit = 0;
481 
482  oglobals->hups = 0;
483  oglobals->idx = IDX_NADA;
484 
485 
486  if (oglobals->session) {
487  caller_channel = switch_core_session_get_channel(oglobals->session);
488  if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
489  caller_channel = NULL;
490  }
491  }
492 
493 
494  for (i = 0; i < len; i++) {
496  const char *key = switch_channel_get_variable(oglobals->originate_status[i].peer_channel, "channel_swap_uuid");
497  switch_core_session_t *swap_session, *old_session;
498 
499  if ((swap_session = switch_core_session_locate(key))) {
502 
505 
506 
507  old_session = oglobals->originate_status[i].peer_session;
508  oglobals->originate_status[i].peer_session = swap_session;
512 
514 
515  switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "picked_up_uuid", switch_core_session_get_uuid(old_session));
516  switch_channel_execute_on(oglobals->originate_status[i].peer_channel, "execute_on_pickup");
517  switch_channel_api_on(oglobals->originate_status[i].peer_channel, "api_on_pickup");
518 
519  switch_core_session_rwunlock(old_session);
520  break;
521  }
522  }
523  }
524 
525  for (i = 0; i < len; i++) {
527 
528  if (oglobals->originate_status[i].tagged && oglobals->originate_status[i].peer_session) {
530  uint32_t j;
531 
532  if (switch_channel_down_nosig(channel)) {
534 
535  for (j = 0; j < len; j++) {
537  switch_channel_hangup(channel, cause);
538  }
539  oglobals->hups = len;
540  rval = 0;
541  goto end;
542  }
543  }
544 
545 
547  if (oglobals->originate_status[i].per_channel_timelimit_sec == 0) {
548  pickups_without_timelimit++;
549  }
550  }
551 
552  if (!(oglobals->originate_status[i].peer_channel && oglobals->originate_status[i].peer_session)) {
553  oglobals->hups++;
554  continue;
555  }
556 
557  if ((ring_ready_val = (uint8_t)switch_channel_test_flag(oglobals->originate_status[i].peer_channel, CF_RING_READY))) {
558  if (!oglobals->originate_status[i].ring_ready) {
559  oglobals->originate_status[i].ring_ready = ring_ready_val;
560  }
561 
562  if (oglobals->sending_ringback == 1) {
563  send_ringback++;
564  pindex = (uint32_t) i;
565  } else {
566  if (!oglobals->ring_ready) {
567  oglobals->ring_ready = ring_ready_val;
568  if (caller_channel && !oglobals->ignore_ring_ready) {
569  if (len == 1) {
570  switch_channel_pass_callee_id(oglobals->originate_status[0].peer_channel, caller_channel);
571  }
572  switch_channel_ring_ready_value(caller_channel, ring_ready_val);
573  oglobals->sent_ring = ring_ready_val;
574  }
575  }
576  }
577  }
578 
580 
581  if (oglobals->ignore_early_media == 3 && oglobals->bridge_early_media == -1) {
582  oglobals->bridge_early_media = i;
583  oglobals->ringback_ok = 1;
584  }
585 
586  if (oglobals->sending_ringback == 1) {
587  send_ringback++;
588  pindex = (uint32_t) i;
589  } else if (!oglobals->sent_ring && oglobals->ignore_early_media == 2 && len == 1 && caller_channel && !oglobals->ignore_ring_ready) {
590  switch_channel_pass_callee_id(oglobals->originate_status[0].peer_channel, caller_channel);
591  switch_channel_ring_ready(caller_channel);
592  oglobals->sent_ring = 1;
593  }
594 
595  if (!oglobals->originate_status[i].early_media) {
596  oglobals->originate_status[i].early_media = 1;
597  if (oglobals->early_ok) {
598  pindex = i;
599  }
600 
601  if (oglobals->monitor_early_media_fail) {
602  const char *var = switch_channel_get_variable(oglobals->originate_status[i].peer_channel, "monitor_early_media_fail");
603  if (!zstr(var)) {
604  char *fail_array[128] = { 0 };
605  int fail_count = 0;
606  char *fail_data = strdup(var);
607  int fx;
608  int y = 0;
609 
610  switch_assert(fail_data);
611  fail_count = switch_separate_string(fail_data, '!', fail_array, (sizeof(fail_array) / sizeof(fail_array[0])));
612 
613  for (fx = 0; fx < fail_count; fx++) {
614  char *cause = fail_array[fx];
615  int hits = 2;
616  char *p, *q;
617 
618  if (!(p = strchr(cause, ':'))) {
620  continue;
621  }
622  *p++ = '\0';
623 
624 
625  if (!p) {
627  continue;
628  }
629 
630 
631  if (!(hits = atoi(p))) {
632  hits = 2;
633  }
634 
635 
636  if (!(p = strchr(p, ':'))) {
638  continue;
639  }
640  *p++ = '\0';
641 
642  if (!p) {
644  continue;
645  }
646 
647  for (q = p; q && *q; q++) {
648  if (*q == '+') {
649  *q = ',';
650  }
651  }
652  switch_snprintf(bug_key, sizeof(bug_key), "monitor_early_media_fail_%d", ++y);
653  switch_ivr_tone_detect_session(oglobals->originate_status[i].peer_session, bug_key, p, "r", 0, hits, "fail", cause, monitor_callback);
654 
655  }
656 
657  switch_safe_free(fail_data);
658 
659  }
660  }
661 
662  if (oglobals->monitor_early_media_ring) {
663  const char *var = switch_channel_get_variable(oglobals->originate_status[i].peer_channel, "monitor_early_media_ring");
664  const char *var_total = switch_channel_get_variable(oglobals->originate_status[i].peer_channel, "monitor_early_media_ring_total");
665  if (!zstr(var)) {
666  char *ring_array[128] = { 0 };
667  int ring_count = 0;
668  char *ring_data = strdup(var);
669  int fx;
670  int y = 0;
671 
672  switch_assert(ring_data);
673  ring_count = switch_separate_string(ring_data, '!', ring_array, (sizeof(ring_array) / sizeof(ring_array[0])));
674 
675  for (fx = 0; fx < ring_count; fx++) {
676  int hits = 2;
677  char *p = ring_array[fx], *q;
678 
679  if (!p) {
681  continue;
682  }
683 
684  if (!(hits = atoi(p))) {
685  hits = 2;
686  }
687 
688  if (!(p = strchr(p, ':'))) {
690  continue;
691  }
692  *p++ = '\0';
693 
694  if (!p) {
696  continue;
697  }
698 
699  for (q = p; q && *q; q++) {
700  if (*q == '+') {
701  *q = ',';
702  }
703  }
704 
705  switch_channel_set_private(oglobals->originate_status[i].peer_channel, "_oglobals_", oglobals);
706  switch_snprintf(bug_key, sizeof(bug_key), "monitor_early_media_ring_%d", ++y);
707  switch_ivr_tone_detect_session(oglobals->originate_status[i].peer_session, bug_key, p, "r", 0, hits, "ring", NULL, monitor_callback);
708 
709  }
710 
711  if (var_total) {
712  int tmp = atoi(var_total);
713  if (tmp > 0 && tmp < 100) {
715  "%s setting ring total to %d\n", switch_channel_get_name(oglobals->originate_status[i].peer_channel), tmp);
716  oglobals->monitor_early_media_ring_total = tmp;
717  }
718  }
719 
720  switch_safe_free(ring_data);
721 
722  }
723  }
724  }
725 
726  if (!oglobals->monitor_early_media_ring) {
727 
728  if (!oglobals->progress) {
729  oglobals->progress = 1;
730  }
731 
732  if (!oglobals->ring_ready && !oglobals->ignore_ring_ready) {
733  oglobals->ring_ready = 1;
734 
735  }
736  }
737  }
738 
744  } else {
746  }
747  }
748  }
749 
751  if (!oglobals->early_ok) {
752  oglobals->early_ok = 1;
753  }
755  }
756 
757  if (caller_channel && switch_channel_test_flag(caller_channel, CF_EARLY_OK)) {
758  if (!oglobals->early_ok) {
759  oglobals->early_ok = 1;
760  }
761  switch_channel_clear_flag(caller_channel, CF_EARLY_OK);
762  }
763 
765  if (state >= CS_HANGUP || state == CS_RESET || switch_channel_test_flag(oglobals->originate_status[i].peer_channel, CF_TRANSFER) ||
769  ) {
770  (oglobals->hups)++;
772  if (oglobals->originate_status[i].per_channel_timelimit_sec == 0) {
773  pickups_without_timelimit--;
774  }
775  }
778  (oglobals->ring_ready && oglobals->return_ring_ready && len == 1 &&
780  )
782  ) {
783 
784  const char *group_confirm_key = switch_channel_get_variable(oglobals->originate_status[i].peer_channel, "group_confirm_key");
785  const char *group_confirm_file = switch_channel_get_variable(oglobals->originate_status[i].peer_channel, "group_confirm_file");
786 
787  if (!zstr(oglobals->key) || !zstr(group_confirm_key)) {
788  struct key_collect *collect;
789  const char *group_confirm_timeout = switch_channel_get_variable(oglobals->originate_status[i].peer_channel, "group_confirm_timeout");
790  int extend_timeout = 0;
791  int cancel_timeout = 0;
792  if (group_confirm_timeout && switch_is_number(group_confirm_timeout)) {
793  // leg var overrides global group_confirm_timeout
794  extend_timeout = atoi(group_confirm_timeout);
795  if (extend_timeout == 0) {
796  cancel_timeout = 1;
797  }
798  } else {
799  extend_timeout = oglobals->confirm_timeout;
800  }
801 
802  if (extend_timeout > 0) {
803  /* extend timeout for this leg only */
804  time_t elapsed = switch_epoch_time_now(NULL) - start;
805  oglobals->originate_status[i].per_channel_progress_timelimit_sec = elapsed + extend_timeout;
806  oglobals->originate_status[i].per_channel_timelimit_sec = elapsed + extend_timeout;
807  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "elapsed %" TIME_T_FMT ", timelimit extended to %u\n", elapsed, oglobals->originate_status[i].per_channel_timelimit_sec);
808  } else if (oglobals->cancel_timeout || cancel_timeout) {
809  /* cancel timeout for this leg only */
812  }
813 
814  if ((collect = switch_core_session_alloc(oglobals->originate_status[i].peer_session, sizeof(*collect)))) {
816  if (!zstr(group_confirm_key)) {
817  collect->key = switch_core_session_strdup(oglobals->originate_status[i].peer_session, group_confirm_key);
818  } else {
819  collect->key = switch_core_session_strdup(oglobals->originate_status[i].peer_session, oglobals->key);
820  }
821 
822  if (!zstr(group_confirm_file)) {
823  collect->file = switch_core_session_strdup(oglobals->originate_status[i].peer_session, group_confirm_file);
824  } else if (!zstr(oglobals->file)) {
825  collect->file = switch_core_session_strdup(oglobals->originate_status[i].peer_session, oglobals->file);
826  }
827  if (!zstr(oglobals->error_file)) {
829  }
830 
831  if (oglobals->confirm_read_timeout) {
832  collect->confirm_read_timeout = oglobals->confirm_read_timeout;
833  } else {
834  collect->confirm_read_timeout = 5000;
835  }
836 
838  collect->session = oglobals->originate_status[i].peer_session;
839  launch_collect_thread(collect);
840  }
841  } else {
842  oglobals->idx = i;
843  pindex = (uint32_t) i;
844  rval = 0;
845  goto end;
846 
847  }
849  /* unset group_confirm variables */
850  switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_key", NULL);
851  switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_file", NULL);
852  switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_error_file", NULL);
853  switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_cancel_timeout", NULL);
854  switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_read_timeout", NULL);
855  oglobals->idx = i;
856  rval = 0;
857  pindex = (uint32_t) i;
858  goto end;
859  }
860  }
861 
862  if (oglobals->hups > 0 && oglobals->hups + pickups_without_timelimit == len) {
863  /* only pickup channels with no timelimit remain */
864  rval = 0;
865  } else {
866  rval = 1;
867  }
868 
869  end:
870 
871  if (rval == 0 && pickups_without_timelimit) {
872  for (i = 0; i < len; i++) {
876  }
877  }
878  }
879 
880 
881  if (pindex > -1 && caller_channel && switch_channel_ready(caller_channel) && !switch_channel_media_ready(caller_channel) &&
883  inherit_codec(caller_channel, oglobals->originate_status[pindex].peer_session);
884  }
885 
886  if (send_ringback) {
887  oglobals->sending_ringback++;
888  }
889 
890  return rval;
891 
892 }
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
#define switch_channel_answer(channel)
Answer a channel (initiate/acknowledge a successful connection)
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define SWITCH_CHANNEL_LOG
switch_caller_profile_t * caller_profile
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
switch_channel_t * peer_channel
#define switch_channel_up(_channel)
#define switch_channel_ready(_channel)
#define switch_channel_media_ready(_channel)
static void inherit_codec(switch_channel_t *caller_channel, switch_core_session_t *session)
switch_bool_t switch_is_number(const char *str)
#define switch_core_session_get_name(_s)
Definition: switch_core.h:265
switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session)
Parse all commands from an event.
Definition: switch_ivr.c:913
#define switch_channel_ring_ready_value(channel, _rv)
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
#define zstr(x)
Definition: switch_utils.h:314
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
originate_status_t originate_status[MAX_PEERS]
#define switch_channel_audio_sync(_c)
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
switch_core_session_t * session
#define switch_channel_get_variable(_c, _v)
uint32_t switch_core_session_messages_waiting(switch_core_session_t *session)
uint32_t per_channel_progress_timelimit_sec
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
#define switch_channel_ring_ready(channel)
Send Ringing message to a channel.
#define switch_channel_down_nosig(_channel)
static void launch_collect_thread(struct key_collect *collect)
#define TIME_T_FMT
switch_call_cause_t
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
switch_bool_t cancel_timeout
switch_status_t switch_ivr_tone_detect_session(switch_core_session_t *session, const char *key, const char *tone_spec, const char *flags, time_t timeout, int hits, const char *app, const char *data, switch_tone_detect_callback_t callback)
Start looking for TONES.
switch_core_session_t * peer_session
switch_channel_state_t
Channel States (these are the defaults, CS_SOFT_EXECUTE, CS_EXCHANGE_MEDIA, and CS_CONSUME_MEDIA are ...
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
#define switch_channel_set_flag(_c, _f)
switch_status_t switch_core_session_wake_session_thread(_In_ switch_core_session_t *session)
switch_core_session_t * session
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:322
char * key
Definition: switch_msrp.c:64
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
static switch_bool_t monitor_callback(switch_core_session_t *session, const char *app, const char *data)
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
#define switch_assert(expr)
#define switch_channel_set_variable(_channel, _var, _val)
switch_caller_profile_t * switch_channel_get_caller_profile(switch_channel_t *channel)
Retrieve the given channel&#39;s caller profile.
switch_status_t switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix)
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
switch_status_t switch_channel_pass_callee_id(switch_channel_t *channel, switch_channel_t *other_channel)
#define SWITCH_CHANNEL_CHANNEL_LOG(x)
switch_call_cause_t switch_channel_get_cause(_In_ switch_channel_t *channel)
return the cause code for a given channel

◆ check_per_channel_timeouts()

static int check_per_channel_timeouts ( originate_global_t oglobals,
int  max,
time_t  start,
switch_call_cause_t force_reason 
)
static

Definition at line 297 of file switch_ivr_originate.c.

References CF_ANSWERED, CF_BLOCK_STATE, CF_EARLY_MEDIA, CF_RING_READY, CS_DESTROY, CS_REPORTING, originate_global_t::monitor_early_media_ring, originate_global_t::originate_status, originate_status_t::peer_channel, originate_status_t::per_channel_delay_start, originate_status_t::per_channel_progress_timelimit_sec, originate_status_t::per_channel_timelimit_sec, SWITCH_CAUSE_ALLOTTED_TIMEOUT, SWITCH_CAUSE_PROGRESS_TIMEOUT, switch_channel_clear_flag(), switch_channel_get_state(), switch_channel_hangup, switch_channel_test_flag(), switch_channel_up_nosig, and switch_epoch_time_now().

Referenced by switch_ivr_originate().

299 {
300  int x = 0, i, delayed_channels = 0, active_channels = 0;
301  uint32_t early_exit_time = 0, delayed_min = 0;
302 
303  time_t elapsed = switch_epoch_time_now(NULL) - start;
304 
305  for (i = 0; i < max; i++) {
308  if (oglobals->originate_status[i].per_channel_delay_start) {
309  delayed_channels++;
310  } else {
311  active_channels++;
312  }
313  }
314  }
315 
316  if (active_channels == 0 && delayed_channels) {
317  for (i = 0; i < max; i++) {
318  if (oglobals->originate_status[i].peer_channel && oglobals->originate_status[i].per_channel_delay_start &&
319  (!delayed_min || delayed_min > oglobals->originate_status[i].per_channel_delay_start)) {
320  delayed_min = oglobals->originate_status[i].per_channel_delay_start;
321  }
322  }
323 
324  early_exit_time = delayed_min - (uint32_t)(switch_time_t) elapsed;
325  }
326 
327  for (i = 0; i < max; i++) {
328  if (oglobals->originate_status[i].peer_channel && oglobals->originate_status[i].per_channel_delay_start &&
329  (elapsed > oglobals->originate_status[i].per_channel_delay_start || active_channels == 0)) {
330  if (active_channels == 0) {
331  if (oglobals->originate_status[i].per_channel_timelimit_sec) {
332  if (oglobals->originate_status[i].per_channel_timelimit_sec > early_exit_time) {
333  /* IN theory this check is not needed ( should just be if !0 then -= with no else), if its not 0 it should always be greater.... */
334  oglobals->originate_status[i].per_channel_timelimit_sec -= early_exit_time;
335  } else {
337  }
338  }
339 
341  if (oglobals->originate_status[i].per_channel_progress_timelimit_sec > early_exit_time) {
342  /* IN theory this check is not needed ( should just be if !0 then -= with no else), if its not 0 it should always be greater.... */
343  oglobals->originate_status[i].per_channel_progress_timelimit_sec -= early_exit_time;
344  } else {
346  }
347  }
348 
349  oglobals->originate_status[i].per_channel_delay_start -= delayed_min;
350  } else {
351  oglobals->originate_status[i].per_channel_delay_start = 0;
352  }
353 
354  if (!oglobals->originate_status[i].per_channel_delay_start) {
356  }
357  }
358 
364  )
365  ) {
367  *force_reason = SWITCH_CAUSE_PROGRESS_TIMEOUT;
368  x++;
369  }
370  if (oglobals->originate_status[i].per_channel_timelimit_sec && elapsed > oglobals->originate_status[i].per_channel_timelimit_sec) {
372  x++;
373  }
374  }
375  }
376 
377  return x;
378 }
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
switch_channel_t * peer_channel
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
originate_status_t originate_status[MAX_PEERS]
int64_t switch_time_t
Definition: switch_apr.h:188
uint32_t per_channel_progress_timelimit_sec
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:322
#define switch_channel_up_nosig(_channel)
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.

◆ collect_thread_run()

static void* SWITCH_THREAD_FUNC collect_thread_run ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 186 of file switch_ivr_originate.c.

References switch_application_interface::application_function, buf, CF_WINNER, key_collect::confirm_read_timeout, key_collect::error_file, key_collect::file, key_collect::key, memset(), key_collect::session, SWITCH_BLANK_STRING, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_get_name(), switch_channel_hangup, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_variable, switch_channel_up_nosig, switch_core_session_exec(), switch_core_session_get_channel(), switch_core_session_read_lock(), switch_core_session_rwunlock(), switch_ivr_play_file(), switch_ivr_read(), switch_ivr_sleep(), switch_loadable_module_get_application_interface(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_STATUS_BREAK, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TOO_SMALL, SWITCH_TRUE, UNPROTECT_INTERFACE, and zstr.

Referenced by launch_collect_thread().

187 {
188  struct key_collect *collect = (struct key_collect *) obj;
189  switch_channel_t *channel = NULL;
190  char buf[10] = SWITCH_BLANK_STRING;
191  switch_application_interface_t *application_interface = NULL;
192 
193  if (!collect->session) {
194  return NULL;
195  }
196 
197  channel = switch_core_session_get_channel(collect->session);
199  return NULL;
200  }
201 
202  switch_ivr_sleep(collect->session, 0, SWITCH_TRUE, NULL);
203 
204  if (!strcasecmp(collect->key, "exec")) {
205  char *data;
206  char *app_name, *app_data;
207 
208  if (!(data = collect->file)) {
209  goto wbreak;
210  }
211 
212  app_name = data;
213 
214  if ((app_data = strchr(app_name, ' '))) {
215  *app_data++ = '\0';
216  }
217 
218  if ((application_interface = switch_loadable_module_get_application_interface(app_name)) == 0) {
219  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "Invalid Application %s\n", app_name);
221  goto wbreak;
222  }
223 
224  if (!application_interface->application_function) {
225  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "No Function for %s\n", app_name);
227  goto wbreak;
228  }
229 
230  switch_core_session_exec(collect->session, application_interface, app_data);
231 
232  if (switch_channel_up_nosig(channel)) {
234  switch_channel_set_variable(channel, "group_dial_status", "winner");
235  }
236 
237  goto wbreak;
238  }
239 
240  if (!switch_channel_up_nosig(channel)) {
242  goto wbreak;
243  }
244 
245  while (switch_channel_ready(channel)) {
246  switch_size_t len = strlen(collect->key);
247  const char *file = collect->file;
248  switch_status_t status;
249 
250  memset(buf, 0, sizeof(buf));
251 
252  if (zstr(file)) {
253  file = "silence";
254  }
255 
256  status = switch_ivr_read(collect->session,
257  (uint32_t)len,
258  (uint32_t)len,
259  file, NULL, buf, sizeof(buf), collect->confirm_read_timeout, NULL, 0);
260 
261 
262  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_TOO_SMALL) {
263  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "%s Error Playing File!\n",
264  switch_channel_get_name(channel));
266  }
267 
268  if (!strcmp(collect->key, buf)) {
270  switch_channel_set_variable(channel, "group_dial_status", "winner");
271  goto wbreak;
272  } else if (collect->error_file) {
273  switch_ivr_play_file(collect->session, NULL, collect->error_file, NULL);
274  }
275  }
276 
277  wbreak:
278 
280 
281  UNPROTECT_INTERFACE(application_interface);
282 
283  return NULL;
284 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
A module interface to implement an application.
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_ivr_read(switch_core_session_t *session, uint32_t min_digits, uint32_t max_digits, const char *prompt_audio_file, const char *var_name, char *digit_buffer, switch_size_t digit_buffer_length, uint32_t timeout, const char *valid_terminators, uint32_t digit_timeout)
switch_status_t switch_ivr_sleep(switch_core_session_t *session, uint32_t ms, switch_bool_t sync, switch_input_args_t *args)
Wait for time to pass for a specified number of milliseconds.
Definition: switch_ivr.c:127
#define switch_channel_ready(_channel)
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
switch_status_t switch_core_session_exec(_In_ switch_core_session_t *session, _In_ const switch_application_interface_t *application_interface, _In_opt_z_ const char *arg)
Execute an application on a session.
switch_status_t switch_ivr_play_file(switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args)
play a file from the disk to the session
#define zstr(x)
Definition: switch_utils.h:314
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define UNPROTECT_INTERFACE(_it)
switch_byte_t switch_byte_t * buf
switch_application_interface_t * switch_loadable_module_get_application_interface(const char *name)
Retrieve the application interface by it&#39;s registered name.
#define SWITCH_BLANK_STRING
Definition: switch_types.h:48
switch_application_function_t application_function
uintptr_t switch_size_t
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t
Common return values.
#define switch_channel_set_flag(_c, _f)
switch_core_session_t * session
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_channel_up_nosig(_channel)
#define switch_channel_set_variable(_channel, _var, _val)
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
memset(buf, 0, buflen)

◆ early_thread_run()

static void* SWITCH_THREAD_FUNC early_thread_run ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 1897 of file switch_ivr_originate.c.

References switch_codec_implementation::actual_samples_per_second, originate_status_t::array_pos, ringback::asis, originate_global_t::bridge_early_media, early_state::buffer, CF_ANSWERED, CF_RING_READY, switch_frame::data, switch_frame::datalen, originate_global_t::early_ok, if(), originate_global_t::ignore_early_media, MAX_PEERS, memset(), switch_codec_implementation::microseconds_per_packet, early_state::mutex, switch_codec_implementation::number_of_channels, early_state::oglobals, originate_global_t::originate_status, originate_status_t::peer_channel, originate_status_t::peer_session, early_state::ready, early_state::ringback, originate_global_t::session, SFF_CNG, switch_buffer_write(), switch_channel_media_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), switch_channel_up, switch_channel_up_nosig, SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, switch_core_codec_ready(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_read_frame(), switch_core_session_read_lock(), switch_core_session_reset(), switch_core_session_rwunlock(), switch_core_session_set_read_codec(), SWITCH_FALSE, SWITCH_IO_FLAG_NONE, SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_normalize_to_16bit, SWITCH_READ_ACCEPTABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_STATUS_SUCCESS, switch_test_flag, SWITCH_TRUE, and early_state::ttl.

Referenced by switch_ivr_originate().

1898 {
1899  early_state_t *state = (early_state_t *) obj;
1900  originate_status_t originate_status[MAX_PEERS] = { {0} };
1901  uint8_t array_pos = 0;
1902  int16_t mux_data[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
1903  int32_t sample;
1904  switch_codec_t read_codecs[MAX_PEERS] = { {0} };
1905  int i, x, ready = 0, answered = 0, ring_ready = 0;
1906  int16_t *data;
1907  uint32_t datalen = 0;
1908  switch_status_t status;
1909  switch_frame_t *read_frame = NULL;
1910  switch_codec_implementation_t read_impl = { 0 };
1911 
1912  for (i = 0; i < MAX_PEERS && i < state->ttl; i++) {
1914  switch_channel_t *channel = NULL;
1915 
1916  if (session) channel = switch_core_session_get_channel(session);
1917 
1918  if (!session || !channel || !switch_channel_up(channel)) {
1919  continue;
1920  }
1921 
1923  originate_status[array_pos].peer_session = session;
1924  originate_status[array_pos].peer_channel = channel;
1925  originate_status[array_pos].array_pos = (uint8_t) i;
1926  array_pos++;
1927  }
1928  }
1929 
1930  if (state->oglobals->session) {
1931  switch_core_session_get_read_impl(state->oglobals->session, &read_impl);
1932  }
1933 
1934  while (state->ready) {
1935  datalen = 0;
1936  memset(mux_data, 0, sizeof(mux_data));
1937  ready = 0;
1938  answered = 0;
1939 
1940  for (array_pos = 0; array_pos < MAX_PEERS && originate_status[array_pos].peer_session; array_pos++) {
1941  switch_core_session_t *session = originate_status[array_pos].peer_session;
1942  switch_channel_t *channel = originate_status[array_pos].peer_channel;
1943  i = originate_status[array_pos].array_pos;
1944 
1945  if (!session || !channel || !switch_channel_up(channel)) {
1946  continue;
1947  }
1948 
1949  if (switch_channel_media_ready(channel)) {
1950  ready++;
1951 
1952  if (switch_channel_test_flag(channel, CF_RING_READY)) {
1953  ring_ready = 1;
1954  state->oglobals->bridge_early_media = -1;
1955  state->oglobals->ignore_early_media = 1;
1956  }
1957 
1958  if (switch_channel_test_flag(channel, CF_ANSWERED)) {
1959  answered++;
1960  }
1961 
1962  if (!state->ringback->asis) {
1963  if (!switch_core_codec_ready((&read_codecs[i]))) {
1964  if (switch_core_codec_init(&read_codecs[i],
1965  "L16",
1966  NULL,
1967  NULL,
1968  read_impl.actual_samples_per_second,
1969  read_impl.microseconds_per_packet / 1000,
1972  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n");
1973  }
1974  switch_core_session_set_read_codec(session, NULL);
1975  switch_core_session_set_read_codec(session, &read_codecs[i]);
1976  }
1977  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1978  if (SWITCH_READ_ACCEPTABLE(status) && !switch_test_flag(read_frame, SFF_CNG)) {
1979  data = (int16_t *) read_frame->data;
1980  if (datalen < read_frame->datalen) {
1981  datalen = read_frame->datalen;
1982  }
1983  for (x = 0; x < (int) read_frame->datalen / 2; x++) {
1984  sample = data[x] + mux_data[x];
1985  switch_normalize_to_16bit(sample);
1986  mux_data[x] = (int16_t) sample;
1987  }
1988  }
1989  } else {
1990  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1991  if (SWITCH_READ_ACCEPTABLE(status) && !switch_test_flag(read_frame, SFF_CNG)) {
1992  datalen = read_frame->datalen;
1993  }
1994  break;
1995  }
1996  }
1997  }
1998 
1999  if (!ready || answered || ring_ready) {
2000  break;
2001  }
2002 
2003  if (!datalen) {
2004  continue;
2005  }
2006 
2007  if (state->ringback->asis) {
2008  uint16_t flen = (uint16_t)datalen;
2009  switch_mutex_lock(state->mutex);
2010  switch_buffer_write(state->buffer, &flen, sizeof(uint16_t));
2011  switch_buffer_write(state->buffer, read_frame->data, datalen);
2012  switch_mutex_unlock(state->mutex);
2013  } else {
2014  switch_mutex_lock(state->mutex);
2015  switch_buffer_write(state->buffer, mux_data, datalen);
2016  switch_mutex_unlock(state->mutex);
2017  }
2018  }
2019 
2020 
2021  for (array_pos = 0; array_pos < MAX_PEERS && originate_status[array_pos].peer_session; array_pos++) {
2022  switch_core_session_t *session = originate_status[array_pos].peer_session;
2023  switch_channel_t *channel = originate_status[array_pos].peer_channel;
2024  i = originate_status[array_pos].array_pos;
2025 
2026  if (!session) continue;
2027 
2028  if (switch_core_codec_ready((&read_codecs[i]))) {
2029  switch_core_session_set_read_codec(session, NULL);
2030  switch_core_codec_destroy(&read_codecs[i]);
2031  }
2032 
2033  if (switch_channel_up_nosig(channel)) {
2035  }
2036 
2038  }
2039 
2040  if (!ring_ready) {
2041  state->oglobals->early_ok = 1;
2042  }
2043 
2044  return NULL;
2045 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
void switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
Reset the buffers and resampler on a session.
switch_channel_t * peer_channel
#define switch_channel_up(_channel)
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
switch_status_t switch_core_session_set_read_codec(_In_ switch_core_session_t *session, switch_codec_t *codec)
Assign the read codec to a given session.
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
#define switch_channel_media_ready(_channel)
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
switch_status_t switch_core_session_read_frame(_In_ switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
Read a frame from a session.
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
originate_status_t originate_status[MAX_PEERS]
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
uint32_t datalen
Definition: switch_frame.h:68
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_core_session_t * session
switch_mutex_t * mutex
switch_buffer_t * buffer
An abstraction of a data frame.
Definition: switch_frame.h:54
#define MAX_PEERS
#define switch_core_codec_init(_codec, _codec_name, _modname, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool)
Initialize a codec handle.
Definition: switch_core.h:1693
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_core_session_t * peer_session
switch_status_t
Common return values.
ringback_t * ringback
originate_global_t * oglobals
switch_core_session_t * session
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
static switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
#define switch_normalize_to_16bit(n)
Definition: switch_utils.h:292
#define switch_channel_up_nosig(_channel)
#define SWITCH_READ_ACCEPTABLE(status)
memset(buf, 0, buflen)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.

◆ enterprise_originate_ringback_thread()

static void* SWITCH_THREAD_FUNC enterprise_originate_ringback_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 1531 of file switch_ivr_originate.c.

References CF_NOT_READY, ent_originate_ringback::ringback_data, ent_originate_ringback::running, ent_originate_ringback::session, switch_channel_ready, switch_channel_set_flag, switch_core_session_get_channel(), switch_core_session_read_lock(), switch_core_session_rwunlock(), switch_is_file_path(), switch_ivr_collect_digits_callback(), switch_ivr_gentones(), switch_ivr_parse_all_messages(), switch_ivr_play_file(), SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and zstr.

Referenced by switch_ivr_enterprise_originate().

1532 {
1533  struct ent_originate_ringback *rb_data = (struct ent_originate_ringback *) obj;
1535  switch_channel_t *channel;
1537 
1539  return NULL;
1540  }
1541 
1542  channel = switch_core_session_get_channel(session);
1543 
1544  while (rb_data->running && switch_channel_ready(channel)) {
1546  if (status != SWITCH_STATUS_BREAK) {
1547  if (zstr(rb_data->ringback_data) || !strcasecmp(rb_data->ringback_data, "silence")) {
1548  status = switch_ivr_collect_digits_callback(session, NULL, 0, 0);
1549  } else if (switch_is_file_path(rb_data->ringback_data)) {
1550  status = switch_ivr_play_file(session, NULL, rb_data->ringback_data, NULL);
1551  } else {
1552  status = switch_ivr_gentones(session, rb_data->ringback_data, 0, NULL);
1553  }
1554  }
1555 
1556  if (status == SWITCH_STATUS_BREAK) {
1558  }
1559  }
1561 
1562  rb_data->running = 0;
1563  return NULL;
1564 }
switch_status_t switch_ivr_gentones(switch_core_session_t *session, const char *script, int32_t loops, switch_input_args_t *args)
switch_status_t switch_ivr_collect_digits_callback(switch_core_session_t *session, switch_input_args_t *args, uint32_t digit_timeout, uint32_t abs_timeout)
Wait for DTMF digits calling a pluggable callback function when digits are collected.
Definition: switch_ivr.c:1225
#define switch_channel_ready(_channel)
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
switch_status_t switch_ivr_play_file(switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args)
play a file from the disk to the session
#define zstr(x)
Definition: switch_utils.h:314
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_core_session_t * session
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t
Common return values.
static switch_bool_t switch_is_file_path(const char *file)
#define switch_channel_set_flag(_c, _f)
switch_status_t switch_ivr_parse_all_messages(switch_core_session_t *session)
Definition: switch_ivr.c:847

◆ enterprise_originate_thread()

static void* SWITCH_THREAD_FUNC enterprise_originate_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 1490 of file switch_ivr_originate.c.

References enterprise_originate_handle_t::bleg, enterprise_originate_handle_t::bridgeto, enterprise_originate_handle_t::caller_profile_override, enterprise_originate_handle_t::cancel_cause, enterprise_originate_handle_t::cause, enterprise_originate_handle_t::cid_name_override, enterprise_originate_handle_t::cid_num_override, enterprise_originate_handle_t::dh, enterprise_originate_handle_t::done, enterprise_originate_handle_t::fence_mutex, enterprise_originate_handle_t::flags, switch_dial_leg_list_s::handle, enterprise_originate_handle_t::mutex, enterprise_originate_handle_t::ovars, enterprise_originate_handle_t::status, SWITCH_CAUSE_LOSE_RACE, switch_channel_hangup, switch_channel_set_variable, switch_core_session_get_channel(), switch_core_session_rwunlock(), switch_ivr_originate(), switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STATUS_SUCCESS, enterprise_originate_handle_t::table, and enterprise_originate_handle_t::timelimit_sec.

Referenced by switch_ivr_enterprise_originate().

1491 {
1493  switch_status_t status;
1494 
1495  switch_mutex_lock(handle->fence_mutex);
1496  handle->done = 0;
1498 
1499  status = switch_ivr_originate(NULL, &handle->bleg, &handle->cause,
1500  handle->bridgeto, handle->timelimit_sec,
1501  handle->table,
1502  handle->cid_name_override,
1503  handle->cid_num_override,
1504  handle->caller_profile_override,
1505  handle->ovars,
1506  handle->flags,
1507  &handle->cancel_cause,
1508  handle->dh);
1509 
1510  switch_mutex_lock(handle->fence_mutex);
1511  handle->status = status;
1512  handle->done = 1;
1514 
1515  switch_mutex_lock(handle->mutex);
1516  switch_mutex_unlock(handle->mutex);
1517 
1518  if (handle->done != 2) {
1519  if (handle->status == SWITCH_STATUS_SUCCESS && handle->bleg) {
1521 
1522  switch_channel_set_variable(channel, "group_dial_status", "loser");
1525  }
1526  }
1527 
1528  return NULL;
1529 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
const switch_state_handler_table_t * table
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t switch_ivr_originate(switch_core_session_t *session, switch_core_session_t **bleg, switch_call_cause_t *cause, const char *bridgeto, uint32_t timelimit_sec, const switch_state_handler_table_t *table, const char *cid_name_override, const char *cid_num_override, switch_caller_profile_t *caller_profile_override, switch_event_t *ovars, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause, switch_dial_handle_t *dh)
Make an outgoing call.
switch_caller_profile_t * caller_profile_override
switch_status_t
Common return values.
#define switch_channel_set_variable(_channel, _var, _val)

◆ inherit_codec()

static void inherit_codec ( switch_channel_t caller_channel,
switch_core_session_t session 
)
static

Definition at line 429 of file switch_ivr_originate.c.

References switch_codec_implementation::iananame, switch_codec_implementation::microseconds_per_packet, switch_codec_implementation::samples_per_second, SWITCH_CHANNEL_CHANNEL_LOG, switch_channel_get_name(), switch_channel_get_variable, switch_channel_set_variable, switch_core_session_get_channel(), switch_core_session_get_read_impl(), switch_core_session_get_video_read_impl(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_LOG_WARNING, switch_snprintf(), SWITCH_STATUS_SUCCESS, switch_stristr(), switch_true(), and zstr.

Referenced by check_channel_status(), and setup_ringback().

430 {
431  const char *var = switch_channel_get_variable(caller_channel, "inherit_codec");
433 
434  if (!zstr(var) && !strcasecmp(var, "passthru")) {
435  switch_channel_set_variable(caller_channel, "absolute_codec_string", switch_channel_get_variable(channel, "ep_codec_string"));
436  } else if (switch_true(var)) {
437  switch_codec_implementation_t impl = { 0 };
438  switch_codec_implementation_t video_impl = { 0 };
439  char tmp[128] = "";
440 
442  const char *ep = switch_channel_get_variable(caller_channel, "ep_codec_string");
443 
444  if (switch_core_session_get_video_read_impl(session, &video_impl) == SWITCH_STATUS_SUCCESS) {
445  switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui,%s",
446  impl.iananame, impl.samples_per_second, (uint32_t)impl.microseconds_per_packet / 1000,
447  video_impl.iananame);
448  } else {
449  switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui",
450  impl.iananame, impl.samples_per_second, (uint32_t)impl.microseconds_per_packet / 1000);
451  }
452 
453  if (ep && switch_stristr(impl.iananame, ep)) {
454  switch_channel_set_variable(caller_channel, "absolute_codec_string", tmp);
455  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "Setting codec string on %s to %s\n",
456  switch_channel_get_name(caller_channel), tmp);
457  } else {
458  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "Codec string %s not supported on %s, skipping inheritance\n",
459  tmp, switch_channel_get_name(caller_channel));
460  }
461  } else {
463  "Error inheriting codec. Channel %s has no read codec yet.\n",
464  switch_channel_get_name(channel));
465  }
466 
467  }
468 }
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
#define zstr(x)
Definition: switch_utils.h:314
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define switch_channel_get_variable(_c, _v)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char * switch_stristr(const char *instr, const char *str)
A table of settings and callbacks that define a paticular implementation of a codec.
switch_status_t switch_core_session_get_video_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
#define switch_channel_set_variable(_channel, _var, _val)
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
#define SWITCH_CHANNEL_CHANNEL_LOG(x)

◆ launch_collect_thread()

static void launch_collect_thread ( struct key_collect collect)
static

Definition at line 286 of file switch_ivr_originate.c.

References collect_thread_run(), key_collect::session, switch_core_session_get_pool(), switch_thread_create(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_detach_set(), switch_threadattr_stacksize_set(), and thread.

Referenced by check_channel_status().

287 {
289  switch_threadattr_t *thd_attr = NULL;
290 
292  switch_threadattr_detach_set(thd_attr, 1);
294  switch_thread_create(&thread, thd_attr, collect_thread_run, collect, switch_core_session_get_pool(collect->session));
295 }
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:683
static switch_thread_t * thread
Definition: switch_log.c:486
switch_status_t switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on)
Definition: switch_apr.c:678
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:584
static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void *obj)
switch_core_session_t * session
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:665
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:698
struct fspr_thread_t switch_thread_t
Definition: switch_apr.h:941
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.

◆ leg_list_serialize_json_obj()

static switch_status_t leg_list_serialize_json_obj ( switch_dial_leg_list_t ll,
cJSON **  json 
)
static

Definition at line 4654 of file switch_ivr_originate.c.

References switch_dial_leg_list_s::leg_idx, leg_serialize_json_obj(), switch_dial_leg_list_s::legs, and SWITCH_STATUS_SUCCESS.

Referenced by switch_dial_handle_serialize_json_obj().

4655 {
4656  int i;
4657  cJSON *legs_json = cJSON_CreateArray();
4658  *json = cJSON_CreateObject();
4659  cJSON_AddItemToObject(*json, "legs", legs_json);
4660  for (i = 0; i < ll->leg_idx; i++) {
4661  switch_dial_leg_t *leg = ll->legs[i];
4662  cJSON *leg_json = NULL;
4663  if (leg_serialize_json_obj(leg, &leg_json) == SWITCH_STATUS_SUCCESS && leg_json) {
4664  cJSON_AddItemToArray(legs_json, leg_json);
4665  }
4666  }
4667  return SWITCH_STATUS_SUCCESS;
4668 }
static switch_status_t leg_serialize_json_obj(switch_dial_leg_t *leg, cJSON **json)
switch_dial_leg_t * legs[MAX_PEERS]

◆ leg_serialize_json_obj()

static switch_status_t leg_serialize_json_obj ( switch_dial_leg_t leg,
cJSON **  json 
)
static

Definition at line 4640 of file switch_ivr_originate.c.

References switch_dial_leg_s::dial_string, switch_dial_leg_s::leg_vars, SWITCH_STATUS_SUCCESS, and vars_serialize_json_obj().

Referenced by leg_list_serialize_json_obj().

4641 {
4642  cJSON *vars_json = NULL;
4643  *json = cJSON_CreateObject();
4644  if (leg->dial_string) {
4645  cJSON_AddStringToObject(*json, "dial_string", leg->dial_string);
4646  }
4647  if (leg->leg_vars && vars_serialize_json_obj(leg->leg_vars, &vars_json) == SWITCH_STATUS_SUCCESS && vars_json) {
4648  cJSON_AddItemToObject(*json, "vars", vars_json);
4649  }
4650  return SWITCH_STATUS_SUCCESS;
4651 }
switch_event_t * leg_vars
static switch_status_t vars_serialize_json_obj(switch_event_t *event, cJSON **json)

◆ monitor_callback()

static switch_bool_t monitor_callback ( switch_core_session_t session,
const char *  app,
const char *  data 
)
static

Definition at line 381 of file switch_ivr_originate.c.

References originate_global_t::early_ok, originate_global_t::ignore_early_media, originate_global_t::ignore_ring_ready, originate_global_t::monitor_early_media_ring_count, originate_global_t::monitor_early_media_ring_total, originate_global_t::progress, originate_global_t::ring_ready, SWITCH_CAUSE_USER_BUSY, switch_channel_get_private(), switch_channel_get_variable, switch_channel_hangup, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_channel_set_variable, switch_channel_str2cause(), switch_core_session_get_channel(), SWITCH_FALSE, SWITCH_LOG_DEBUG, switch_log_printf(), and SWITCH_TRUE.

Referenced by check_channel_status().

382 {
383  if (app) {
385  if (!strcmp(app, "fail")) {
386  const char *bd = switch_channel_get_variable(channel, "monitor_fail_dispo");
387  if (!bd) {
388  bd = "monitor_early_media_fail";
389  }
390  switch_channel_set_variable(channel, "DIALSTATUS", "BUSY");
391  switch_channel_set_variable(channel, "originate_disposition", bd);
393  } else if (!strcmp(app, "ring")) {
394  originate_global_t *oglobals = (originate_global_t *) switch_channel_get_private(channel, "_oglobals_");
395  const char *bd = switch_channel_get_variable(channel, "monitor_ring_dispo");
396  if (!bd) {
397  bd = "monitor_early_media_ring";
398  }
399  switch_channel_set_variable(channel, "originate_disposition", bd);
400  switch_channel_set_variable(channel, "DIALSTATUS", "EARLY");
401 
402  if (oglobals) {
406  return SWITCH_TRUE;
407  }
408 
409  switch_channel_set_private(channel, "_oglobals_", NULL);
410 
411  if (!oglobals->progress) {
412  oglobals->progress = 1;
413  }
414 
415  if (!oglobals->ring_ready && !oglobals->ignore_ring_ready) {
416  oglobals->ring_ready = 1;
417  }
418 
419  if (!oglobals->ignore_early_media && !oglobals->early_ok) {
420  oglobals->early_ok = 1;
421  }
422  }
423  }
424  }
425 
426  return SWITCH_FALSE;
427 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define switch_channel_get_variable(_c, _v)
switch_call_cause_t switch_channel_str2cause(_In_ const char *str)
return a cause code for a given string
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_channel_set_variable(_channel, _var, _val)

◆ o_bridge_on_dtmf()

static switch_status_t o_bridge_on_dtmf ( switch_core_session_t session,
void *  input,
switch_input_type_t  itype,
void *  buf,
unsigned int  buflen 
)
static

Definition at line 4898 of file switch_ivr_originate.c.

References switch_dtmf_t::digit, SWITCH_INPUT_TYPE_DTMF, SWITCH_STATUS_BREAK, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_enterprise_orig_and_bridge(), and switch_ivr_orig_and_bridge().

4899 {
4900  char *str = (char *) buf;
4901 
4902  if (str && input && itype == SWITCH_INPUT_TYPE_DTMF) {
4903  switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
4904  if (strchr(str, dtmf->digit)) {
4905  return SWITCH_STATUS_BREAK;
4906  }
4907  }
4908  return SWITCH_STATUS_SUCCESS;
4909 }
switch_byte_t switch_byte_t * buf

◆ originate_on_consume_media_transmit()

static switch_status_t originate_on_consume_media_transmit ( switch_core_session_t session)
static

Definition at line 40 of file switch_ivr_originate.c.

References CF_CONSUME_ON_ORIGINATE, CF_ORIGINATING, CF_PROXY_MODE, CF_TAGGED, CS_CONSUME_MEDIA, switch_channel_clear_state_handler(), switch_channel_get_state(), switch_channel_media_ready, switch_channel_test_flag(), switch_core_session_get_channel(), SWITCH_FALSE, switch_ivr_parse_all_messages(), switch_ivr_sleep(), SWITCH_STATUS_FALSE, and switch_yield.

Referenced by originate_on_routing().

41 {
43 
45  while (switch_channel_test_flag(channel, CF_ORIGINATING) &&
47  if (!switch_channel_media_ready(channel)) {
48  switch_yield(10000);
49  } else {
50  switch_ivr_sleep(session, 10, SWITCH_FALSE, NULL);
51  }
53  }
54  }
55 
57 
58  return SWITCH_STATUS_FALSE;
59 }
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
switch_status_t switch_ivr_sleep(switch_core_session_t *session, uint32_t ms, switch_bool_t sync, switch_input_args_t *args)
Wait for time to pass for a specified number of milliseconds.
Definition: switch_ivr.c:127
#define switch_channel_media_ready(_channel)
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
void switch_channel_clear_state_handler(switch_channel_t *channel, const switch_state_handler_table_t *state_handler)
clear a state handler table from a given channel
static const switch_state_handler_table_t originate_state_handlers
switch_status_t switch_ivr_parse_all_messages(switch_core_session_t *session)
Definition: switch_ivr.c:847

◆ originate_on_routing()

static switch_status_t originate_on_routing ( switch_core_session_t session)
static

Definition at line 61 of file switch_ivr_originate.c.

References CS_CONSUME_MEDIA, CS_ROUTING, originate_on_consume_media_transmit(), switch_channel_get_state(), switch_channel_set_state, switch_core_session_get_channel(), and SWITCH_STATUS_FALSE.

62 {
64 
65  if (switch_channel_get_state(channel) == CS_ROUTING) {
66  /* put the channel in a passive state until it is answered */
68  }
69 
70  return SWITCH_STATUS_FALSE;
71 }
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.

◆ setup_ringback()

static switch_status_t setup_ringback ( originate_global_t oglobals,
originate_status_t originate_status,
int  len,
const char *  ringback_data,
ringback_t ringback,
switch_frame_t write_frame,
switch_codec_t write_codec 
)
static

Definition at line 1291 of file switch_ivr_originate.c.

References switch_codec_implementation::actual_samples_per_second, ringback::asis, ringback::audio_buffer, originate_global_t::bridge_early_media, CF_ANSWERED, CF_EARLY_MEDIA, switch_file_handle::channels, ringback::channels, switch_frame::codec, switch_frame::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, ringback::fh, ringback::fhb, originate_global_t::gen_ringback, switch_codec_implementation::iananame, switch_codec_implementation::impl_id, switch_codec::implementation, inherit_codec(), memset(), switch_codec_implementation::microseconds_per_packet, switch_codec_implementation::number_of_channels, originate_status_t::peer_session, teletone_generation_session::rate, switch_file_handle::samplerate, switch_frame::samples, originate_global_t::session, ringback::silence, switch_buffer_create_dynamic(), switch_buffer_destroy(), switch_buffer_set_loops(), SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL, SWITCH_CHANNEL_CHANNEL_LOG, switch_channel_get_name(), switch_channel_hangup, switch_channel_media_ready, switch_channel_pre_answer, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, SWITCH_CODEC_FLAG_PASSTHROUGH, switch_core_codec_init, switch_core_file_close(), switch_core_file_open, switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_codec(), switch_core_session_get_read_impl(), switch_core_session_get_write_codec(), switch_core_session_get_write_impl(), switch_core_session_set_read_codec(), SWITCH_FILE_DATA_SHORT, SWITCH_FILE_FLAG_READ, SWITCH_FILE_OPEN, switch_goto_status, switch_is_file_path(), SWITCH_IVR_VERIFY_SILENCE_DIVISOR, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, switch_mprintf(), switch_safe_free, SWITCH_STATUS_BREAK, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, switch_test_flag, SWITCH_URL_SEPARATOR, teletone_destroy_session(), teletone_handler(), teletone_init_session(), teletone_run(), ringback::ts, and zstr.

Referenced by switch_ivr_originate().

1293 {
1295  switch_channel_t *caller_channel = switch_core_session_get_channel(oglobals->session);
1296  switch_codec_t *read_codec = NULL;
1297  char *tmp_data = NULL;
1298 
1299  if (!switch_channel_test_flag(caller_channel, CF_ANSWERED)
1300  && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
1301  if (oglobals->bridge_early_media > -1 && len == 1 && originate_status[0].peer_session &&
1302  switch_channel_media_ready(originate_status[0].peer_channel)) {
1303  inherit_codec(caller_channel, originate_status[0].peer_session);
1304  }
1305  if ((status = switch_channel_pre_answer(caller_channel)) != SWITCH_STATUS_SUCCESS) {
1306  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n",
1307  switch_channel_get_name(caller_channel));
1309  }
1310  }
1311 
1312  if ((read_codec = switch_core_session_get_read_codec(oglobals->session))) {
1314  if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) {
1315  ringback->asis++;
1316  }
1317  } else if (oglobals->bridge_early_media > -1 && zstr(ringback_data) && len == 1 && originate_status[0].peer_session) {
1318  switch_codec_implementation_t read_impl = { 0 }, write_impl = { 0 };
1319 
1320  if (switch_channel_ready(originate_status[0].peer_channel)
1321  && switch_core_session_get_read_impl(originate_status[0].peer_session, &read_impl) == SWITCH_STATUS_SUCCESS
1322  && switch_core_session_get_write_impl(oglobals->session, &write_impl) == SWITCH_STATUS_SUCCESS) {
1323  if (read_impl.impl_id == write_impl.impl_id &&
1324  read_impl.microseconds_per_packet == write_impl.microseconds_per_packet &&
1325  read_impl.actual_samples_per_second == write_impl.actual_samples_per_second) {
1326  ringback->asis++;
1327  write_frame->codec = switch_core_session_get_write_codec(originate_status[0].peer_session);
1328  write_frame->datalen = write_frame->codec->implementation->decoded_bytes_per_packet;
1329  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "bridge_early_media: passthrough enabled\n");
1330  } else {
1331  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "bridge_early_media: codecs don't match (%s@%uh@%di / %s@%uh@%di)\n",
1332  read_impl.iananame, read_impl.actual_samples_per_second, read_impl.microseconds_per_packet / 1000,
1333  write_impl.iananame, write_impl.actual_samples_per_second, write_impl.microseconds_per_packet / 1000);
1334  }
1335  }
1336  }
1337 
1338  if (!ringback->asis) {
1339  switch_codec_implementation_t peer_read_impl = { 0 };
1340 
1342  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_WARNING, "%s Ringback not supported in passthrough codec mode.\n",
1343  switch_channel_get_name(caller_channel));
1345  }
1346 
1347  if (oglobals->bridge_early_media > -1 && zstr(ringback_data) && len == 1 && originate_status[0].peer_session) {
1348  switch_core_session_get_read_impl(originate_status[0].peer_session, &peer_read_impl);
1349  } else {
1350  switch_core_session_get_read_impl(oglobals->session, &peer_read_impl);
1351  }
1352 
1353  if (switch_core_codec_init(write_codec,
1354  "L16",
1355  NULL,
1356  NULL,
1357  peer_read_impl.actual_samples_per_second,
1358  peer_read_impl.microseconds_per_packet / 1000,
1361 
1362 
1364  "Raw Codec Activation Success L16@%uhz %d channel %dms\n",
1365  peer_read_impl.actual_samples_per_second, peer_read_impl.number_of_channels, peer_read_impl.microseconds_per_packet / 1000);
1366  write_frame->codec = write_codec;
1367  write_frame->datalen = peer_read_impl.decoded_bytes_per_packet;
1368  write_frame->samples = write_frame->datalen / 2;
1369  memset(write_frame->data, 255, write_frame->datalen);
1370  switch_core_session_set_read_codec(oglobals->session, write_codec);
1371  } else {
1372  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_ERROR, "Codec Error!\n");
1374  read_codec = NULL;
1376  }
1377  }
1378 
1379  oglobals->gen_ringback = 1;
1380 
1381  if (zstr(ringback_data)) {
1383  }
1384 
1386  char *ext;
1387 
1388  if (ringback->asis) {
1389  write_frame->codec = read_codec;
1390  ext = read_codec->implementation->iananame;
1391  tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
1392  ringback_data = tmp_data;
1393  }
1394 
1395  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
1396 
1397  if (switch_test_flag((&ringback->fhb), SWITCH_FILE_OPEN)) {
1398  switch_core_file_close(&ringback->fhb);
1399  }
1400 
1401 
1402  ringback->fhb.channels = read_codec->implementation->number_of_channels;
1403  ringback->fhb.samplerate = read_codec->implementation->actual_samples_per_second;
1404  if (switch_core_file_open(&ringback->fhb,
1405  ringback_data,
1406  read_codec->implementation->number_of_channels,
1409  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_ERROR, "Error Playing File\n");
1410  switch_safe_free(tmp_data);
1412  //switch_goto_status(SWITCH_STATUS_FALSE, end);
1413  }
1414  ringback->fh = &ringback->fhb;
1415 
1416  } else if (!strncasecmp(ringback_data, "silence", 7)) {
1417  const char *c = ringback_data + 7;
1418  if (*c == ':') {
1419  c++;
1420  if (c) {
1421  ringback->silence = atoi(c);
1422  }
1423  }
1425  } else {
1426  if (ringback->audio_buffer) {
1427  switch_buffer_destroy(&ringback->audio_buffer);
1428  teletone_destroy_session(&ringback->ts);
1429  }
1430 
1431  switch_buffer_create_dynamic(&ringback->audio_buffer, 512, 1024, 0);
1432  switch_buffer_set_loops(ringback->audio_buffer, -1);
1433 
1434  teletone_init_session(&ringback->ts, 0, teletone_handler, ringback);
1435  ringback->ts.rate = read_codec->implementation->actual_samples_per_second;
1436  ringback->channels = read_codec->implementation->number_of_channels;
1437  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
1438  /* ringback->ts.debug = 1;
1439  ringback->ts.debug_stream = switch_core_get_console(); */
1440 
1441  if (teletone_run(&ringback->ts, ringback_data)) {
1442  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_ERROR, "Error Playing Tone\n");
1443  teletone_destroy_session(&ringback->ts);
1444  switch_buffer_destroy(&ringback->audio_buffer);
1446  }
1447  }
1448  }
1449 
1450  end:
1451 
1452  switch_safe_free(tmp_data);
1453 
1454  return status;
1455 
1456 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_core_file_open(_fh, _file_path, _channels, _rate, _flags, _pool)
Open a media file using file format modules.
Definition: switch_core.h:1963
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
teletone_generation_session_t ts
switch_status_t switch_core_session_set_read_codec(_In_ switch_core_session_t *session, switch_codec_t *codec)
Assign the read codec to a given session.
#define SWITCH_URL_SEPARATOR
Definition: switch_types.h:126
switch_file_handle_t fhb
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
#define switch_channel_ready(_channel)
#define switch_channel_media_ready(_channel)
static void inherit_codec(switch_channel_t *caller_channel, switch_core_session_t *session)
int teletone_destroy_session(teletone_generation_session_t *ts)
Free the buffer allocated by a tone generation session.
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
switch_codec_t * codec
Definition: switch_frame.h:56
switch_codec_t * switch_core_session_get_write_codec(_In_ switch_core_session_t *session)
Retrieve the write codec from a given session.
#define zstr(x)
Definition: switch_utils.h:314
switch_codec_t * switch_core_session_get_read_codec(_In_ switch_core_session_t *session)
Retrieve the read codec from a given session.
int teletone_run(teletone_generation_session_t *ts, const char *cmd)
Execute a tone generation script and call callbacks after each instruction.
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
int teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data)
Initilize a tone generation session.
const switch_codec_implementation_t * implementation
uint32_t datalen
Definition: switch_frame.h:68
switch_core_session_t * session
void switch_buffer_set_loops(_In_ switch_buffer_t *buffer, _In_ int32_t loops)
Assign a number of loops to read.
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
#define SWITCH_IVR_VERIFY_SILENCE_DIVISOR(divisor)
Definition: switch_ivr.h:68
#define switch_core_codec_init(_codec, _codec_name, _modname, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool)
Initialize a codec handle.
Definition: switch_core.h:1693
switch_status_t switch_core_session_get_write_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
switch_core_session_t * peer_session
switch_status_t
Common return values.
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:287
switch_buffer_t * audio_buffer
static switch_bool_t switch_is_file_path(const char *file)
uint32_t samples
Definition: switch_frame.h:72
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
switch_file_handle_t * fh
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
memset(buf, 0, buflen)
#define SWITCH_CHANNEL_CHANNEL_LOG(x)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)

◆ switch_dial_handle_dup()

static switch_status_t switch_dial_handle_dup ( switch_dial_handle_t **  handle,
switch_dial_handle_t todup 
)
static

Definition at line 4378 of file switch_ivr_originate.c.

References switch_dial_leg_s::dial_string, switch_dial_handle_s::global_vars, switch_dial_handle_s::is_sub, switch_dial_leg_list_s::leg_idx, switch_dial_handle_s::leg_list_idx, switch_dial_handle_s::leg_lists, switch_dial_leg_s::leg_vars, switch_dial_leg_list_s::legs, switch_assert, switch_dial_handle_add_leg_list(), switch_dial_handle_create(), switch_dial_leg_list_add_leg(), switch_event_dup(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_enterprise_originate().

4379 {
4380  int i;
4382 
4383  if (!todup || !handle) {
4384  return SWITCH_STATUS_FALSE;
4385  }
4386 
4387  *handle = NULL;
4388 
4390  switch_assert(hp);
4391 
4392  for (i = 0; i < todup->leg_list_idx; i++) {
4393  int j;
4394  switch_dial_leg_list_t *ll_todup = todup->leg_lists[i];
4395  switch_dial_leg_list_t *ll = NULL;
4397  for (j = 0; j < ll_todup->leg_idx; j++) {
4398  switch_dial_leg_t *leg;
4399  switch_dial_leg_t *leg_todup = ll_todup->legs[j];
4400  switch_dial_leg_list_add_leg(ll, &leg, leg_todup->dial_string);
4401  if (leg_todup->leg_vars) {
4402  switch_event_dup(&leg->leg_vars, leg_todup->leg_vars);
4403  }
4404  }
4405  }
4406 
4407  if (todup->global_vars) {
4409  }
4410 
4411  hp->is_sub = todup->is_sub;
4412 
4413  *handle = hp;
4414 
4415  return SWITCH_STATUS_SUCCESS;
4416 }
void switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP)
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
void switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *dial_string)
switch_event_t * leg_vars
switch_event_t * global_vars
switch_dial_leg_list_t * leg_lists[MAX_PEERS]
#define switch_assert(expr)
switch_status_t switch_dial_handle_create(switch_dial_handle_t **handle)
switch_dial_leg_t * legs[MAX_PEERS]

◆ switch_dial_handle_list_add_handle()

static switch_status_t switch_dial_handle_list_add_handle ( switch_dial_handle_list_t hl,
switch_dial_handle_t handle 
)
static

◆ teletone_handler()

static int teletone_handler ( teletone_generation_session_t ts,
teletone_tone_map_t map 
)
static

Definition at line 908 of file switch_ivr_originate.c.

References ringback::audio_buffer, buf, teletone_generation_session::buffer, buflen, ringback::channels, ringback::mux_buf, ringback::mux_buflen, switch_buffer_write(), switch_mux_channels(), teletone_mux_tones(), and teletone_generation_session::user_data.

Referenced by setup_ringback(), and switch_ivr_wait_for_answer().

909 {
910  ringback_t *tto = ts->user_data;
911  int wrote;
912  void *buf;
913  int buflen;
914 
915  if (!tto) {
916  return -1;
917  }
918  wrote = teletone_mux_tones(ts, map);
919  if (wrote <= 0) {
920  return -1;
921  }
922 
923  if (tto->channels != 1) {
924  if (tto->mux_buflen < wrote * 2 * tto->channels) {
925  tto->mux_buflen = wrote * 2 * tto->channels;
926  tto->mux_buf = realloc(tto->mux_buf, tto->mux_buflen);
927  }
928  memcpy(tto->mux_buf, ts->buffer, wrote * 2);
929  switch_mux_channels((int16_t *) tto->mux_buf, wrote, 1, tto->channels);
930  buf = tto->mux_buf;
931  buflen = wrote * 2 * tto->channels;
932  } else {
933  buf = ts->buffer;
934  buflen = wrote * 2;
935  }
936 
937  switch_buffer_write(tto->audio_buffer, buf, buflen);
938 
939  return 0;
940 }
int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map)
Execute a single tone generation instruction.
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
switch_byte_t switch_byte_t * buf
switch_byte_t switch_byte_t uint32_t buflen
void switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
switch_buffer_t * audio_buffer

◆ vars_serialize_json_obj()

static switch_status_t vars_serialize_json_obj ( switch_event_t event,
cJSON **  json 
)
static

Definition at line 4627 of file switch_ivr_originate.c.

References switch_event::headers, switch_event_header::name, switch_event_header::next, SWITCH_STATUS_SUCCESS, and switch_event_header::value.

Referenced by leg_serialize_json_obj(), switch_dial_handle_list_serialize_json_obj(), and switch_dial_handle_serialize_json_obj().

4628 {
4630  *json = cJSON_CreateObject();
4631  for (hp = event->headers; hp; hp = hp->next) {
4632  if (hp->name && hp->value) {
4633  cJSON_AddItemToObject(*json, hp->name, cJSON_CreateString(hp->value));
4634  }
4635  }
4636  return SWITCH_STATUS_SUCCESS;
4637 }
An event Header.
Definition: switch_event.h:65
struct switch_event_header * next
Definition: switch_event.h:76
switch_event_header_t * headers
Definition: switch_event.h:90

◆ wait_for_cause()

static void wait_for_cause ( switch_channel_t channel)
static

Definition at line 2053 of file switch_ivr_originate.c.

References peer_eligible, SWITCH_CAUSE_NONE, switch_channel_get_cause(), and switch_yield.

Referenced by switch_ivr_originate().

2054 {
2055  int sanity = 5;
2056 
2057  while (--sanity > 0 && peer_eligible(channel) && switch_channel_get_cause(channel) == SWITCH_CAUSE_NONE) {
2058  switch_yield(10000);
2059  }
2060 }
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
#define peer_eligible(_peer)
switch_call_cause_t switch_channel_get_cause(_In_ switch_channel_t *channel)
return the cause code for a given channel

Variable Documentation

◆ originate_state_handlers

static const switch_state_handler_table_t originate_state_handlers
static
Initial value:
= {
NULL,
NULL,
NULL,
NULL,
originate_on_consume_media_transmit
}
static switch_status_t originate_on_routing(switch_core_session_t *session)
static switch_status_t originate_on_consume_media_transmit(switch_core_session_t *session)

Definition at line 38 of file switch_ivr_originate.c.