FreeSWITCH API Documentation  1.7.0
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  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 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, originate_status_t *originate_status, 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, originate_status_t *originate_status, uint32_t len, switch_call_cause_t *force_reason)
 
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)
 
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)
 Make an outgoing call. More...
 

Variables

static const
switch_state_handler_table_t 
originate_state_handlers
 

Macro Definition Documentation

#define MAX_PEERS   128
#define peer_eligible (   _peer)
Value:
(_peer && !(switch_channel_test_flag(_peer, CF_TRANSFER) || \
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
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 1883 of file switch_ivr_originate.c.

Referenced by switch_ivr_originate(), and wait_for_cause().

#define QUOTED_ESC_COMMA   1

Definition at line 35 of file switch_ivr_originate.c.

Referenced by switch_ivr_originate().

#define UNQUOTED_ESC_COMMA   2

Definition at line 36 of file switch_ivr_originate.c.

Referenced by switch_ivr_originate().

Typedef Documentation

typedef struct early_state early_state_t

Definition at line 1744 of file switch_ivr_originate.c.

typedef struct ringback ringback_t

Definition at line 824 of file switch_ivr_originate.c.

Enumeration Type Documentation

enum abort_t
Enumerator
IDX_XFER 
IDX_KEY_CANCEL 
IDX_TIMEOUT 
IDX_CANCEL 
IDX_NADA 

Definition at line 133 of file switch_ivr_originate.c.

Function Documentation

static uint8_t check_channel_status ( originate_global_t oglobals,
originate_status_t originate_status,
uint32_t  len,
switch_call_cause_t force_reason 
)
static

Definition at line 425 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_timeout, key_collect::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(), 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_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_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_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(), SWITCH_TRUE, and zstr.

Referenced by switch_ivr_originate().

426 {
427 
428  uint32_t i;
429  uint8_t rval = 0;
430  switch_channel_t *caller_channel = NULL;
431  int pindex = -1;
432  char bug_key[256] = "";
433  int send_ringback = 0;
434  uint8_t ring_ready_val = 0;
435  int pickups = 0;
436 
437  oglobals->hups = 0;
438  oglobals->idx = IDX_NADA;
439 
440 
441  if (oglobals->session) {
442  caller_channel = switch_core_session_get_channel(oglobals->session);
443  if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
444  caller_channel = NULL;
445  }
446  }
447 
448 
449  for (i = 0; i < len; i++) {
450  if (originate_status[i].peer_channel && switch_channel_test_flag(originate_status[i].peer_channel, CF_CHANNEL_SWAP)) {
451  const char *key = switch_channel_get_variable(originate_status[i].peer_channel, "channel_swap_uuid");
452  switch_core_session_t *swap_session, *old_session;
453 
454  if ((swap_session = switch_core_session_locate(key))) {
455  switch_channel_clear_flag(originate_status[i].peer_channel, CF_CHANNEL_SWAP);
456  switch_channel_hangup(originate_status[i].peer_channel, SWITCH_CAUSE_PICKED_OFF);
457 
458  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(originate_status[i].peer_channel), SWITCH_LOG_DEBUG, "Swapping %s for %s\n",
459  switch_core_session_get_name(swap_session), switch_channel_get_name(originate_status[i].peer_channel));
460 
461 
462  old_session = originate_status[i].peer_session;
463  originate_status[i].peer_session = swap_session;
464  originate_status[i].peer_channel = switch_core_session_get_channel(originate_status[i].peer_session);
465  originate_status[i].caller_profile = switch_channel_get_caller_profile(originate_status[i].peer_channel);
466  switch_channel_set_flag(originate_status[i].peer_channel, CF_ORIGINATING);
467 
468  switch_channel_answer(originate_status[i].peer_channel);
469 
470  switch_channel_set_variable(originate_status[i].peer_channel, "picked_up_uuid", switch_core_session_get_uuid(old_session));
471  switch_channel_execute_on(originate_status[i].peer_channel, "execute_on_pickup");
472  switch_channel_api_on(originate_status[i].peer_channel, "api_on_pickup");
473 
474  switch_core_session_rwunlock(old_session);
475  break;
476  }
477  }
478  }
479 
480  for (i = 0; i < len; i++) {
482 
483  if (originate_status[i].tagged && originate_status[i].peer_session) {
484  switch_channel_t *channel = switch_core_session_get_channel(originate_status[i].peer_session);
485  uint32_t j;
486 
487  if (switch_channel_down_nosig(channel)) {
489 
490  for (j = 0; j < len; j++) {
491  channel = switch_core_session_get_channel(originate_status[j].peer_session);
492  switch_channel_hangup(channel, cause);
493  }
494  oglobals->hups = len;
495  rval = 0;
496  goto end;
497  }
498  }
499 
500 
501  if (originate_status[i].peer_channel && switch_channel_test_flag(originate_status[i].peer_channel, CF_PICKUP)) {
502  pickups++;
503  }
504 
505  if (!(originate_status[i].peer_channel && originate_status[i].peer_session)) {
506  oglobals->hups++;
507  continue;
508  }
509 
510  if ((ring_ready_val = (uint8_t)switch_channel_test_flag(originate_status[i].peer_channel, CF_RING_READY))) {
511  if (!originate_status[i].ring_ready) {
512  originate_status[i].ring_ready = ring_ready_val;
513  }
514 
515  if (oglobals->sending_ringback == 1) {
516  send_ringback++;
517  pindex = (uint32_t) i;
518  } else {
519  if (!oglobals->ring_ready) {
520  oglobals->ring_ready = ring_ready_val;
521  if (caller_channel && !oglobals->ignore_ring_ready) {
522  if (len == 1) {
523  switch_channel_pass_callee_id(originate_status[0].peer_channel, caller_channel);
524  }
525  switch_channel_ring_ready_value(caller_channel, ring_ready_val);
526  oglobals->sent_ring = ring_ready_val;
527  }
528  }
529  }
530  }
531 
532  if (switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_MEDIA)) {
533 
534  if (oglobals->ignore_early_media == 3 && oglobals->bridge_early_media == -1) {
535  oglobals->bridge_early_media = i;
536  oglobals->ringback_ok = 1;
537  }
538 
539  if (oglobals->sending_ringback == 1) {
540  send_ringback++;
541  pindex = (uint32_t) i;
542  } else if (!oglobals->sent_ring && oglobals->ignore_early_media == 2 && len == 1 && caller_channel && !oglobals->ignore_ring_ready) {
543  switch_channel_pass_callee_id(originate_status[0].peer_channel, caller_channel);
544  switch_channel_ring_ready(caller_channel);
545  oglobals->sent_ring = 1;
546  }
547 
548  if (!originate_status[i].early_media) {
549  originate_status[i].early_media = 1;
550  if (oglobals->early_ok) {
551  pindex = i;
552  }
553 
554  if (oglobals->monitor_early_media_fail) {
555  const char *var = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_fail");
556  if (!zstr(var)) {
557  char *fail_array[128] = { 0 };
558  int fail_count = 0;
559  char *fail_data = strdup(var);
560  int fx;
561  int y = 0;
562 
563  switch_assert(fail_data);
564  fail_count = switch_separate_string(fail_data, '!', fail_array, (sizeof(fail_array) / sizeof(fail_array[0])));
565 
566  for (fx = 0; fx < fail_count; fx++) {
567  char *cause = fail_array[fx];
568  int hits = 2;
569  char *p, *q;
570 
571  if (!(p = strchr(cause, ':'))) {
572  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
573  continue;
574  }
575  *p++ = '\0';
576 
577 
578  if (!p) {
579  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
580  continue;
581  }
582 
583 
584  if (!(hits = atoi(p))) {
585  hits = 2;
586  }
587 
588 
589  if (!(p = strchr(p, ':'))) {
590  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
591  continue;
592  }
593  *p++ = '\0';
594 
595  if (!p) {
596  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
597  continue;
598  }
599 
600  for (q = p; q && *q; q++) {
601  if (*q == '+') {
602  *q = ',';
603  }
604  }
605  switch_snprintf(bug_key, sizeof(bug_key), "monitor_early_media_fail_%d", ++y);
606  switch_ivr_tone_detect_session(originate_status[i].peer_session, bug_key, p, "r", 0, hits, "fail", cause, monitor_callback);
607 
608  }
609 
610  switch_safe_free(fail_data);
611 
612  }
613  }
614 
615  if (oglobals->monitor_early_media_ring) {
616  const char *var = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_ring");
617  const char *var_total = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_ring_total");
618  if (!zstr(var)) {
619  char *ring_array[128] = { 0 };
620  int ring_count = 0;
621  char *ring_data = strdup(var);
622  int fx;
623  int y = 0;
624 
625  switch_assert(ring_data);
626  ring_count = switch_separate_string(ring_data, '!', ring_array, (sizeof(ring_array) / sizeof(ring_array[0])));
627 
628  for (fx = 0; fx < ring_count; fx++) {
629  int hits = 2;
630  char *p = ring_array[fx], *q;
631 
632  if (!p) {
633  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
634  continue;
635  }
636 
637  if (!(hits = atoi(p))) {
638  hits = 2;
639  }
640 
641  if (!(p = strchr(p, ':'))) {
642  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
643  continue;
644  }
645  *p++ = '\0';
646 
647  if (!p) {
648  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_ERROR, "Parse Error\n");
649  continue;
650  }
651 
652  for (q = p; q && *q; q++) {
653  if (*q == '+') {
654  *q = ',';
655  }
656  }
657 
658  switch_channel_set_private(originate_status[i].peer_channel, "_oglobals_", oglobals);
659  switch_snprintf(bug_key, sizeof(bug_key), "monitor_early_media_ring_%d", ++y);
660  switch_ivr_tone_detect_session(originate_status[i].peer_session, bug_key, p, "r", 0, hits, "ring", NULL, monitor_callback);
661 
662  }
663 
664  if (var_total) {
665  int tmp = atoi(var_total);
666  if (tmp > 0 && tmp < 100) {
667  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originate_status[i].peer_session), SWITCH_LOG_DEBUG,
668  "%s setting ring total to %d\n", switch_channel_get_name(originate_status[i].peer_channel), tmp);
669  oglobals->monitor_early_media_ring_total = tmp;
670  }
671  }
672 
673  switch_safe_free(ring_data);
674 
675  }
676  }
677  }
678 
679  if (!oglobals->monitor_early_media_ring) {
680 
681  if (!oglobals->progress) {
682  oglobals->progress = 1;
683  }
684 
685  if (!oglobals->ring_ready && !oglobals->ignore_ring_ready) {
686  oglobals->ring_ready = 1;
687 
688  }
689  }
690  }
691 
692  if (!switch_channel_test_flag(originate_status[i].peer_channel, CF_PARK) &&
693  !switch_channel_test_flag(originate_status[i].peer_channel, CF_CONSUME_ON_ORIGINATE)) {
694  if (switch_core_session_messages_waiting(originate_status[i].peer_session)) {
695  if (switch_channel_test_flag(originate_status[i].peer_channel, CF_THREAD_SLEEPING)) {
696  switch_core_session_wake_session_thread(originate_status[i].peer_session);
697  } else {
698  switch_ivr_parse_all_events(originate_status[i].peer_session);
699  }
700  }
701  }
702 
703  if (switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_OK)) {
704  if (!oglobals->early_ok) {
705  oglobals->early_ok = 1;
706  }
707  switch_channel_clear_flag(originate_status[i].peer_channel, CF_EARLY_OK);
708  }
709 
710  if (caller_channel && switch_channel_test_flag(caller_channel, CF_EARLY_OK)) {
711  if (!oglobals->early_ok) {
712  oglobals->early_ok = 1;
713  }
714  switch_channel_clear_flag(caller_channel, CF_EARLY_OK);
715  }
716 
717  state = switch_channel_get_state(originate_status[i].peer_channel);
718  if (state >= CS_HANGUP || state == CS_RESET || switch_channel_test_flag(originate_status[i].peer_channel, CF_TRANSFER) ||
719  switch_channel_test_flag(originate_status[i].peer_channel, CF_REDIRECT) ||
720  switch_channel_test_flag(originate_status[i].peer_channel, CF_BRIDGED) ||
721  !switch_channel_test_flag(originate_status[i].peer_channel, CF_ORIGINATING)
722  ) {
723  (oglobals->hups)++;
724  if (switch_channel_test_flag(originate_status[i].peer_channel, CF_PICKUP)) {
725  pickups--;
726  }
727  } else if ((switch_channel_test_flag(originate_status[i].peer_channel, CF_ANSWERED) ||
728  (oglobals->early_ok && switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_MEDIA)) ||
729  (oglobals->ring_ready && oglobals->return_ring_ready && len == 1 &&
730  switch_channel_test_flag(originate_status[i].peer_channel, CF_RING_READY))
731  )
732  && !switch_channel_test_flag(originate_status[i].peer_channel, CF_TAGGED)
733  ) {
734 
735  if (!zstr(oglobals->key)) {
736  struct key_collect *collect;
737 
738  if (oglobals->cancel_timeout == SWITCH_TRUE) {
739  /* cancel timeout for this leg only */
740  originate_status[i].per_channel_progress_timelimit_sec = 0;
741  originate_status[i].per_channel_timelimit_sec = 0;
742  }
743 
744  if ((collect = switch_core_session_alloc(originate_status[i].peer_session, sizeof(*collect)))) {
745  switch_channel_set_flag(originate_status[i].peer_channel, CF_TAGGED);
746  if (!zstr(oglobals->key)) {
747  collect->key = switch_core_session_strdup(originate_status[i].peer_session, oglobals->key);
748  }
749  if (!zstr(oglobals->file)) {
750  collect->file = switch_core_session_strdup(originate_status[i].peer_session, oglobals->file);
751  }
752  if (!zstr(oglobals->error_file)) {
753  collect->error_file = switch_core_session_strdup(originate_status[i].peer_session, oglobals->error_file);
754  }
755 
756  if (oglobals->confirm_timeout) {
757  collect->confirm_timeout = oglobals->confirm_timeout;
758  } else {
759  collect->confirm_timeout = 5000;
760  }
761 
762  switch_channel_audio_sync(originate_status[i].peer_channel);
763  collect->session = originate_status[i].peer_session;
764  launch_collect_thread(collect);
765  }
766  } else {
767  oglobals->idx = i;
768  pindex = (uint32_t) i;
769  rval = 0;
770  goto end;
771 
772  }
773  } else if (switch_channel_test_flag(originate_status[i].peer_channel, CF_WINNER)) {
774  oglobals->idx = i;
775  rval = 0;
776  pindex = (uint32_t) i;
777  goto end;
778  }
779  }
780 
781  if (oglobals->hups > 0 && oglobals->hups + pickups == len) {
782  rval = 0;
783  } else {
784  rval = 1;
785  }
786 
787  end:
788 
789  if (rval == 0 && pickups) {
790  for (i = 0; i < len; i++) {
791  if (originate_status[i].peer_channel && switch_channel_test_flag(originate_status[i].peer_channel, CF_PICKUP) &&
792  switch_channel_up(originate_status[i].peer_channel)) {
793  switch_channel_hangup(originate_status[i].peer_channel, SWITCH_CAUSE_NO_PICKUP);
794  }
795  }
796  }
797 
798 
799  if (pindex > -1 && caller_channel && switch_channel_ready(caller_channel) && !switch_channel_media_ready(caller_channel) &&
800  switch_channel_media_ready(originate_status[pindex].peer_channel)) {
801  inherit_codec(caller_channel, originate_status[pindex].peer_session);
802  }
803 
804  if (send_ringback) {
805  oglobals->sending_ringback++;
806  }
807 
808  return rval;
809 
810 }
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'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)
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)
#define switch_core_session_get_name(_s)
Definition: switch_core.h:271
switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session)
Parse all commands from an event.
Definition: switch_ivr.c:867
#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:281
_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_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:789
#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)
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's uuid.
Definition: switch_core.h:916
#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
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
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's pool.
Definition: switch_core.h:717
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'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
static int check_per_channel_timeouts ( originate_global_t oglobals,
originate_status_t originate_status,
int  max,
time_t  start,
switch_call_cause_t force_reason 
)
static

Definition at line 257 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_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().

259 {
260  int x = 0, i, delayed_channels = 0, active_channels = 0;
261  uint32_t early_exit_time = 0, delayed_min = 0;
262 
263  time_t elapsed = switch_epoch_time_now(NULL) - start;
264 
265  for (i = 0; i < max; i++) {
266  if (originate_status[i].peer_channel && switch_channel_get_state(originate_status[i].peer_channel) != CS_DESTROY &&
267  switch_channel_get_state(originate_status[i].peer_channel) != CS_REPORTING) {
268  if (originate_status[i].per_channel_delay_start) {
269  delayed_channels++;
270  } else {
271  active_channels++;
272  }
273  }
274  }
275 
276  if (active_channels == 0 && delayed_channels) {
277  for (i = 0; i < max; i++) {
278  if (originate_status[i].peer_channel && originate_status[i].per_channel_delay_start &&
279  (!delayed_min || delayed_min > originate_status[i].per_channel_delay_start)) {
280  delayed_min = originate_status[i].per_channel_delay_start;
281  }
282  }
283  early_exit_time = delayed_min - (uint32_t) elapsed;
284  }
285  for (i = 0; i < max; i++) {
286  if (originate_status[i].peer_channel && originate_status[i].per_channel_delay_start &&
287  (elapsed > originate_status[i].per_channel_delay_start || active_channels == 0)) {
288  if (active_channels == 0) {
289  if (originate_status[i].per_channel_timelimit_sec) {
290  if (originate_status[i].per_channel_timelimit_sec > early_exit_time) {
291  /* 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.... */
292  originate_status[i].per_channel_timelimit_sec -= early_exit_time;
293  } else {
294  originate_status[i].per_channel_timelimit_sec = 1;
295  }
296  }
297  if (originate_status[i].per_channel_progress_timelimit_sec) {
298  if (originate_status[i].per_channel_progress_timelimit_sec > early_exit_time) {
299  /* 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.... */
300  originate_status[i].per_channel_progress_timelimit_sec -= early_exit_time;
301  } else {
302  originate_status[i].per_channel_progress_timelimit_sec = 1;
303  }
304  }
305  originate_status[i].per_channel_delay_start -= delayed_min;
306  } else {
307  originate_status[i].per_channel_delay_start = 0;
308  }
309 
310  if (!originate_status[i].per_channel_delay_start) {
311  switch_channel_clear_flag(originate_status[i].peer_channel, CF_BLOCK_STATE);
312  }
313  }
314 
315  if (originate_status[i].peer_channel && switch_channel_up_nosig(originate_status[i].peer_channel)) {
316  if (originate_status[i].per_channel_progress_timelimit_sec && elapsed > originate_status[i].per_channel_progress_timelimit_sec &&
317  !(switch_channel_test_flag(originate_status[i].peer_channel, CF_RING_READY) ||
318  switch_channel_test_flag(originate_status[i].peer_channel, CF_ANSWERED) ||
319  (!oglobals->monitor_early_media_ring && switch_channel_test_flag(originate_status[i].peer_channel, CF_EARLY_MEDIA))
320  )
321  ) {
322  switch_channel_hangup(originate_status[i].peer_channel, SWITCH_CAUSE_PROGRESS_TIMEOUT);
323  *force_reason = SWITCH_CAUSE_PROGRESS_TIMEOUT;
324  x++;
325  }
326  if (originate_status[i].per_channel_timelimit_sec && elapsed > originate_status[i].per_channel_timelimit_sec) {
327  switch_channel_hangup(originate_status[i].peer_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
328  x++;
329  }
330  }
331  }
332 
333  return x;
334 }
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's state machine to end.
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.
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:321
#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.
static void* SWITCH_THREAD_FUNC collect_thread_run ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 149 of file switch_ivr_originate.c.

References switch_application_interface::application_function, buf, CF_WINNER, key_collect::confirm_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().

150 {
151  struct key_collect *collect = (struct key_collect *) obj;
153  char buf[10] = SWITCH_BLANK_STRING;
154  switch_application_interface_t *application_interface = NULL;
155 
156  if (collect->session) {
158  return NULL;
159  }
160  } else {
161  return NULL;
162  }
163 
164  switch_ivr_sleep(collect->session, 0, SWITCH_TRUE, NULL);
165 
166  if (!strcasecmp(collect->key, "exec")) {
167  char *data;
168  char *app_name, *app_data;
169 
170  if (!(data = collect->file)) {
171  goto wbreak;
172  }
173 
174  app_name = data;
175 
176  if ((app_data = strchr(app_name, ' '))) {
177  *app_data++ = '\0';
178  }
179 
180  if ((application_interface = switch_loadable_module_get_application_interface(app_name)) == 0) {
181  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "Invalid Application %s\n", app_name);
183  goto wbreak;
184  }
185 
186  if (!application_interface->application_function) {
187  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "No Function for %s\n", app_name);
189  goto wbreak;
190  }
191 
192  switch_core_session_exec(collect->session, application_interface, app_data);
193 
194  if (switch_channel_up_nosig(channel)) {
196  switch_channel_set_variable(channel, "group_dial_status", "winner");
197  }
198  goto wbreak;
199  }
200 
201  if (!switch_channel_up_nosig(channel)) {
203  goto wbreak;
204  }
205 
206  while (switch_channel_ready(channel)) {
207  switch_size_t len = strlen(collect->key);
208  const char *file = collect->file;
209  switch_status_t status;
210 
211  memset(buf, 0, sizeof(buf));
212 
213  if (zstr(file)) {
214  file = "silence";
215  }
216 
217  status = switch_ivr_read(collect->session,
218  (uint32_t)len,
219  (uint32_t)len,
220  collect->file, NULL, buf, sizeof(buf), collect->confirm_timeout, NULL, 0);
221 
222 
223  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_TOO_SMALL) {
224  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(collect->session), SWITCH_LOG_ERROR, "%s Error Playing File!\n",
225  switch_channel_get_name(channel));
227  }
228 
229  if (!strcmp(collect->key, buf)) {
231  switch_channel_set_variable(channel, "group_dial_status", "winner");
232  goto wbreak;
233  } else if (collect->error_file) {
234  switch_ivr_play_file(collect->session, NULL, collect->error_file, NULL);
235  }
236  }
237  wbreak:
238 
240 
241  UNPROTECT_INTERFACE(application_interface);
242 
243  return NULL;
244 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it'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:281
_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's registered name.
#define SWITCH_BLANK_STRING
Definition: switch_types.h:47
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)
static void* SWITCH_THREAD_FUNC early_thread_run ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 1747 of file switch_ivr_originate.c.

References switch_codec_implementation::actual_samples_per_second, 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, early_state::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().

1748 {
1749  early_state_t *state = (early_state_t *) obj;
1750  originate_status_t originate_status[MAX_PEERS] = { {0} };
1751  int16_t mux_data[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
1752  int32_t sample;
1753  switch_codec_t read_codecs[MAX_PEERS] = { {0} };
1754  int i, x, ready = 0, answered = 0, ring_ready = 0;
1755  int16_t *data;
1756  uint32_t datalen = 0;
1757  switch_status_t status;
1758  switch_frame_t *read_frame = NULL;
1759  switch_codec_implementation_t read_impl = { 0 };
1760 
1761  for (i = 0; i < MAX_PEERS && i < state->ttl; i++) {
1763  originate_status[i].peer_session = state->originate_status[i].peer_session;
1765  }
1766  }
1767 
1768  if (state->oglobals->session) {
1769  switch_core_session_get_read_impl(state->oglobals->session, &read_impl);
1770  }
1771 
1772  while (state->ready) {
1773  datalen = 0;
1774  memset(mux_data, 0, sizeof(mux_data));
1775  ready = 0;
1776  answered = 0;
1777 
1778  for (i = 0; i < MAX_PEERS && i < state->ttl; i++) {
1779  switch_core_session_t *session = originate_status[i].peer_session;
1780  switch_channel_t *channel = originate_status[i].peer_channel;
1781 
1782  if (!session || !channel || !switch_channel_up(channel)) {
1783  continue;
1784  }
1785 
1786  if (switch_channel_media_ready(channel)) {
1787  ready++;
1788 
1789  if (switch_channel_test_flag(channel, CF_RING_READY)) {
1790  ring_ready = 1;
1791  state->oglobals->bridge_early_media = -1;
1792  state->oglobals->ignore_early_media = 1;
1793  }
1794 
1795  if (switch_channel_test_flag(channel, CF_ANSWERED)) {
1796  answered++;
1797  }
1798 
1799  if (!state->ringback->asis) {
1800  if (!switch_core_codec_ready((&read_codecs[i]))) {
1801  if (switch_core_codec_init(&read_codecs[i],
1802  "L16",
1803  NULL,
1804  NULL,
1805  read_impl.actual_samples_per_second,
1806  read_impl.microseconds_per_packet / 1000,
1809  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n");
1810  }
1811  switch_core_session_set_read_codec(session, NULL);
1812  switch_core_session_set_read_codec(session, &read_codecs[i]);
1813  }
1814  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1815  if (SWITCH_READ_ACCEPTABLE(status) && !switch_test_flag(read_frame, SFF_CNG)) {
1816  data = (int16_t *) read_frame->data;
1817  if (datalen < read_frame->datalen) {
1818  datalen = read_frame->datalen;
1819  }
1820  for (x = 0; x < (int) read_frame->datalen / 2; x++) {
1821  sample = data[x] + mux_data[x];
1822  switch_normalize_to_16bit(sample);
1823  mux_data[x] = (int16_t) sample;
1824  }
1825  }
1826  } else {
1827  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1828  if (SWITCH_READ_ACCEPTABLE(status) && !switch_test_flag(read_frame, SFF_CNG)) {
1829  datalen = read_frame->datalen;
1830  }
1831  break;
1832  }
1833  }
1834  }
1835 
1836  if (!ready || answered || ring_ready) {
1837  break;
1838  }
1839 
1840  if (!datalen) {
1841  continue;
1842  }
1843 
1844  if (state->ringback->asis) {
1845  uint16_t flen = (uint16_t)datalen;
1846  switch_mutex_lock(state->mutex);
1847  switch_buffer_write(state->buffer, &flen, sizeof(uint16_t));
1848  switch_buffer_write(state->buffer, read_frame->data, datalen);
1849  switch_mutex_unlock(state->mutex);
1850  } else {
1851  switch_mutex_lock(state->mutex);
1852  switch_buffer_write(state->buffer, mux_data, datalen);
1853  switch_mutex_unlock(state->mutex);
1854  }
1855  }
1856 
1857 
1858  for (i = 0; i < MAX_PEERS && i < state->ttl; i++) {
1859  switch_core_session_t *session = originate_status[i].peer_session;
1860  switch_channel_t *channel = originate_status[i].peer_channel;
1861 
1862  if (!session) continue;
1863 
1864  if (switch_core_codec_ready((&read_codecs[i]))) {
1865  switch_core_session_set_read_codec(session, NULL);
1866  switch_core_codec_destroy(&read_codecs[i]);
1867  }
1868 
1869  if (switch_channel_up_nosig(channel)) {
1871  }
1872 
1874  }
1875 
1876  if (!ring_ready) {
1877  state->oglobals->early_ok = 1;
1878  }
1879 
1880  return NULL;
1881 }
#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:557
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.
originate_status_t * originate_status
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:290
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.
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
uint32_t datalen
Definition: switch_frame.h:57
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_core_session_t * session
switch_mutex_t * mutex
switch_buffer_t * buffer
An abstraction of a data frame.
Definition: switch_frame.h:43
#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:1602
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:624
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:261
#define switch_channel_up_nosig(_channel)
#define SWITCH_READ_ACCEPTABLE(status)
Definition: switch_utils.h:995
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.
static void* SWITCH_THREAD_FUNC enterprise_originate_ringback_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 1422 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, and zstr.

Referenced by switch_ivr_enterprise_originate().

1423 {
1424  struct ent_originate_ringback *rb_data = (struct ent_originate_ringback *) obj;
1428 
1430 
1431  while (rb_data->running && switch_channel_ready(channel)) {
1433  if (status != SWITCH_STATUS_BREAK) {
1434  if (zstr(rb_data->ringback_data) || !strcasecmp(rb_data->ringback_data, "silence")) {
1435  status = switch_ivr_collect_digits_callback(session, NULL, 0, 0);
1436  } else if (switch_is_file_path(rb_data->ringback_data)) {
1437  status = switch_ivr_play_file(session, NULL, rb_data->ringback_data, NULL);
1438  } else {
1439  status = switch_ivr_gentones(session, rb_data->ringback_data, 0, NULL);
1440  }
1441  }
1442 
1443  if (status == SWITCH_STATUS_BREAK) {
1445  }
1446  }
1448 
1449  rb_data->running = 0;
1450  return NULL;
1451 }
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:1173
#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:281
_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:801
static void* SWITCH_THREAD_FUNC enterprise_originate_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 1393 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::done, enterprise_originate_handle_t::flags, 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().

1394 {
1396 
1397  handle->done = 0;
1398  handle->status = switch_ivr_originate(NULL, &handle->bleg, &handle->cause,
1399  handle->bridgeto, handle->timelimit_sec,
1400  handle->table,
1401  handle->cid_name_override,
1402  handle->cid_num_override, handle->caller_profile_override, handle->ovars, handle->flags, &handle->cancel_cause);
1403 
1404 
1405  handle->done = 1;
1406  switch_mutex_lock(handle->mutex);
1407  switch_mutex_unlock(handle->mutex);
1408 
1409  if (handle->done != 2) {
1410  if (handle->status == SWITCH_STATUS_SUCCESS && handle->bleg) {
1412 
1413  switch_channel_set_variable(channel, "group_dial_status", "loser");
1416  }
1417  }
1418 
1419  return NULL;
1420 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
_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:285
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_caller_profile_t * caller_profile_override
#define switch_channel_set_variable(_channel, _var, _val)
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)
Make an outgoing call.
static void inherit_codec ( switch_channel_t caller_channel,
switch_core_session_t session 
)
static

Definition at line 384 of file switch_ivr_originate.c.

References ep, 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().

385 {
386  const char *var = switch_channel_get_variable(caller_channel, "inherit_codec");
388 
389  if (!zstr(var) && !strcasecmp(var, "passthru")) {
390  switch_channel_set_variable(caller_channel, "absolute_codec_string", switch_channel_get_variable(channel, "ep_codec_string"));
391  } else if (switch_true(var)) {
392  switch_codec_implementation_t impl = { 0 };
393  switch_codec_implementation_t video_impl = { 0 };
394  char tmp[128] = "";
395 
397  const char *ep = switch_channel_get_variable(caller_channel, "ep_codec_string");
398 
399  if (switch_core_session_get_video_read_impl(session, &video_impl) == SWITCH_STATUS_SUCCESS) {
400  switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui,%s",
401  impl.iananame, impl.samples_per_second, (uint32_t)impl.microseconds_per_packet / 1000,
402  video_impl.iananame);
403  } else {
404  switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui",
405  impl.iananame, impl.samples_per_second, (uint32_t)impl.microseconds_per_packet / 1000);
406  }
407 
408  if (ep && switch_stristr(impl.iananame, ep)) {
409  switch_channel_set_variable(caller_channel, "absolute_codec_string", tmp);
410  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "Setting codec string on %s to %s\n",
411  switch_channel_get_name(caller_channel), tmp);
412  } else {
413  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "Codec string %s not supported on %s, skipping inheritance\n",
414  tmp, switch_channel_get_name(caller_channel));
415  }
416  } else {
418  "Error inheriting codec. Channel %s has no read codec yet.\n",
419  switch_channel_get_name(channel));
420  }
421 
422  }
423 }
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
#define zstr(x)
Definition: switch_utils.h:281
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)
static const char * ep
Definition: switch_json.c:36
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)
static void launch_collect_thread ( struct key_collect collect)
static

Definition at line 246 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().

247 {
249  switch_threadattr_t *thd_attr = NULL;
250 
252  switch_threadattr_detach_set(thd_attr, 1);
254  switch_thread_create(&thread, thd_attr, collect_thread_run, collect, switch_core_session_get_pool(collect->session));
255 }
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
static switch_thread_t * thread
Definition: switch_log.c:279
switch_status_t switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on)
Definition: switch_apr.c:655
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void *obj)
struct apr_thread_t switch_thread_t
Definition: switch_apr.h:941
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:642
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:675
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
static switch_bool_t monitor_callback ( switch_core_session_t session,
const char *  app,
const char *  data 
)
static

Definition at line 336 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().

337 {
338  if (app) {
340  if (!strcmp(app, "fail")) {
341  const char *bd = switch_channel_get_variable(channel, "monitor_fail_dispo");
342  if (!bd) {
343  bd = "monitor_early_media_fail";
344  }
345  switch_channel_set_variable(channel, "DIALSTATUS", "BUSY");
346  switch_channel_set_variable(channel, "originate_disposition", bd);
348  } else if (!strcmp(app, "ring")) {
349  originate_global_t *oglobals = (originate_global_t *) switch_channel_get_private(channel, "_oglobals_");
350  const char *bd = switch_channel_get_variable(channel, "monitor_ring_dispo");
351  if (!bd) {
352  bd = "monitor_early_media_ring";
353  }
354  switch_channel_set_variable(channel, "originate_disposition", bd);
355  switch_channel_set_variable(channel, "DIALSTATUS", "EARLY");
356 
357  if (oglobals) {
361  return SWITCH_TRUE;
362  }
363 
364  switch_channel_set_private(channel, "_oglobals_", NULL);
365 
366  if (!oglobals->progress) {
367  oglobals->progress = 1;
368  }
369 
370  if (!oglobals->ring_ready && !oglobals->ignore_ring_ready) {
371  oglobals->ring_ready = 1;
372  }
373 
374  if (!oglobals->ignore_early_media && !oglobals->early_ok) {
375  oglobals->early_ok = 1;
376  }
377  }
378  }
379  }
380 
381  return SWITCH_FALSE;
382 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it'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)
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.

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:908
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:801
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, 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.
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 1201 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().

1203 {
1205  switch_channel_t *caller_channel = switch_core_session_get_channel(oglobals->session);
1206  switch_codec_t *read_codec = NULL;
1207  char *tmp_data = NULL;
1208 
1209  if (!switch_channel_test_flag(caller_channel, CF_ANSWERED)
1210  && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
1211  if (oglobals->bridge_early_media > -1 && len == 1 && originate_status[0].peer_session &&
1212  switch_channel_media_ready(originate_status[0].peer_channel)) {
1213  inherit_codec(caller_channel, originate_status[0].peer_session);
1214  }
1215  if ((status = switch_channel_pre_answer(caller_channel)) != SWITCH_STATUS_SUCCESS) {
1216  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n",
1217  switch_channel_get_name(caller_channel));
1219  }
1220  }
1221 
1222  if (oglobals->session && (read_codec = switch_core_session_get_read_codec(oglobals->session))) {
1224  if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) {
1225  ringback->asis++;
1226  }
1227  } else if (oglobals->bridge_early_media > -1 && zstr(ringback_data) && len == 1 && originate_status[0].peer_session) {
1228  switch_codec_implementation_t read_impl = { 0 }, write_impl = { 0 };
1229 
1230  if (switch_channel_ready(originate_status[0].peer_channel)
1231  && switch_core_session_get_read_impl(originate_status[0].peer_session, &read_impl) == SWITCH_STATUS_SUCCESS
1232  && switch_core_session_get_write_impl(oglobals->session, &write_impl) == SWITCH_STATUS_SUCCESS) {
1233  if (read_impl.impl_id == write_impl.impl_id &&
1234  read_impl.microseconds_per_packet == write_impl.microseconds_per_packet &&
1235  read_impl.actual_samples_per_second == write_impl.actual_samples_per_second) {
1236  ringback->asis++;
1237  write_frame->codec = switch_core_session_get_write_codec(originate_status[0].peer_session);
1238  write_frame->datalen = write_frame->codec->implementation->decoded_bytes_per_packet;
1239  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "bridge_early_media: passthrough enabled\n");
1240  } else {
1241  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",
1242  read_impl.iananame, read_impl.actual_samples_per_second, read_impl.microseconds_per_packet / 1000,
1243  write_impl.iananame, write_impl.actual_samples_per_second, write_impl.microseconds_per_packet / 1000);
1244  }
1245  }
1246  }
1247 
1248  if (!ringback->asis) {
1249  switch_codec_implementation_t peer_read_impl = { 0 };
1250 
1252  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_WARNING, "%s Ringback not supported in passthrough codec mode.\n",
1253  switch_channel_get_name(caller_channel));
1255  }
1256 
1257  if (oglobals->bridge_early_media > -1 && zstr(ringback_data) && len == 1 && originate_status[0].peer_session) {
1258  switch_core_session_get_read_impl(originate_status[0].peer_session, &peer_read_impl);
1259  } else {
1260  switch_core_session_get_read_impl(oglobals->session, &peer_read_impl);
1261  }
1262 
1263  if (switch_core_codec_init(write_codec,
1264  "L16",
1265  NULL,
1266  NULL,
1267  peer_read_impl.actual_samples_per_second,
1268  peer_read_impl.microseconds_per_packet / 1000,
1271 
1272 
1274  "Raw Codec Activation Success L16@%uhz %d channel %dms\n",
1275  peer_read_impl.actual_samples_per_second, peer_read_impl.number_of_channels, peer_read_impl.microseconds_per_packet / 1000);
1276  write_frame->codec = write_codec;
1277  write_frame->datalen = peer_read_impl.decoded_bytes_per_packet;
1278  write_frame->samples = write_frame->datalen / 2;
1279  memset(write_frame->data, 255, write_frame->datalen);
1280  switch_core_session_set_read_codec(oglobals->session, write_codec);
1281  } else {
1282  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_ERROR, "Codec Error!\n");
1284  read_codec = NULL;
1286  }
1287  }
1288 
1289  oglobals->gen_ringback = 1;
1290 
1291  if (zstr(ringback_data)) {
1293  }
1294 
1296  char *ext;
1297 
1298  if (ringback->asis) {
1299  write_frame->codec = read_codec;
1300  ext = read_codec->implementation->iananame;
1301  tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
1302  ringback_data = tmp_data;
1303  }
1304 
1305  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
1306 
1307  if (switch_test_flag((&ringback->fhb), SWITCH_FILE_OPEN)) {
1308  switch_core_file_close(&ringback->fhb);
1309  }
1310 
1311 
1312  ringback->fhb.channels = read_codec->implementation->number_of_channels;
1313  ringback->fhb.samplerate = read_codec->implementation->actual_samples_per_second;
1314  if (switch_core_file_open(&ringback->fhb,
1315  ringback_data,
1316  read_codec->implementation->number_of_channels,
1319  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_ERROR, "Error Playing File\n");
1320  switch_safe_free(tmp_data);
1322  //switch_goto_status(SWITCH_STATUS_FALSE, end);
1323  }
1324  ringback->fh = &ringback->fhb;
1325 
1326  } else if (!strncasecmp(ringback_data, "silence", 7)) {
1327  const char *c = ringback_data + 7;
1328  if (*c == ':') {
1329  c++;
1330  if (c) {
1331  ringback->silence = atoi(c);
1332  }
1333  }
1335  } else {
1336  switch_buffer_create_dynamic(&ringback->audio_buffer, 512, 1024, 0);
1337  switch_buffer_set_loops(ringback->audio_buffer, -1);
1338 
1339  teletone_init_session(&ringback->ts, 0, teletone_handler, ringback);
1340  ringback->ts.rate = read_codec->implementation->actual_samples_per_second;
1341  ringback->channels = read_codec->implementation->number_of_channels;
1342  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
1343  /* ringback->ts.debug = 1;
1344  ringback->ts.debug_stream = switch_core_get_console(); */
1345 
1346  if (teletone_run(&ringback->ts, ringback_data)) {
1347  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_ERROR, "Error Playing Tone\n");
1348  teletone_destroy_session(&ringback->ts);
1349  switch_buffer_destroy(&ringback->audio_buffer);
1351  }
1352  }
1353  }
1354 
1355  end:
1356 
1357  switch_safe_free(tmp_data);
1358 
1359  return status;
1360 
1361 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it'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:1865
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:124
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:45
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:281
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:57
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:789
#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:1602
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:256
switch_buffer_t * audio_buffer
static switch_bool_t switch_is_file_path(const char *file)
uint32_t samples
Definition: switch_frame.h:61
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
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)
static int teletone_handler ( teletone_generation_session_t ts,
teletone_tone_map_t map 
)
static

Definition at line 826 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().

827 {
828  ringback_t *tto = ts->user_data;
829  int wrote;
830  void *buf;
831  int buflen;
832 
833  if (!tto) {
834  return -1;
835  }
836  wrote = teletone_mux_tones(ts, map);
837 
838  if (tto->channels != 1) {
839  if (tto->mux_buflen < wrote * 2 * tto->channels) {
840  tto->mux_buflen = wrote * 2 * tto->channels;
841  tto->mux_buf = realloc(tto->mux_buf, tto->mux_buflen);
842  }
843  memcpy(tto->mux_buf, ts->buffer, wrote * 2);
844  switch_mux_channels((int16_t *) tto->mux_buf, wrote, 1, tto->channels);
845  buf = tto->mux_buf;
846  buflen = wrote * 2 * tto->channels;
847  } else {
848  buf = ts->buffer;
849  buflen = wrote * 2;
850  }
851 
852  switch_buffer_write(tto->audio_buffer, buf, buflen);
853 
854  return 0;
855 }
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
static void wait_for_cause ( switch_channel_t channel)
static

Definition at line 1889 of file switch_ivr_originate.c.

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

Referenced by switch_ivr_originate().

1890 {
1891  int sanity = 5;
1892 
1893  while (--sanity > 0 && peer_eligible(channel) && switch_channel_get_cause(channel) == SWITCH_CAUSE_NONE) {
1894  switch_yield(10000);
1895  }
1896 }
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
#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

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.