Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Enumerations | Functions | Variables
app_dial.c File Reference

dial() & retrydial() - Trivial application to dial a channel and send an URL on answer More...

#include "asterisk.h"
#include <sys/time.h>
#include <signal.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/say.h"
#include "asterisk/config.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/callerid.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/causes.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/manager.h"
#include "asterisk/privacy.h"
#include "asterisk/stringfields.h"
#include "asterisk/dsp.h"
#include "asterisk/aoc.h"
#include "asterisk/ccss.h"
#include "asterisk/indications.h"
#include "asterisk/framehook.h"
#include "asterisk/dial.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/bridge_after.h"
#include "asterisk/features_config.h"
#include "asterisk/max_forwards.h"
#include "asterisk/stream.h"
Include dependency graph for app_dial.c:

Go to the source code of this file.

Data Structures

struct  cause_args
 
struct  chanlist
 List of channel drivers. More...
 
struct  dial_head
 
struct  privacy_args
 

Macros

#define AST_MAX_WATCHERS   256
 
#define CAN_EARLY_BRIDGE(flags, chan, peer)
 
#define DIAL_CALLERID_ABSENT   (1LLU << 33) /* TRUE if caller id is not available for connected line. */
 
#define DIAL_NOFORWARDHTML   (1LLU << 32)
 
#define DIAL_STILLGOING   (1LLU << 31)
 
#define OPT_CALLEE_GO_ON   (1LLU << 36)
 
#define OPT_CALLER_ANSWER   (1LLU << 40)
 
#define OPT_CANCEL_ELSEWHERE   (1LLU << 34)
 
#define OPT_CANCEL_TIMEOUT   (1LLU << 37)
 
#define OPT_FORCE_CID_PRES   (1LLU << 39)
 
#define OPT_FORCE_CID_TAG   (1LLU << 38)
 
#define OPT_HANGUPCAUSE   (1LLU << 44)
 
#define OPT_PEER_H   (1LLU << 35)
 
#define OPT_PREDIAL_CALLEE   (1LLU << 41)
 
#define OPT_PREDIAL_CALLER   (1LLU << 42)
 
#define OPT_RING_WITH_EARLY_MEDIA   (1LLU << 43)
 

Enumerations

enum  {
  OPT_ANNOUNCE = (1 << 0), OPT_RESETCDR = (1 << 1), OPT_DTMF_EXIT = (1 << 2), OPT_SENDDTMF = (1 << 3),
  OPT_FORCECLID = (1 << 4), OPT_GO_ON = (1 << 5), OPT_CALLEE_HANGUP = (1 << 6), OPT_CALLER_HANGUP = (1 << 7),
  OPT_ORIGINAL_CLID = (1 << 8), OPT_DURATION_LIMIT = (1 << 9), OPT_MUSICBACK = (1 << 10), OPT_CALLEE_MACRO = (1 << 11),
  OPT_SCREEN_NOINTRO = (1 << 12), OPT_SCREEN_NOCALLERID = (1 << 13), OPT_IGNORE_CONNECTEDLINE = (1 << 14), OPT_SCREENING = (1 << 15),
  OPT_PRIVACY = (1 << 16), OPT_RINGBACK = (1 << 17), OPT_DURATION_STOP = (1 << 18), OPT_CALLEE_TRANSFER = (1 << 19),
  OPT_CALLER_TRANSFER = (1 << 20), OPT_CALLEE_MONITOR = (1 << 21), OPT_CALLER_MONITOR = (1 << 22), OPT_GOTO = (1 << 23),
  OPT_OPERMODE = (1 << 24), OPT_CALLEE_PARK = (1 << 25), OPT_CALLER_PARK = (1 << 26), OPT_IGNORE_FORWARDING = (1 << 27),
  OPT_CALLEE_GOSUB = (1 << 28), OPT_CALLEE_MIXMONITOR = (1 << 29), OPT_CALLER_MIXMONITOR = (1 << 30)
}
 
enum  {
  OPT_ARG_ANNOUNCE = 0, OPT_ARG_SENDDTMF, OPT_ARG_GOTO, OPT_ARG_DURATION_LIMIT,
  OPT_ARG_MUSICBACK, OPT_ARG_CALLEE_MACRO, OPT_ARG_RINGBACK, OPT_ARG_CALLEE_GOSUB,
  OPT_ARG_CALLEE_GO_ON, OPT_ARG_PRIVACY, OPT_ARG_DURATION_STOP, OPT_ARG_OPERMODE,
  OPT_ARG_SCREEN_NOINTRO, OPT_ARG_ORIGINAL_CLID, OPT_ARG_FORCECLID, OPT_ARG_FORCE_CID_TAG,
  OPT_ARG_FORCE_CID_PRES, OPT_ARG_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLER, OPT_ARG_HANGUPCAUSE,
  OPT_ARG_ARRAY_SIZE
}
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void chanlist_free (struct chanlist *outgoing)
 
static int detect_disconnect (struct ast_channel *chan, char code, struct ast_str **featurecode)
 
static int dial_exec (struct ast_channel *chan, const char *data)
 
static int dial_exec_full (struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
 
static int dial_handle_playtones (struct ast_channel *chan, const char *data)
 
static void do_forward (struct chanlist *o, struct cause_args *num, struct ast_flags64 *peerflags, int single, int caller_entertained, int *to, struct ast_party_id *forced_clid, struct ast_party_id *stored_clid)
 
static void end_bridge_callback (void *data)
 
static void end_bridge_callback_data_fixup (struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
 
static const char * get_cid_name (char *name, int namelen, struct ast_channel *chan)
 
static void handle_cause (int cause, struct cause_args *num)
 
static void hanguptree (struct dial_head *out_chans, struct ast_channel *exception, int hangupcause)
 
static int load_module (void)
 
static int onedigit_goto (struct ast_channel *chan, const char *context, char exten, int pri)
 
static void publish_dial_end_event (struct ast_channel *in, struct dial_head *out_chans, struct ast_channel *exception, const char *status)
 
static int retrydial_exec (struct ast_channel *chan, const char *data)
 
static void set_duration_var (struct ast_channel *chan, const char *var_base, int64_t duration)
 
static void setup_peer_after_bridge_goto (struct ast_channel *chan, struct ast_channel *peer, struct ast_flags64 *opts, char *opt_args[])
 
static int setup_privacy_args (struct privacy_args *pa, struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
 returns 1 if successful, 0 or <0 if the caller should 'goto out' More...
 
static int unload_module (void)
 
static void update_connected_line_from_peer (struct ast_channel *chan, struct ast_channel *peer, int is_caller)
 
static int valid_priv_reply (struct ast_flags64 *opts, int res)
 
static struct ast_channelwait_for_answer (struct ast_channel *in, struct dial_head *out_chans, int *to, struct ast_flags64 *peerflags, char *opt_args[], struct privacy_args *pa, const struct cause_args *num_in, int *result, char *dtmf_progress, char *mf_progress, const int ignore_cc, struct ast_party_id *forced_clid, struct ast_party_id *stored_clid, struct ast_bridge_config *config)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Dialing Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "ccss", }
 
static const char app [] = "Dial"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const struct ast_app_option dial_exec_options [128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'a' ] = { .flag = (1LLU << 40) }, [ 'b' ] = { .flag = (1LLU << 41) , .arg_index = OPT_ARG_PREDIAL_CALLEE + 1 }, [ 'B' ] = { .flag = (1LLU << 42) , .arg_index = OPT_ARG_PREDIAL_CALLER + 1 }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'c' ] = { .flag = (1LLU << 34) }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'e' ] = { .flag = (1LLU << 35) }, [ 'f' ] = { .flag = OPT_FORCECLID , .arg_index = OPT_ARG_FORCECLID + 1 }, [ 'F' ] = { .flag = (1LLU << 36) , .arg_index = OPT_ARG_CALLEE_GO_ON + 1 }, [ 'g' ] = { .flag = OPT_GO_ON }, [ 'G' ] = { .flag = OPT_GOTO , .arg_index = OPT_ARG_GOTO + 1 }, [ 'h' ] = { .flag = OPT_CALLEE_HANGUP }, [ 'H' ] = { .flag = OPT_CALLER_HANGUP }, [ 'i' ] = { .flag = OPT_IGNORE_FORWARDING }, [ 'I' ] = { .flag = OPT_IGNORE_CONNECTEDLINE }, [ 'k' ] = { .flag = OPT_CALLEE_PARK }, [ 'K' ] = { .flag = OPT_CALLER_PARK }, [ 'L' ] = { .flag = OPT_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, [ 'm' ] = { .flag = OPT_MUSICBACK , .arg_index = OPT_ARG_MUSICBACK + 1 }, [ 'M' ] = { .flag = OPT_CALLEE_MACRO , .arg_index = OPT_ARG_CALLEE_MACRO + 1 }, [ 'n' ] = { .flag = OPT_SCREEN_NOINTRO , .arg_index = OPT_ARG_SCREEN_NOINTRO + 1 }, [ 'N' ] = { .flag = OPT_SCREEN_NOCALLERID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID , .arg_index = OPT_ARG_ORIGINAL_CLID + 1 }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'Q' ] = { .flag = (1LLU << 44) , .arg_index = OPT_ARG_HANGUPCAUSE + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK , .arg_index = OPT_ARG_RINGBACK + 1 }, [ 'R' ] = { .flag = (1LLU << 43) }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 's' ] = { .flag = (1LLU << 38) , .arg_index = OPT_ARG_FORCE_CID_TAG + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'u' ] = { .flag = (1LLU << 39) , .arg_index = OPT_ARG_FORCE_CID_PRES + 1 }, [ 'U' ] = { .flag = OPT_CALLEE_GOSUB , .arg_index = OPT_ARG_CALLEE_GOSUB + 1 }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR }, [ 'x' ] = { .flag = OPT_CALLEE_MIXMONITOR }, [ 'X' ] = { .flag = OPT_CALLER_MIXMONITOR }, [ 'z' ] = { .flag = (1LLU << 37) }, }
 
static const char rapp [] = "RetryDial"
 

Detailed Description

dial() & retrydial() - Trivial application to dial a channel and send an URL on answer

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file app_dial.c.

Macro Definition Documentation

◆ AST_MAX_WATCHERS

#define AST_MAX_WATCHERS   256

Definition at line 847 of file app_dial.c.

Referenced by wait_for_answer().

◆ CAN_EARLY_BRIDGE

#define CAN_EARLY_BRIDGE (   flags,
  chan,
  peer 
)

Definition at line 786 of file app_dial.c.

Referenced by dial_exec_full(), do_forward(), and wait_for_answer().

◆ DIAL_CALLERID_ABSENT

#define DIAL_CALLERID_ABSENT   (1LLU << 33) /* TRUE if caller id is not available for connected line. */

Definition at line 703 of file app_dial.c.

Referenced by dial_exec_full(), do_forward(), and wait_for_answer().

◆ DIAL_NOFORWARDHTML

#define DIAL_NOFORWARDHTML   (1LLU << 32)

Definition at line 702 of file app_dial.c.

Referenced by dial_exec_full(), and wait_for_answer().

◆ DIAL_STILLGOING

#define DIAL_STILLGOING   (1LLU << 31)

Definition at line 701 of file app_dial.c.

Referenced by dial_exec_full(), do_forward(), and wait_for_answer().

◆ OPT_CALLEE_GO_ON

#define OPT_CALLEE_GO_ON   (1LLU << 36)

Definition at line 706 of file app_dial.c.

Referenced by setup_peer_after_bridge_goto().

◆ OPT_CALLER_ANSWER

#define OPT_CALLER_ANSWER   (1LLU << 40)

Definition at line 710 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_CANCEL_ELSEWHERE

#define OPT_CANCEL_ELSEWHERE   (1LLU << 34)

Definition at line 704 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_CANCEL_TIMEOUT

#define OPT_CANCEL_TIMEOUT   (1LLU << 37)

Definition at line 707 of file app_dial.c.

Referenced by dial_exec_full(), and do_forward().

◆ OPT_FORCE_CID_PRES

#define OPT_FORCE_CID_PRES   (1LLU << 39)

Definition at line 709 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_FORCE_CID_TAG

#define OPT_FORCE_CID_TAG   (1LLU << 38)

Definition at line 708 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_HANGUPCAUSE

#define OPT_HANGUPCAUSE   (1LLU << 44)

Definition at line 714 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_PEER_H

#define OPT_PEER_H   (1LLU << 35)

Definition at line 705 of file app_dial.c.

Referenced by setup_peer_after_bridge_goto().

◆ OPT_PREDIAL_CALLEE

#define OPT_PREDIAL_CALLEE   (1LLU << 41)

Definition at line 711 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_PREDIAL_CALLER

#define OPT_PREDIAL_CALLER   (1LLU << 42)

Definition at line 712 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_RING_WITH_EARLY_MEDIA

#define OPT_RING_WITH_EARLY_MEDIA   (1LLU << 43)

Definition at line 713 of file app_dial.c.

Referenced by dial_exec_full(), and valid_priv_reply().

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
OPT_ANNOUNCE 
OPT_RESETCDR 
OPT_DTMF_EXIT 
OPT_SENDDTMF 
OPT_FORCECLID 
OPT_GO_ON 
OPT_CALLEE_HANGUP 
OPT_CALLER_HANGUP 
OPT_ORIGINAL_CLID 
OPT_DURATION_LIMIT 
OPT_MUSICBACK 
OPT_CALLEE_MACRO 
OPT_SCREEN_NOINTRO 
OPT_SCREEN_NOCALLERID 
OPT_IGNORE_CONNECTEDLINE 
OPT_SCREENING 
OPT_PRIVACY 
OPT_RINGBACK 
OPT_DURATION_STOP 
OPT_CALLEE_TRANSFER 
OPT_CALLER_TRANSFER 
OPT_CALLEE_MONITOR 
OPT_CALLER_MONITOR 
OPT_GOTO 
OPT_OPERMODE 
OPT_CALLEE_PARK 
OPT_CALLER_PARK 
OPT_IGNORE_FORWARDING 
OPT_CALLEE_GOSUB 
OPT_CALLEE_MIXMONITOR 
OPT_CALLER_MIXMONITOR 

Definition at line 666 of file app_dial.c.

666  {
667  OPT_ANNOUNCE = (1 << 0),
668  OPT_RESETCDR = (1 << 1),
669  OPT_DTMF_EXIT = (1 << 2),
670  OPT_SENDDTMF = (1 << 3),
671  OPT_FORCECLID = (1 << 4),
672  OPT_GO_ON = (1 << 5),
673  OPT_CALLEE_HANGUP = (1 << 6),
674  OPT_CALLER_HANGUP = (1 << 7),
675  OPT_ORIGINAL_CLID = (1 << 8),
676  OPT_DURATION_LIMIT = (1 << 9),
677  OPT_MUSICBACK = (1 << 10),
678  OPT_CALLEE_MACRO = (1 << 11),
679  OPT_SCREEN_NOINTRO = (1 << 12),
680  OPT_SCREEN_NOCALLERID = (1 << 13),
681  OPT_IGNORE_CONNECTEDLINE = (1 << 14),
682  OPT_SCREENING = (1 << 15),
683  OPT_PRIVACY = (1 << 16),
684  OPT_RINGBACK = (1 << 17),
685  OPT_DURATION_STOP = (1 << 18),
686  OPT_CALLEE_TRANSFER = (1 << 19),
687  OPT_CALLER_TRANSFER = (1 << 20),
688  OPT_CALLEE_MONITOR = (1 << 21),
689  OPT_CALLER_MONITOR = (1 << 22),
690  OPT_GOTO = (1 << 23),
691  OPT_OPERMODE = (1 << 24),
692  OPT_CALLEE_PARK = (1 << 25),
693  OPT_CALLER_PARK = (1 << 26),
694  OPT_IGNORE_FORWARDING = (1 << 27),
695  OPT_CALLEE_GOSUB = (1 << 28),
696  OPT_CALLEE_MIXMONITOR = (1 << 29),
697  OPT_CALLER_MIXMONITOR = (1 << 30),
698 };

◆ anonymous enum

anonymous enum
Enumerator
OPT_ARG_ANNOUNCE 
OPT_ARG_SENDDTMF 
OPT_ARG_GOTO 
OPT_ARG_DURATION_LIMIT 
OPT_ARG_MUSICBACK 
OPT_ARG_CALLEE_MACRO 
OPT_ARG_RINGBACK 
OPT_ARG_CALLEE_GOSUB 
OPT_ARG_CALLEE_GO_ON 
OPT_ARG_PRIVACY 
OPT_ARG_DURATION_STOP 
OPT_ARG_OPERMODE 
OPT_ARG_SCREEN_NOINTRO 
OPT_ARG_ORIGINAL_CLID 
OPT_ARG_FORCECLID 
OPT_ARG_FORCE_CID_TAG 
OPT_ARG_FORCE_CID_PRES 
OPT_ARG_PREDIAL_CALLEE 
OPT_ARG_PREDIAL_CALLER 
OPT_ARG_HANGUPCAUSE 
OPT_ARG_ARRAY_SIZE 

Definition at line 716 of file app_dial.c.

716  {
717  OPT_ARG_ANNOUNCE = 0,
719  OPT_ARG_GOTO,
737  /* note: this entry _MUST_ be the last one in the enum */
739 };

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 3567 of file app_dial.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3567 of file app_dial.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 3567 of file app_dial.c.

◆ chanlist_free()

static void chanlist_free ( struct chanlist outgoing)
static

Definition at line 821 of file app_dial.c.

References chanlist::aoc_s_rate_list, ast_aoc_destroy_decoded(), ast_free, ast_party_connected_line_free(), chanlist::connected, and chanlist::orig_chan_name.

Referenced by dial_exec_full(), and hanguptree().

822 {
825  ast_free(outgoing->orig_chan_name);
826  ast_free(outgoing);
827 }
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2072
struct ast_party_connected_line connected
Definition: app_dial.c:809
#define ast_free(a)
Definition: astmm.h:182
struct ast_aoc_decoded * aoc_s_rate_list
Definition: app_dial.c:812
char * orig_chan_name
Definition: app_dial.c:806

◆ detect_disconnect()

static int detect_disconnect ( struct ast_channel chan,
char  code,
struct ast_str **  featurecode 
)
static

Definition at line 1898 of file app_dial.c.

References AST_FEATURE_MAX_LEN, ast_get_builtin_feature(), ast_str_append(), ast_str_buffer(), ast_str_reset(), and ast_str_strlen().

Referenced by wait_for_answer().

1899 {
1900  char disconnect_code[AST_FEATURE_MAX_LEN];
1901  int res;
1902 
1903  ast_str_append(featurecode, 1, "%c", code);
1904 
1905  res = ast_get_builtin_feature(chan, "disconnect", disconnect_code, sizeof(disconnect_code));
1906  if (res) {
1907  ast_str_reset(*featurecode);
1908  return 0;
1909  }
1910 
1911  if (strlen(disconnect_code) > ast_str_strlen(*featurecode)) {
1912  /* Could be a partial match, anyway */
1913  if (strncmp(disconnect_code, ast_str_buffer(*featurecode), ast_str_strlen(*featurecode))) {
1914  ast_str_reset(*featurecode);
1915  }
1916  return 0;
1917  }
1918 
1919  if (strcmp(disconnect_code, ast_str_buffer(*featurecode))) {
1920  ast_str_reset(*featurecode);
1921  return 0;
1922  }
1923 
1924  return 1;
1925 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
int ast_get_builtin_feature(struct ast_channel *chan, const char *feature, char *buf, size_t len)
Get the DTMF code for a builtin feature.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define AST_FEATURE_MAX_LEN

◆ dial_exec()

static int dial_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 3425 of file app_dial.c.

References dial_exec_full(), and NULL.

Referenced by load_module().

3426 {
3427  struct ast_flags64 peerflags;
3428 
3429  memset(&peerflags, 0, sizeof(peerflags));
3430 
3431  return dial_exec_full(chan, data, &peerflags, NULL);
3432 }
#define NULL
Definition: resample.c:96
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
Definition: app_dial.c:2254

◆ dial_exec_full()

static int dial_exec_full ( struct ast_channel chan,
const char *  data,
struct ast_flags64 peerflags,
int *  continue_exec 
)
static

< TRUE if force CallerID on call forward only. Legacy behaviour.

Forced CallerID party information to send.

Note
This will not have any malloced strings so do not free it.

Stored CallerID information if needed.

Note
If OPT_ORIGINAL_CLID set then this is the o option CallerID. Otherwise it is the dialplan extension and hint name.
This will not have any malloced strings so do not free it.

CallerID party information to store.

Note
This will not have any malloced strings so do not free it.

Definition at line 2254 of file app_dial.c.

References ast_bridge_config::answer_topology, args, ast_answer(), AST_APP_ARG, ast_app_exec_macro(), ast_app_exec_sub(), ast_app_expand_sub_args(), ast_app_group_set_channel(), ast_app_parse_options64(), ast_asprintf, ast_autoservice_chan_hangup_peer(), ast_autoservice_start(), ast_autoservice_stop(), ast_bridge_call(), ast_bridge_setup_after_goto(), ast_bridge_timelimit(), ast_call(), ast_callerid_parse(), ast_calloc, ast_cause2str(), AST_CAUSE_ANSWERED_ELSEWHERE, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_cc_busy_interface(), ast_cc_call_failed(), ast_cc_call_init(), ast_cc_callback(), ast_cc_extension_monitor_add_dialstring(), ast_cdr_reset(), ast_channel_adsicpe_set(), ast_channel_appl_set(), ast_channel_caller(), ast_channel_clear_flag(), ast_channel_connected(), ast_channel_connected_line_macro(), ast_channel_connected_line_sub(), ast_channel_context(), ast_channel_context_set(), ast_channel_data_set(), ast_channel_datastore_inherit(), ast_channel_dialed(), ast_channel_early_bridge(), ast_channel_exten(), ast_channel_exten_set(), ast_channel_flags(), ast_channel_get_device_name(), ast_channel_get_stream_topology(), ast_channel_hangupcause(), ast_channel_hangupcause_set(), ast_channel_inherit_variables(), ast_channel_language(), ast_channel_lock, ast_channel_lock_both, ast_channel_macrocontext(), ast_channel_macroexten(), ast_channel_make_compatible(), ast_channel_musicclass(), AST_CHANNEL_NAME, ast_channel_name(), ast_channel_priority(), ast_channel_priority_set(), ast_channel_publish_dial(), ast_channel_redirecting(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_BRIDGE_PEER, ast_channel_sched(), ast_channel_sendurl(), ast_channel_set_caller_event(), ast_channel_set_connected_line(), ast_channel_set_flag(), ast_channel_setoption(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_stream(), ast_channel_supports_html(), ast_channel_timingfunc(), ast_channel_transfercapability(), ast_channel_transfercapability_set(), ast_channel_unlock, ast_channel_visible_indication_set(), ast_channel_whentohangup(), ast_channel_whentohangup_set(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, ast_connected_line_copy_from_caller(), AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_copy_flags64, ast_copy_string(), ast_deactivate_generator(), ast_debug, AST_DECLARE_APP_ARGS, AST_DIGIT_ANY, ast_dtmf_stream(), ast_exists_extension(), AST_FEATURE_AUTOMIXMON, AST_FEATURE_AUTOMON, AST_FEATURE_DISCONNECT, AST_FEATURE_PARKCALL, AST_FEATURE_REDIRECT, ast_filedelete(), ast_fileexists(), AST_FLAG_END_DTMF_ONLY, AST_FLAG_OUTGOING, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, ast_free, ast_frfree, ast_hangup(), ast_ignore_cc(), ast_indicate(), ast_indicate_data(), AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK_INIT_VALUE, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, AST_MAX_EXTENSION, ast_max_forwards_decrement(), ast_max_forwards_get(), ast_mf_stream(), ast_moh_start(), ast_moh_stop(), AST_OPTION_OPRMODE, ast_parse_caller_presentation(), ast_parseable_goto(), ast_party_caller_set_init(), ast_party_connected_line_copy(), ast_party_connected_line_set_init(), ast_party_id_init(), ast_party_id_set_init(), ast_party_redirecting_copy(), AST_PBX_INCOMPLETE, ast_pbx_start(), ast_pre_call(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRIVACY_UNKNOWN, ast_read(), ast_replace_subargument_delimiter(), ast_request_with_stream_topology(), ast_rtp_instance_early_bridge_make_compatible(), ast_sched_runq(), ast_sched_wait(), ast_senddigit(), ast_set2_flag64, ast_set_flag, ast_set_flag64, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_str2cause(), ast_str_tmp, ast_strdup, ast_strdupa, ast_stream_topology_clone(), ast_stream_topology_free(), ast_stream_topology_to_str(), ast_streamfile(), ast_strip(), ast_strlen_zero, ast_test_flag64, ast_trace, ast_tvadd(), ast_tvnow(), ast_tvzero(), ast_verb, ast_waitfor_n(), CAN_EARLY_BRIDGE, chanlist::chan, chanlist_free(), chanlist::connected, ast_frame::data, ast_frame::datalen, DIAL_CALLERID_ABSENT, dial_exec_options, dial_handle_playtones(), DIAL_NOFORWARDHTML, DIAL_STILLGOING, digit, done, ast_bridge_config::end_bridge_callback, end_bridge_callback(), ast_bridge_config::end_bridge_callback_data, ast_bridge_config::end_bridge_callback_data_fixup, end_bridge_callback_data_fixup(), ast_bridge_config::end_sound, ast_bridge_config::features_callee, ast_bridge_config::features_caller, ast_flags64::flags, ast_frame::frametype, get_cid_name(), handle_cause(), hanguptree(), ast_party_caller::id, ast_party_connected_line::id, ast_frame_subclass::integer, chanlist::interface, LOG_ERROR, LOG_NOTICE, LOG_WARNING, oprmode::mode, name, ast_party_id::name, NULL, ast_party_id::number, chanlist::number, OPT_ANNOUNCE, OPT_ARG_ANNOUNCE, OPT_ARG_ARRAY_SIZE, OPT_ARG_CALLEE_GOSUB, OPT_ARG_CALLEE_MACRO, OPT_ARG_DURATION_LIMIT, OPT_ARG_DURATION_STOP, OPT_ARG_FORCE_CID_PRES, OPT_ARG_FORCE_CID_TAG, OPT_ARG_FORCECLID, OPT_ARG_GOTO, OPT_ARG_HANGUPCAUSE, OPT_ARG_MUSICBACK, OPT_ARG_OPERMODE, OPT_ARG_ORIGINAL_CLID, OPT_ARG_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLER, OPT_ARG_PRIVACY, OPT_ARG_RINGBACK, OPT_ARG_SCREEN_NOINTRO, OPT_ARG_SENDDTMF, OPT_CALLEE_GOSUB, OPT_CALLEE_HANGUP, OPT_CALLEE_MACRO, OPT_CALLEE_MIXMONITOR, OPT_CALLEE_MONITOR, OPT_CALLEE_PARK, OPT_CALLEE_TRANSFER, OPT_CALLER_ANSWER, OPT_CALLER_HANGUP, OPT_CALLER_MIXMONITOR, OPT_CALLER_MONITOR, OPT_CALLER_PARK, OPT_CALLER_TRANSFER, OPT_CANCEL_ELSEWHERE, OPT_CANCEL_TIMEOUT, OPT_DTMF_EXIT, OPT_DURATION_LIMIT, OPT_DURATION_STOP, OPT_FORCE_CID_PRES, OPT_FORCE_CID_TAG, OPT_FORCECLID, OPT_GO_ON, OPT_GOTO, OPT_HANGUPCAUSE, OPT_IGNORE_CONNECTEDLINE, OPT_IGNORE_FORWARDING, OPT_MUSICBACK, OPT_OPERMODE, OPT_ORIGINAL_CLID, OPT_PREDIAL_CALLEE, OPT_PREDIAL_CALLER, OPT_PRIVACY, OPT_RESETCDR, OPT_RING_WITH_EARLY_MEDIA, OPT_RINGBACK, OPT_SCREEN_NOINTRO, OPT_SCREENING, OPT_SENDDTMF, options, chanlist::orig_chan_name, out, parse(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), oprmode::peer, ast_party_number::presentation, privacy_args::privdb_val, privacy_args::privintro, ast_frame::ptr, result, S_COR, S_OR, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, privacy_args::sentringing, setup_peer_after_bridge_goto(), setup_privacy_args(), ast_bridge_config::start_sound, privacy_args::status, ast_party_name::str, ast_party_number::str, ast_party_subaddress::str, strsep(), chanlist::stuff, ast_party_id::subaddress, ast_frame::subclass, ast_party_id::tag, chanlist::tech, timeout, tmp(), ast_party_dialed::transit_network_select, url, ast_party_name::valid, ast_party_number::valid, wait_for_answer(), and ast_bridge_config::warning_sound.

Referenced by dial_exec(), and retrydial_exec().

2255 {
2256  int res = -1; /* default: error */
2257  char *rest, *cur; /* scan the list of destinations */
2258  struct dial_head out_chans = AST_LIST_HEAD_NOLOCK_INIT_VALUE; /* list of destinations */
2259  struct chanlist *outgoing;
2260  struct chanlist *tmp;
2261  struct ast_channel *peer = NULL;
2262  int to; /* timeout */
2263  struct cause_args num = { chan, 0, 0, 0 };
2264  int cause;
2265 
2266  struct ast_bridge_config config = { { 0, } };
2267  struct timeval calldurationlimit = { 0, };
2268  char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress=NULL;
2269  char *mfcalled = NULL, *mfcalling = NULL, *mf_progress=NULL;
2270  struct privacy_args pa = {
2271  .sentringing = 0,
2272  .privdb_val = 0,
2273  .status = "INVALIDARGS",
2274  };
2275  int sentringing = 0, moh = 0;
2276  const char *outbound_group = NULL;
2277  int result = 0;
2278  char *parse;
2279  int opermode = 0;
2280  int delprivintro = 0;
2282  AST_APP_ARG(peers);
2285  AST_APP_ARG(url);
2286  );
2287  struct ast_flags64 opts = { 0, };
2288  char *opt_args[OPT_ARG_ARRAY_SIZE];
2289  int fulldial = 0, num_dialed = 0;
2290  int ignore_cc = 0;
2291  char device_name[AST_CHANNEL_NAME];
2292  char forced_clid_name[AST_MAX_EXTENSION];
2293  char stored_clid_name[AST_MAX_EXTENSION];
2294  int force_forwards_only; /*!< TRUE if force CallerID on call forward only. Legacy behaviour.*/
2295  /*!
2296  * \brief Forced CallerID party information to send.
2297  * \note This will not have any malloced strings so do not free it.
2298  */
2299  struct ast_party_id forced_clid;
2300  /*!
2301  * \brief Stored CallerID information if needed.
2302  *
2303  * \note If OPT_ORIGINAL_CLID set then this is the o option
2304  * CallerID. Otherwise it is the dialplan extension and hint
2305  * name.
2306  *
2307  * \note This will not have any malloced strings so do not free it.
2308  */
2309  struct ast_party_id stored_clid;
2310  /*!
2311  * \brief CallerID party information to store.
2312  * \note This will not have any malloced strings so do not free it.
2313  */
2314  struct ast_party_caller caller;
2315  int max_forwards;
2316  SCOPE_ENTER(1, "%s: Data: %s\n", ast_channel_name(chan), data);
2317 
2318  /* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
2319  ast_channel_lock(chan);
2321  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
2322  pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
2323  pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
2324  pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
2325  pbx_builtin_setvar_helper(chan, "ANSWEREDTIME_MS", "");
2326  pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
2327  pbx_builtin_setvar_helper(chan, "DIALEDTIME_MS", "");
2328  pbx_builtin_setvar_helper(chan, "RINGTIME", "");
2329  pbx_builtin_setvar_helper(chan, "RINGTIME_MS", "");
2330  pbx_builtin_setvar_helper(chan, "PROGRESSTIME", "");
2331  pbx_builtin_setvar_helper(chan, "PROGRESSTIME_MS", "");
2333  max_forwards = ast_max_forwards_get(chan);
2334  ast_channel_unlock(chan);
2335 
2336  if (max_forwards <= 0) {
2337  ast_log(LOG_WARNING, "Cannot place outbound call from channel '%s'. Max forwards exceeded\n",
2338  ast_channel_name(chan));
2339  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "BUSY");
2340  SCOPE_EXIT_RTN_VALUE(-1, "%s: Max forwards exceeded\n", ast_channel_name(chan));
2341  }
2342 
2343  if (ast_check_hangup_locked(chan)) {
2344  /*
2345  * Caller hung up before we could dial. If dial is executed
2346  * within an AGI then the AGI has likely eaten all queued
2347  * frames before executing the dial in DeadAGI mode. With
2348  * the caller hung up and no pending frames from the caller's
2349  * read queue, dial would not know that the call has hung up
2350  * until a called channel answers. It is rather annoying to
2351  * whoever just answered the non-existent call.
2352  *
2353  * Dial should not continue execution in DeadAGI mode, hangup
2354  * handlers, or the h exten.
2355  */
2356  ast_verb(3, "Caller hung up before dial.\n");
2357  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "CANCEL");
2358  SCOPE_EXIT_RTN_VALUE(-1, "%s: Caller hung up before dial\n", ast_channel_name(chan));
2359  }
2360 
2361  parse = ast_strdupa(data ?: "");
2362 
2363  AST_STANDARD_APP_ARGS(args, parse);
2364 
2365  if (!ast_strlen_zero(args.options) &&
2366  ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
2367  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2368  goto done;
2369  }
2370 
2371  if (ast_cc_call_init(chan, &ignore_cc)) {
2372  goto done;
2373  }
2374 
2376  delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
2377 
2378  if (delprivintro < 0 || delprivintro > 1) {
2379  ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
2380  delprivintro = 0;
2381  }
2382  }
2383 
2384  if (!ast_test_flag64(&opts, OPT_RINGBACK)) {
2385  opt_args[OPT_ARG_RINGBACK] = NULL;
2386  }
2387 
2388  if (ast_test_flag64(&opts, OPT_OPERMODE)) {
2389  opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
2390  ast_verb(3, "Setting operator services mode to %d.\n", opermode);
2391  }
2392 
2394  calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
2395  if (!calldurationlimit.tv_sec) {
2396  ast_log(LOG_WARNING, "Dial does not accept S(%s)\n", opt_args[OPT_ARG_DURATION_STOP]);
2397  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2398  goto done;
2399  }
2400  ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
2401  }
2402 
2403  if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
2404  mf_progress = opt_args[OPT_ARG_SENDDTMF];
2405  dtmfcalling = strsep(&mf_progress, ":");
2406  dtmfcalled = strsep(&mf_progress, ":");
2407  dtmf_progress = strsep(&mf_progress, ":");
2408  mfcalling = strsep(&mf_progress, ":");
2409  mfcalled = strsep(&mf_progress, ":");
2410  }
2411 
2413  if (ast_bridge_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
2414  goto done;
2415  }
2416 
2417  /* Setup the forced CallerID information to send if used. */
2418  ast_party_id_init(&forced_clid);
2419  force_forwards_only = 0;
2420  if (ast_test_flag64(&opts, OPT_FORCECLID)) {
2421  if (ast_strlen_zero(opt_args[OPT_ARG_FORCECLID])) {
2422  ast_channel_lock(chan);
2423  forced_clid.number.str = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
2424  ast_channel_unlock(chan);
2425  forced_clid_name[0] = '\0';
2426  forced_clid.name.str = (char *) get_cid_name(forced_clid_name,
2427  sizeof(forced_clid_name), chan);
2428  force_forwards_only = 1;
2429  } else {
2430  /* Note: The opt_args[OPT_ARG_FORCECLID] string value is altered here. */
2431  ast_callerid_parse(opt_args[OPT_ARG_FORCECLID], &forced_clid.name.str,
2432  &forced_clid.number.str);
2433  }
2434  if (!ast_strlen_zero(forced_clid.name.str)) {
2435  forced_clid.name.valid = 1;
2436  }
2437  if (!ast_strlen_zero(forced_clid.number.str)) {
2438  forced_clid.number.valid = 1;
2439  }
2440  }
2442  && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_TAG])) {
2443  forced_clid.tag = opt_args[OPT_ARG_FORCE_CID_TAG];
2444  }
2445  forced_clid.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
2447  && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_PRES])) {
2448  int pres;
2449 
2450  pres = ast_parse_caller_presentation(opt_args[OPT_ARG_FORCE_CID_PRES]);
2451  if (0 <= pres) {
2452  forced_clid.number.presentation = pres;
2453  }
2454  }
2455 
2456  /* Setup the stored CallerID information if needed. */
2457  ast_party_id_init(&stored_clid);
2458  if (ast_test_flag64(&opts, OPT_ORIGINAL_CLID)) {
2459  if (ast_strlen_zero(opt_args[OPT_ARG_ORIGINAL_CLID])) {
2460  ast_channel_lock(chan);
2461  ast_party_id_set_init(&stored_clid, &ast_channel_caller(chan)->id);
2462  if (!ast_strlen_zero(ast_channel_caller(chan)->id.name.str)) {
2463  stored_clid.name.str = ast_strdupa(ast_channel_caller(chan)->id.name.str);
2464  }
2465  if (!ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
2466  stored_clid.number.str = ast_strdupa(ast_channel_caller(chan)->id.number.str);
2467  }
2468  if (!ast_strlen_zero(ast_channel_caller(chan)->id.subaddress.str)) {
2469  stored_clid.subaddress.str = ast_strdupa(ast_channel_caller(chan)->id.subaddress.str);
2470  }
2471  if (!ast_strlen_zero(ast_channel_caller(chan)->id.tag)) {
2472  stored_clid.tag = ast_strdupa(ast_channel_caller(chan)->id.tag);
2473  }
2474  ast_channel_unlock(chan);
2475  } else {
2476  /* Note: The opt_args[OPT_ARG_ORIGINAL_CLID] string value is altered here. */
2477  ast_callerid_parse(opt_args[OPT_ARG_ORIGINAL_CLID], &stored_clid.name.str,
2478  &stored_clid.number.str);
2479  if (!ast_strlen_zero(stored_clid.name.str)) {
2480  stored_clid.name.valid = 1;
2481  }
2482  if (!ast_strlen_zero(stored_clid.number.str)) {
2483  stored_clid.number.valid = 1;
2484  }
2485  }
2486  } else {
2487  /*
2488  * In case the new channel has no preset CallerID number by the
2489  * channel driver, setup the dialplan extension and hint name.
2490  */
2491  stored_clid_name[0] = '\0';
2492  stored_clid.name.str = (char *) get_cid_name(stored_clid_name,
2493  sizeof(stored_clid_name), chan);
2494  if (ast_strlen_zero(stored_clid.name.str)) {
2495  stored_clid.name.str = NULL;
2496  } else {
2497  stored_clid.name.valid = 1;
2498  }
2499  ast_channel_lock(chan);
2500  stored_clid.number.str = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
2501  stored_clid.number.valid = 1;
2502  ast_channel_unlock(chan);
2503  }
2504 
2505  if (ast_test_flag64(&opts, OPT_RESETCDR)) {
2506  ast_cdr_reset(ast_channel_name(chan), 0);
2507  }
2508  if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
2509  opt_args[OPT_ARG_PRIVACY] = ast_strdupa(ast_channel_exten(chan));
2510 
2511  if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
2512  res = setup_privacy_args(&pa, &opts, opt_args, chan);
2513  if (res <= 0)
2514  goto out;
2515  res = -1; /* reset default */
2516  }
2517 
2518  if (continue_exec)
2519  *continue_exec = 0;
2520 
2521  /* If a channel group has been specified, get it for use when we create peer channels */
2522 
2523  ast_channel_lock(chan);
2524  if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
2525  outbound_group = ast_strdupa(outbound_group);
2526  pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
2527  } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
2528  outbound_group = ast_strdupa(outbound_group);
2529  }
2530  ast_channel_unlock(chan);
2531 
2532  /* Set per dial instance flags. These flags are also passed back to RetryDial. */
2536 
2537  /* PREDIAL: Run gosub on the caller's channel */
2539  && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {
2540  ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLER]);
2541  ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER], 0);
2542  }
2543 
2544  /* loop through the list of dial destinations */
2545  rest = args.peers;
2546  while ((cur = strsep(&rest, "&"))) {
2547  struct ast_channel *tc; /* channel for this destination */
2548  char *number;
2549  char *tech;
2550  size_t tech_len;
2551  size_t number_len;
2552  struct ast_stream_topology *topology;
2553 
2554  cur = ast_strip(cur);
2555  if (ast_strlen_zero(cur)) {
2556  /* No tech/resource in this position. */
2557  continue;
2558  }
2559 
2560  /* Get a technology/resource pair */
2561  number = cur;
2562  tech = strsep(&number, "/");
2563 
2564  num_dialed++;
2565  if (ast_strlen_zero(number)) {
2566  ast_log(LOG_WARNING, "Dial argument takes format (technology/resource)\n");
2567  goto out;
2568  }
2569 
2570  tech_len = strlen(tech) + 1;
2571  number_len = strlen(number) + 1;
2572  tmp = ast_calloc(1, sizeof(*tmp) + (2 * tech_len) + number_len);
2573  if (!tmp) {
2574  goto out;
2575  }
2576 
2577  /* Save tech, number, and interface. */
2578  cur = tmp->stuff;
2579  strcpy(cur, tech);
2580  tmp->tech = cur;
2581  cur += tech_len;
2582  strcpy(cur, tech);
2583  cur[tech_len - 1] = '/';
2584  tmp->interface = cur;
2585  cur += tech_len;
2586  strcpy(cur, number);
2587  tmp->number = cur;
2588 
2589  if (opts.flags) {
2590  /* Set per outgoing call leg options. */
2591  ast_copy_flags64(tmp, &opts,
2601  }
2602 
2603  /* Request the peer */
2604 
2605  ast_channel_lock(chan);
2606  /*
2607  * Seed the chanlist's connected line information with previously
2608  * acquired connected line info from the incoming channel. The
2609  * previously acquired connected line info could have been set
2610  * through the CONNECTED_LINE dialplan function.
2611  */
2613 
2615 
2616  ast_channel_unlock(chan);
2617 
2618  tc = ast_request_with_stream_topology(tmp->tech, topology, NULL, chan, tmp->number, &cause);
2619 
2620  ast_stream_topology_free(topology);
2621 
2622  if (!tc) {
2623  /* If we can't, just go on to the next call */
2624  ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
2625  tmp->tech, cause, ast_cause2str(cause));
2626  handle_cause(cause, &num);
2627  if (!rest) {
2628  /* we are on the last destination */
2629  ast_channel_hangupcause_set(chan, cause);
2630  }
2631  if (!ignore_cc && (cause == AST_CAUSE_BUSY || cause == AST_CAUSE_CONGESTION)) {
2632  if (!ast_cc_callback(chan, tmp->tech, tmp->number, ast_cc_busy_interface)) {
2634  }
2635  }
2636  chanlist_free(tmp);
2637  continue;
2638  }
2639 
2640  ast_channel_get_device_name(tc, device_name, sizeof(device_name));
2641  if (!ignore_cc) {
2642  ast_cc_extension_monitor_add_dialstring(chan, tmp->interface, device_name);
2643  }
2644 
2645  ast_channel_lock_both(tc, chan);
2647 
2648  pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", tmp->number);
2649 
2650  /* Setup outgoing SDP to match incoming one */
2651  if (!AST_LIST_FIRST(&out_chans) && !rest && CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
2652  /* We are on the only destination. */
2654  }
2655 
2656  /* Inherit specially named variables from parent channel */
2660 
2661  ast_channel_appl_set(tc, "AppDial");
2662  ast_channel_data_set(tc, "(Outgoing Line)");
2663 
2664  memset(ast_channel_whentohangup(tc), 0, sizeof(*ast_channel_whentohangup(tc)));
2665 
2666  /* Determine CallerID to store in outgoing channel. */
2668  if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
2669  caller.id = stored_clid;
2670  ast_channel_set_caller_event(tc, &caller, NULL);
2672  } else if (ast_strlen_zero(S_COR(ast_channel_caller(tc)->id.number.valid,
2673  ast_channel_caller(tc)->id.number.str, NULL))) {
2674  /*
2675  * The new channel has no preset CallerID number by the channel
2676  * driver. Use the dialplan extension and hint name.
2677  */
2678  caller.id = stored_clid;
2679  if (!caller.id.name.valid
2680  && !ast_strlen_zero(S_COR(ast_channel_connected(chan)->id.name.valid,
2681  ast_channel_connected(chan)->id.name.str, NULL))) {
2682  /*
2683  * No hint name available. We have a connected name supplied by
2684  * the dialplan we can use instead.
2685  */
2686  caller.id.name.valid = 1;
2687  caller.id.name = ast_channel_connected(chan)->id.name;
2688  }
2689  ast_channel_set_caller_event(tc, &caller, NULL);
2691  } else if (ast_strlen_zero(S_COR(ast_channel_caller(tc)->id.name.valid, ast_channel_caller(tc)->id.name.str,
2692  NULL))) {
2693  /* The new channel has no preset CallerID name by the channel driver. */
2694  if (!ast_strlen_zero(S_COR(ast_channel_connected(chan)->id.name.valid,
2695  ast_channel_connected(chan)->id.name.str, NULL))) {
2696  /*
2697  * We have a connected name supplied by the dialplan we can
2698  * use instead.
2699  */
2700  caller.id.name.valid = 1;
2701  caller.id.name = ast_channel_connected(chan)->id.name;
2702  ast_channel_set_caller_event(tc, &caller, NULL);
2703  }
2704  }
2705 
2706  /* Determine CallerID for outgoing channel to send. */
2707  if (ast_test_flag64(peerflags, OPT_FORCECLID) && !force_forwards_only) {
2709 
2711  connected.id = forced_clid;
2713  } else {
2715  }
2716 
2718 
2720 
2723  ast_channel_musicclass_set(tc, ast_channel_musicclass(chan));
2724  }
2725 
2726  /* Pass ADSI CPE and transfer capability */
2729 
2730  /* If we have an outbound group, set this peer channel to it */
2731  if (outbound_group)
2732  ast_app_group_set_channel(tc, outbound_group);
2733  /* If the calling channel has the ANSWERED_ELSEWHERE flag set, inherit it. This is to support local channels */
2736 
2737  /* Check if we're forced by configuration */
2740 
2741 
2742  /* Inherit context and extension */
2743  ast_channel_dialcontext_set(tc, ast_strlen_zero(ast_channel_macrocontext(chan)) ? ast_channel_context(chan) : ast_channel_macrocontext(chan));
2746  else
2748 
2750 
2751  /* Save the original channel name to detect call pickup masquerading in. */
2753 
2754  ast_channel_unlock(tc);
2755  ast_channel_unlock(chan);
2756 
2757  /* Put channel in the list of outgoing thingies. */
2758  tmp->chan = tc;
2759  AST_LIST_INSERT_TAIL(&out_chans, tmp, node);
2760  }
2761 
2762  if (AST_LIST_EMPTY(&out_chans)) {
2763  ast_verb(3, "No devices or endpoints to dial (technology/resource)\n");
2764  if (continue_exec) {
2765  /* There is no point in having RetryDial try again */
2766  *continue_exec = 1;
2767  }
2768  strcpy(pa.status, "CHANUNAVAIL");
2769  res = 0;
2770  goto out;
2771  }
2772 
2773  /*
2774  * PREDIAL: Run gosub on all of the callee channels
2775  *
2776  * We run the callee predial before ast_call() in case the user
2777  * wishes to do something on the newly created channels before
2778  * the channel does anything important.
2779  *
2780  * Inside the target gosub we will be able to do something with
2781  * the newly created channel name ie: now the calling channel
2782  * can know what channel will be used to call the destination
2783  * ex: now we will know that SIP/abc-123 is calling SIP/def-124
2784  */
2787  && !AST_LIST_EMPTY(&out_chans)) {
2788  const char *predial_callee;
2789 
2790  ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLEE]);
2791  predial_callee = ast_app_expand_sub_args(chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
2792  if (predial_callee) {
2793  ast_autoservice_start(chan);
2794  AST_LIST_TRAVERSE(&out_chans, tmp, node) {
2795  ast_pre_call(tmp->chan, predial_callee);
2796  }
2797  ast_autoservice_stop(chan);
2798  ast_free((char *) predial_callee);
2799  }
2800  }
2801 
2802  /* Start all outgoing calls */
2803  AST_LIST_TRAVERSE_SAFE_BEGIN(&out_chans, tmp, node) {
2804  res = ast_call(tmp->chan, tmp->number, 0); /* Place the call, but don't wait on the answer */
2805  ast_channel_lock(chan);
2806 
2807  /* check the results of ast_call */
2808  if (res) {
2809  /* Again, keep going even if there's an error */
2810  ast_debug(1, "ast call on peer returned %d\n", res);
2811  ast_verb(3, "Couldn't call %s\n", tmp->interface);
2812  if (ast_channel_hangupcause(tmp->chan)) {
2814  }
2815  ast_channel_unlock(chan);
2816  ast_cc_call_failed(chan, tmp->chan, tmp->interface);
2817  ast_hangup(tmp->chan);
2818  tmp->chan = NULL;
2820  chanlist_free(tmp);
2821  continue;
2822  }
2823 
2824  ast_channel_publish_dial(chan, tmp->chan, tmp->number, NULL);
2825  ast_channel_unlock(chan);
2826 
2827  ast_verb(3, "Called %s\n", tmp->interface);
2829 
2830  /* If this line is up, don't try anybody else */
2831  if (ast_channel_state(tmp->chan) == AST_STATE_UP) {
2832  break;
2833  }
2834  }
2836 
2837  if (ast_strlen_zero(args.timeout)) {
2838  to = -1;
2839  } else {
2840  to = atoi(args.timeout);
2841  if (to > 0)
2842  to *= 1000;
2843  else {
2844  ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
2845  to = -1;
2846  }
2847  }
2848 
2849  outgoing = AST_LIST_FIRST(&out_chans);
2850  if (!outgoing) {
2851  strcpy(pa.status, "CHANUNAVAIL");
2852  if (fulldial == num_dialed) {
2853  res = -1;
2854  goto out;
2855  }
2856  } else {
2857  /* Our status will at least be NOANSWER */
2858  strcpy(pa.status, "NOANSWER");
2859  if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
2860  moh = 1;
2861  if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
2862  char *original_moh = ast_strdupa(ast_channel_musicclass(chan));
2863  ast_channel_musicclass_set(chan, opt_args[OPT_ARG_MUSICBACK]);
2864  ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
2865  ast_channel_musicclass_set(chan, original_moh);
2866  } else {
2867  ast_moh_start(chan, NULL, NULL);
2868  }
2870  } else if (ast_test_flag64(outgoing, OPT_RINGBACK) || ast_test_flag64(outgoing, OPT_RING_WITH_EARLY_MEDIA)) {
2871  if (!ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
2872  if (dial_handle_playtones(chan, opt_args[OPT_ARG_RINGBACK])){
2874  sentringing++;
2875  } else {
2877  }
2878  } else {
2880  sentringing++;
2881  }
2882  }
2883  }
2884 
2885  peer = wait_for_answer(chan, &out_chans, &to, peerflags, opt_args, &pa, &num, &result,
2886  dtmf_progress, mf_progress, ignore_cc, &forced_clid, &stored_clid, &config);
2887 
2888  if (!peer) {
2889  if (result) {
2890  res = result;
2891  } else if (to) { /* Musta gotten hung up */
2892  res = -1;
2893  } else { /* Nobody answered, next please? */
2894  res = 0;
2895  }
2896  } else {
2897  const char *number;
2898  const char *name;
2899  int dial_end_raised = 0;
2900  int cause = -1;
2901 
2902  if (ast_test_flag64(&opts, OPT_CALLER_ANSWER)) {
2903  ast_answer(chan);
2904  }
2905 
2906  /* Ah ha! Someone answered within the desired timeframe. Of course after this
2907  we will always return with -1 so that it is hung up properly after the
2908  conversation. */
2909 
2910  if (ast_test_flag64(&opts, OPT_HANGUPCAUSE)
2911  && !ast_strlen_zero(opt_args[OPT_ARG_HANGUPCAUSE])) {
2912  cause = ast_str2cause(opt_args[OPT_ARG_HANGUPCAUSE]);
2913  if (cause <= 0) {
2914  if (!strcasecmp(opt_args[OPT_ARG_HANGUPCAUSE], "NONE")) {
2915  cause = 0;
2916  } else if (sscanf(opt_args[OPT_ARG_HANGUPCAUSE], "%30d", &cause) != 1
2917  || cause < 0) {
2918  ast_log(LOG_WARNING, "Invalid cause given to Dial(...Q(<cause>)): \"%s\"\n",
2919  opt_args[OPT_ARG_HANGUPCAUSE]);
2920  cause = -1;
2921  }
2922  }
2923  }
2924  hanguptree(&out_chans, peer, cause >= 0 ? cause : AST_CAUSE_ANSWERED_ELSEWHERE);
2925 
2926  /* If appropriate, log that we have a destination channel and set the answer time */
2927 
2928  ast_channel_lock(peer);
2929  name = ast_strdupa(ast_channel_name(peer));
2930 
2931  number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
2932  if (ast_strlen_zero(number)) {
2933  number = NULL;
2934  } else {
2935  number = ast_strdupa(number);
2936  }
2937  ast_channel_unlock(peer);
2938 
2939  ast_channel_lock(chan);
2941 
2942  strcpy(pa.status, "ANSWER");
2943  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2944 
2945  pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", name);
2946  pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
2947 
2949  ast_channel_unlock(chan);
2950 
2951  if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
2952  ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
2953  ast_channel_sendurl( peer, args.url );
2954  }
2956  if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
2957  ast_channel_publish_dial(chan, peer, NULL, pa.status);
2958  /* hang up on the callee -- he didn't want to talk anyway! */
2960  res = 0;
2961  goto out;
2962  }
2963  }
2964  if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
2965  res = 0;
2966  } else {
2967  int digit = 0;
2968  struct ast_channel *chans[2];
2969  struct ast_channel *active_chan;
2970  char *calledfile = NULL, *callerfile = NULL;
2971  int calledstream = 0, callerstream = 0;
2972 
2973  chans[0] = chan;
2974  chans[1] = peer;
2975 
2976  /* we need to stream the announcement(s) when the OPT_ARG_ANNOUNCE (-A) is set */
2977  callerfile = opt_args[OPT_ARG_ANNOUNCE];
2978  calledfile = strsep(&callerfile, ":");
2979 
2980  /* stream the file(s) */
2981  if (!ast_strlen_zero(calledfile)) {
2982  res = ast_streamfile(peer, calledfile, ast_channel_language(peer));
2983  if (res) {
2984  res = 0;
2985  ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", calledfile);
2986  } else {
2987  calledstream = 1;
2988  }
2989  }
2990  if (!ast_strlen_zero(callerfile)) {
2991  res = ast_streamfile(chan, callerfile, ast_channel_language(chan));
2992  if (res) {
2993  res = 0;
2994  ast_log(LOG_ERROR, "error streaming file '%s' to caller\n", callerfile);
2995  } else {
2996  callerstream = 1;
2997  }
2998  }
2999 
3000  /* can't use ast_waitstream, because we're streaming two files at once, and can't block
3001  We'll need to handle both channels at once. */
3002 
3004  while (ast_channel_stream(peer) || ast_channel_stream(chan)) {
3005  int mspeer, mschan;
3006 
3007  mspeer = ast_sched_wait(ast_channel_sched(peer));
3008  mschan = ast_sched_wait(ast_channel_sched(chan));
3009 
3010  if (calledstream) {
3011  if (mspeer < 0 && !ast_channel_timingfunc(peer)) {
3012  ast_stopstream(peer);
3013  calledstream = 0;
3014  }
3015  }
3016  if (callerstream) {
3017  if (mschan < 0 && !ast_channel_timingfunc(chan)) {
3018  ast_stopstream(chan);
3019  callerstream = 0;
3020  }
3021  }
3022 
3023  if (!calledstream && !callerstream) {
3024  break;
3025  }
3026 
3027  if (mspeer < 0)
3028  mspeer = 1000;
3029 
3030  if (mschan < 0)
3031  mschan = 1000;
3032 
3033  /* wait for the lowest maximum of the two */
3034  active_chan = ast_waitfor_n(chans, 2, (mspeer > mschan ? &mschan : &mspeer));
3035  if (active_chan) {
3036  struct ast_channel *other_chan;
3037  struct ast_frame *fr = ast_read(active_chan);
3038 
3039  if (!fr) {
3041  res = -1;
3042  goto done;
3043  }
3044  switch (fr->frametype) {
3045  case AST_FRAME_DTMF_END:
3046  digit = fr->subclass.integer;
3047  if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
3048  ast_stopstream(peer);
3049  res = ast_senddigit(chan, digit, 0);
3050  }
3051  break;
3052  case AST_FRAME_CONTROL:
3053  switch (fr->subclass.integer) {
3054  case AST_CONTROL_HANGUP:
3055  ast_frfree(fr);
3057  res = -1;
3058  goto done;
3060  /* Pass COLP update to the other channel. */
3061  if (active_chan == chan) {
3062  other_chan = peer;
3063  } else {
3064  other_chan = chan;
3065  }
3066  if (ast_channel_connected_line_sub(active_chan, other_chan, fr, 1)
3067  && ast_channel_connected_line_macro(active_chan,
3068  other_chan, fr, other_chan == chan, 1)) {
3069  ast_indicate_data(other_chan, fr->subclass.integer,
3070  fr->data.ptr, fr->datalen);
3071  }
3072  break;
3073  default:
3074  break;
3075  }
3076  break;
3077  default:
3078  /* Ignore all others */
3079  break;
3080  }
3081  ast_frfree(fr);
3082  }
3085  }
3087  }
3088 
3089  if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
3090  /* chan and peer are going into the PBX; as such neither are considered
3091  * outgoing channels any longer */
3093 
3094  ast_replace_subargument_delimiter(opt_args[OPT_ARG_GOTO]);
3095  ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
3096  /* peer goes to the same context and extension as chan, so just copy info from chan*/
3097  ast_channel_lock(peer);
3104  ast_channel_unlock(peer);
3105  if (ast_pbx_start(peer)) {
3107  }
3108  if (continue_exec)
3109  *continue_exec = 1;
3110  res = 0;
3111  ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
3112  goto done;
3113  }
3114 
3116  const char *macro_result_peer;
3117  int macro_res;
3118 
3119  /* Set peer->exten and peer->context so that MACRO_EXTEN and MACRO_CONTEXT get set */
3120  ast_channel_lock_both(chan, peer);
3123  ast_channel_unlock(peer);
3124  ast_channel_unlock(chan);
3125  ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
3126  macro_res = ast_app_exec_macro(chan, peer, opt_args[OPT_ARG_CALLEE_MACRO]);
3127 
3128  ast_channel_lock(peer);
3129 
3130  if (!macro_res && (macro_result_peer = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
3131  char *macro_result = ast_strdupa(macro_result_peer);
3132  char *macro_transfer_dest;
3133 
3134  ast_channel_unlock(peer);
3135 
3136  if (!strcasecmp(macro_result, "BUSY")) {
3137  ast_copy_string(pa.status, macro_result, sizeof(pa.status));
3138  ast_set_flag64(peerflags, OPT_GO_ON);
3139  macro_res = -1;
3140  } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
3141  ast_copy_string(pa.status, macro_result, sizeof(pa.status));
3142  ast_set_flag64(peerflags, OPT_GO_ON);
3143  macro_res = -1;
3144  } else if (!strcasecmp(macro_result, "CONTINUE")) {
3145  /* hangup peer and keep chan alive assuming the macro has changed
3146  the context / exten / priority or perhaps
3147  the next priority in the current exten is desired.
3148  */
3149  ast_set_flag64(peerflags, OPT_GO_ON);
3150  macro_res = -1;
3151  } else if (!strcasecmp(macro_result, "ABORT")) {
3152  /* Hangup both ends unless the caller has the g flag */
3153  macro_res = -1;
3154  } else if (!strncasecmp(macro_result, "GOTO:", 5)) {
3155  macro_transfer_dest = macro_result + 5;
3156  macro_res = -1;
3157  /* perform a transfer to a new extension */
3158  if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
3159  ast_replace_subargument_delimiter(macro_transfer_dest);
3160  }
3161  if (!ast_parseable_goto(chan, macro_transfer_dest)) {
3162  ast_set_flag64(peerflags, OPT_GO_ON);
3163  }
3164  }
3165  if (macro_res && !dial_end_raised) {
3166  ast_channel_publish_dial(chan, peer, NULL, macro_result);
3167  dial_end_raised = 1;
3168  }
3169  } else {
3170  ast_channel_unlock(peer);
3171  }
3172  res = macro_res;
3173  }
3174 
3176  const char *gosub_result_peer;
3177  char *gosub_argstart;
3178  char *gosub_args = NULL;
3179  int gosub_res = -1;
3180 
3181  ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
3182  gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
3183  if (gosub_argstart) {
3184  const char *what_is_s = "s";
3185  *gosub_argstart = 0;
3186  if (!ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
3187  ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
3188  what_is_s = "~~s~~";
3189  }
3190  if (ast_asprintf(&gosub_args, "%s,%s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s, gosub_argstart + 1) < 0) {
3191  gosub_args = NULL;
3192  }
3193  *gosub_argstart = ',';
3194  } else {
3195  const char *what_is_s = "s";
3196  if (!ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
3197  ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
3198  what_is_s = "~~s~~";
3199  }
3200  if (ast_asprintf(&gosub_args, "%s,%s,1", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s) < 0) {
3201  gosub_args = NULL;
3202  }
3203  }
3204  if (gosub_args) {
3205  gosub_res = ast_app_exec_sub(chan, peer, gosub_args, 0);
3206  ast_free(gosub_args);
3207  } else {
3208  ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
3209  }
3210 
3211  ast_channel_lock_both(chan, peer);
3212 
3213  if (!gosub_res && (gosub_result_peer = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
3214  char *gosub_transfer_dest;
3215  char *gosub_result = ast_strdupa(gosub_result_peer);
3216  const char *gosub_retval = pbx_builtin_getvar_helper(peer, "GOSUB_RETVAL");
3217 
3218  /* Inherit return value from the peer, so it can be used in the master */
3219  if (gosub_retval) {
3220  pbx_builtin_setvar_helper(chan, "GOSUB_RETVAL", gosub_retval);
3221  }
3222 
3223  ast_channel_unlock(peer);
3224  ast_channel_unlock(chan);
3225 
3226  if (!strcasecmp(gosub_result, "BUSY")) {
3227  ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
3228  ast_set_flag64(peerflags, OPT_GO_ON);
3229  gosub_res = -1;
3230  } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
3231  ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
3232  ast_set_flag64(peerflags, OPT_GO_ON);
3233  gosub_res = -1;
3234  } else if (!strcasecmp(gosub_result, "CONTINUE")) {
3235  /* Hangup peer and continue with the next extension priority. */
3236  ast_set_flag64(peerflags, OPT_GO_ON);
3237  gosub_res = -1;
3238  } else if (!strcasecmp(gosub_result, "ABORT")) {
3239  /* Hangup both ends unless the caller has the g flag */
3240  gosub_res = -1;
3241  } else if (!strncasecmp(gosub_result, "GOTO:", 5)) {
3242  gosub_transfer_dest = gosub_result + 5;
3243  gosub_res = -1;
3244  /* perform a transfer to a new extension */
3245  if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
3246  ast_replace_subargument_delimiter(gosub_transfer_dest);
3247  }
3248  if (!ast_parseable_goto(chan, gosub_transfer_dest)) {
3249  ast_set_flag64(peerflags, OPT_GO_ON);
3250  }
3251  }
3252  if (gosub_res) {
3253  res = gosub_res;
3254  if (!dial_end_raised) {
3255  ast_channel_publish_dial(chan, peer, NULL, gosub_result);
3256  dial_end_raised = 1;
3257  }
3258  }
3259  } else {
3260  ast_channel_unlock(peer);
3261  ast_channel_unlock(chan);
3262  }
3263  }
3264 
3265  if (!res) {
3266 
3267  /* None of the Dial options changed our status; inform
3268  * everyone that this channel answered
3269  */
3270  if (!dial_end_raised) {
3271  ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
3272  dial_end_raised = 1;
3273  }
3274 
3275  if (!ast_tvzero(calldurationlimit)) {
3276  struct timeval whentohangup = ast_tvadd(ast_tvnow(), calldurationlimit);
3277  ast_channel_lock(peer);
3278  ast_channel_whentohangup_set(peer, &whentohangup);
3279  ast_channel_unlock(peer);
3280  }
3281  if (!ast_strlen_zero(mfcalled)) {
3282  ast_verb(3, "Sending MF '%s' to the called party.\n", mfcalled);
3283  res = ast_mf_stream(peer, chan, mfcalled, 50, 55, 120, 65, 0);
3284  }
3285  if (!ast_strlen_zero(mfcalling)) {
3286  ast_verb(3, "Sending MF '%s' to the calling party.\n", mfcalling);
3287  res = ast_mf_stream(chan, peer, mfcalling, 50, 55, 120, 65, 0);
3288  }
3289  if (!ast_strlen_zero(dtmfcalled)) {
3290  ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
3291  res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
3292  }
3293  if (!ast_strlen_zero(dtmfcalling)) {
3294  ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
3295  res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
3296  }
3297  }
3298 
3299  if (res) { /* some error */
3300  if (!ast_check_hangup(chan) && ast_check_hangup(peer)) {
3302  }
3303  setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3304  if (ast_bridge_setup_after_goto(peer)
3305  || ast_pbx_start(peer)) {
3307  }
3308  res = -1;
3309  } else {
3310  if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
3312  if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
3314  if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
3316  if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
3318  if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
3320  if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
3322  if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
3324  if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
3326  if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
3328  if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
3330 
3332  config.end_bridge_callback_data = chan;
3334 
3335  if (moh) {
3336  moh = 0;
3337  ast_moh_stop(chan);
3338  } else if (sentringing) {
3339  sentringing = 0;
3340  ast_indicate(chan, -1);
3341  }
3342  /* Be sure no generators are left on it and reset the visible indication */
3345  /* Make sure channels are compatible */
3346  res = ast_channel_make_compatible(chan, peer);
3347  if (res < 0) {
3348  ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", ast_channel_name(chan), ast_channel_name(peer));
3350  res = -1;
3351  goto done;
3352  }
3353  if (opermode) {
3354  struct oprmode oprmode;
3355 
3356  oprmode.peer = peer;
3357  oprmode.mode = opermode;
3358 
3360  }
3361  setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3362 
3363  res = ast_bridge_call(chan, peer, &config);
3364  }
3365  }
3366 out:
3367  if (moh) {
3368  moh = 0;
3369  ast_moh_stop(chan);
3370  } else if (sentringing) {
3371  sentringing = 0;
3372  ast_indicate(chan, -1);
3373  }
3374 
3375  if (delprivintro && ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3377  if (ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3378  ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
3379  } else {
3380  ast_verb(3, "Successfully deleted %s intro file\n", pa.privintro);
3381  }
3382  }
3383 
3385  /* forward 'answered elsewhere' if we received it */
3386  hanguptree(&out_chans, NULL,
3390  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
3391  ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
3392 
3393  if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
3394  if (!ast_tvzero(calldurationlimit))
3395  memset(ast_channel_whentohangup(chan), 0, sizeof(*ast_channel_whentohangup(chan)));
3396  res = 0;
3397  }
3398 
3399 done:
3400  if (config.answer_topology) {
3401  ast_trace(2, "%s Cleaning up topology: %p %s\n",
3402  peer ? ast_channel_name(peer) : "<no channel>", &config.answer_topology,
3403  ast_str_tmp(256, ast_stream_topology_to_str(config.answer_topology, &STR_TMP)));
3404 
3405  /*
3406  * At this point, the channel driver that answered should have bumped the
3407  * topology refcount for itself. Here we're cleaning up the reference we added
3408  * in wait_for_answer().
3409  */
3411  }
3412  if (config.warning_sound) {
3413  ast_free((char *)config.warning_sound);
3414  }
3415  if (config.end_sound) {
3416  ast_free((char *)config.end_sound);
3417  }
3418  if (config.start_sound) {
3419  ast_free((char *)config.start_sound);
3420  }
3421  ast_ignore_cc(chan);
3422  SCOPE_EXIT_RTN_VALUE(res, "%s: Done\n", ast_channel_name(chan));
3423 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
Definition: main/app.c:981
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
Definition: channel.c:3166
#define OPT_FORCE_CID_PRES
Definition: app_dial.c:709
int sentringing
Definition: app_dial.c:1139
int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
Bridge two channels together (early)
Definition: channel.c:7512
Information needed to identify an endpoint in a call.
Definition: channel.h:339
char digit
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
Definition: test_heap.c:38
int ast_max_forwards_get(struct ast_channel *chan)
Get the current max forwards for a particular channel.
Definition: max_forwards.c:121
#define OPT_RING_WITH_EARLY_MEDIA
Definition: app_dial.c:713
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
char stuff[0]
Definition: app_dial.c:814
char privintro[1024]
Definition: app_dial.c:1142
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame)
Run a connected line interception macro and update a channel&#39;s connected line information.
Definition: channel.c:10435
void ast_channel_visible_indication_set(struct ast_channel *chan, int value)
#define ast_copy_flags64(dest, src, flagz)
Definition: utils.h:141
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
Definition: channel.c:7472
void ast_channel_whentohangup_set(struct ast_channel *chan, struct timeval *value)
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
#define OPT_CANCEL_ELSEWHERE
Definition: app_dial.c:704
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
struct ast_flags features_callee
Definition: channel.h:1079
const char * tech
Definition: app_dial.c:802
char * config
Definition: conf2ael.c:66
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:755
struct ast_stream_topology * answer_topology
Definition: channel.h:1100
struct ast_party_id id
Connected party ID.
Definition: channel.h:459
#define AST_DIGIT_ANY
Definition: file.h:48
const char * ast_app_expand_sub_args(struct ast_channel *chan, const char *args)
Add missing context/exten to subroutine argument string.
Definition: main/app.c:351
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation...
Definition: channel.c:2045
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define OPT_PREDIAL_CALLEE
Definition: app_dial.c:711
int ast_channel_supports_html(struct ast_channel *channel)
Checks for HTML support on a channel.
Definition: channel.c:6720
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
#define AST_OPTION_OPRMODE
#define LOG_WARNING
Definition: logger.h:274
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4712
static int timeout
Definition: cdr_mysql.c:86
static void end_bridge_callback(void *data)
Definition: app_dial.c:2174
static int tmp()
Definition: bt_open.c:389
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6553
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Definition: channel.c:11235
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
#define ast_trace(level,...)
Print a basic trace message.
Definition: logger.h:692
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4698
int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
Bridge a call, optionally allowing redirection.
Definition: features.c:716
#define DIAL_STILLGOING
Definition: app_dial.c:701
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * args
#define NULL
Definition: resample.c:96
int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
Send a DTMF digit to a channel.
Definition: channel.c:5019
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
#define OPT_CANCEL_TIMEOUT
Definition: app_dial.c:707
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7522
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
int ast_channel_priority(const struct ast_channel *chan)
#define ast_verb(level,...)
Definition: logger.h:463
static void handle_cause(int cause, struct cause_args *num)
Definition: app_dial.c:859
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
void ast_cc_call_failed(struct ast_channel *incoming, struct ast_channel *outgoing, const char *const dialstring)
Make CCBS available in the case that ast_call fails.
Definition: ccss.c:4199
#define CAN_EARLY_BRIDGE(flags, chan, peer)
Definition: app_dial.c:786
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
const char * start_sound
Definition: channel.h:1089
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
int done
Definition: test_amihooks.c:48
#define DIAL_CALLERID_ABSENT
Definition: app_dial.c:703
Number structure.
Definition: app_followme.c:154
const struct ast_channel_tech * tech
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2373
static int setup_privacy_args(struct privacy_args *pa, struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
returns 1 if successful, 0 or <0 if the caller should &#39;goto out&#39;
Definition: app_dial.c:2075
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void ast_replace_subargument_delimiter(char *s)
Replace &#39;^&#39; in a string with &#39;,&#39;.
Definition: main/utils.c:2095
#define ast_log
Definition: astobj2.c:42
void ast_cc_extension_monitor_add_dialstring(struct ast_channel *incoming, const char *const dialstring, const char *const device_name)
Add a child dialstring to an extension monitor.
Definition: ccss.c:2005
const char * interface
Definition: app_dial.c:800
static const char * get_cid_name(char *name, int namelen, struct ast_channel *chan)
Definition: app_dial.c:900
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Definition: channel.c:6817
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
struct ast_channel * chan
Definition: app_dial.c:798
#define OPT_PREDIAL_CALLER
Definition: app_dial.c:712
#define OPT_HANGUPCAUSE
Definition: app_dial.c:714
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
#define OPT_FORCE_CID_TAG
Definition: app_dial.c:708
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:113
static struct ast_channel * wait_for_answer(struct ast_channel *in, struct dial_head *out_chans, int *to, struct ast_flags64 *peerflags, char *opt_args[], struct privacy_args *pa, const struct cause_args *num_in, int *result, char *dtmf_progress, char *mf_progress, const int ignore_cc, struct ast_party_id *forced_clid, struct ast_party_id *stored_clid, struct ast_bridge_config *config)
Definition: app_dial.c:1202
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8859
#define AST_MAX_EXTENSION
Definition: channel.h:135
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
bridge configuration
Definition: channel.h:1077
void * end_bridge_callback_data
Definition: channel.h:1092
Caller Party information.
Definition: channel.h:419
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
const char * end_sound
Definition: channel.h:1088
static int dial_handle_playtones(struct ast_channel *chan, const char *data)
Definition: app_dial.c:2190
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
void(* end_bridge_callback_data_fixup)(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
Definition: channel.h:1096
int ast_cdr_reset(const char *channel_name, int keep_variables)
Reset the detail record.
Definition: cdr.c:3598
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
List of channel drivers.
Definition: app_dial.c:796
struct ast_channel * ast_request_with_stream_topology(const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel (specifying stream topology)
Definition: channel.c:6449
#define DIAL_NOFORWARDHTML
Definition: app_dial.c:702
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
int ast_app_exec_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_args)
Run a macro on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:273
int ast_pre_call(struct ast_channel *chan, const char *sub_args)
Execute a Gosub call on the channel before a call is placed.
Definition: channel.c:6536
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
Definition: channel.c:6526
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
const char * ast_channel_exten(const struct ast_channel *chan)
int ast_parse_caller_presentation(const char *data)
Convert caller ID text code to value (used in config file parsing)
Definition: callerid.c:1143
int ast_app_parse_options64(const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:2911
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
struct ast_party_connected_line connected
Definition: app_dial.c:809
struct ast_flags features_caller
Definition: channel.h:1078
int ast_cc_callback(struct ast_channel *inbound, const char *const tech, const char *const dest, ast_cc_callback_fn callback)
Run a callback for potential matching destinations.
Definition: ccss.c:4244
uint64_t flags
Definition: utils.h:205
int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
Start the CC process on a call.
Definition: ccss.c:2409
#define AST_PBX_INCOMPLETE
Definition: pbx.h:51
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
#define OPT_CALLER_ANSWER
Definition: app_dial.c:710
struct ast_sched_context * ast_channel_sched(const struct ast_channel *chan)
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
Definition: channel.c:1999
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
Definition: channel.c:11228
int privdb_val
Definition: app_dial.c:1140
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel&#39;s connected line information...
Definition: channel.c:10539
Channel datastore data for max forwards.
Definition: max_forwards.c:29
const char * number
Definition: app_dial.c:804
int ast_mf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
Send a string of MF digits to a channel.
Definition: main/app.c:967
ast_channel_adsicpe
Definition: channel.h:869
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
Connected Line/Party information.
Definition: channel.h:457
void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
Initialize the given party id structure using the given guide for a set update operation.
Definition: channel.c:1780
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
struct ast_channel * chan
Definition: app_dial.c:853
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7866
static void setup_peer_after_bridge_goto(struct ast_channel *chan, struct ast_channel *peer, struct ast_flags64 *opts, char *opt_args[])
Definition: app_dial.c:2232
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
int ast_channel_sendurl(struct ast_channel *channel, const char *url)
Sends a URL on a given link Send URL on link.
Definition: channel.c:6732
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const char * ast_cause2str(int state) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static const char name[]
Definition: cdr_mysql.c:74
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
Definition: channel.c:6866
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define AST_CHANNEL_NAME
Definition: channel.h:172
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
static const struct ast_app_option dial_exec_options[128]
Definition: app_dial.c:784
void ast_autoservice_chan_hangup_peer(struct ast_channel *chan, struct ast_channel *peer)
Put chan into autoservice while hanging up peer.
Definition: autoservice.c:342
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
Definition: channel.c:1757
#define ast_set2_flag64(p, value, flag)
Definition: utils.h:151
#define AST_PRIVACY_UNKNOWN
Definition: privacy.h:34
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
Definition: linkedlists.h:251
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct ast_channel * peer
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
Callback made from ast_cc_callback for certain channel types.
Definition: ccss.c:4232
Definition: astman.c:88
void(* end_bridge_callback)(void *)
Definition: channel.h:1091
#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:332
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
void ast_ignore_cc(struct ast_channel *chan)
Mark the channel to ignore further CC activity.
Definition: ccss.c:3720
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:2902
int transit_network_select
Transit Network Select.
Definition: channel.h:398
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
Definition: channel.c:2031
char * strsep(char **str, const char *delims)
int ast_max_forwards_decrement(struct ast_channel *chan)
Decrement the max forwards count for a particular channel.
Definition: max_forwards.c:135
FILE * out
Definition: utils/frame.c:33
int ast_channel_hangupcause(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
static void chanlist_free(struct chanlist *outgoing)
Definition: app_dial.c:821
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8389
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
#define ast_frfree(fr)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
static PGresult * result
Definition: cel_pgsql.c:88
#define AST_CAUSE_BUSY
Definition: causes.h:148
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition: sched.c:431
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Definition: channel.c:10697
Data structure associated with a single frame of data.
int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
Run a subroutine on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:370
const char * ast_channel_language(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
union ast_frame::@263 data
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
enum ast_frame_type frametype
int ast_str2cause(const char *name) attribute_pure
Convert the string form of a cause code to a number.
Definition: channel.c:625
const char * warning_sound
Definition: channel.h:1087
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
Definition: app_dial.c:2186
char status[256]
Definition: app_dial.c:1143
static struct test_options options
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
const char * ast_channel_macrocontext(const struct ast_channel *chan)
static char url[512]
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c_dst, struct ast_channel *c_src)
Make two channels compatible for early bridging.
Definition: rtp_engine.c:2251
static void hanguptree(struct dial_head *out_chans, struct ast_channel *exception, int hangupcause)
Definition: app_dial.c:829
char connected
Definition: eagi_proxy.c:82
ast_timing_func_t ast_channel_timingfunc(const struct ast_channel *chan)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:447
void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Set the connected line information in the Asterisk channel.
Definition: channel.c:8404
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
const char * ast_channel_macroexten(const struct ast_channel *chan)
void ast_channel_data_set(struct ast_channel *chan, const char *value)
int ast_app_group_set_channel(struct ast_channel *chan, const char *data)
Set the group for a channel, splitting the provided data into group and category, if specified...
Definition: main/app.c:2036
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Definition: channel.c:2135
const char * ast_channel_musicclass(const struct ast_channel *chan)
#define AST_APP_ARG(name)
Define an application argument.
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1008
int ast_bridge_timelimit(struct ast_channel *chan, struct ast_bridge_config *config, char *parse, struct timeval *calldurationlimit)
parse L option and read associated channel variables to set warning, warning frequency, and timelimit
Definition: features.c:886
char * orig_chan_name
Definition: app_dial.c:806
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ dial_handle_playtones()

static int dial_handle_playtones ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2190 of file app_dial.c.

References ast_channel_zone(), ast_debug, ast_get_indication_tone(), ast_log, ast_playtones_start(), ast_strlen_zero, ast_tone_zone_sound_unref(), ast_tone_zone_sound::data, LOG_WARNING, NULL, and str.

Referenced by dial_exec_full().

2191 {
2192  struct ast_tone_zone_sound *ts = NULL;
2193  int res;
2194  const char *str = data;
2195 
2196  if (ast_strlen_zero(str)) {
2197  ast_debug(1,"Nothing to play\n");
2198  return -1;
2199  }
2200 
2201  ts = ast_get_indication_tone(ast_channel_zone(chan), str);
2202 
2203  if (ts && ts->data[0]) {
2204  res = ast_playtones_start(chan, 0, ts->data, 0);
2205  } else {
2206  res = -1;
2207  }
2208 
2209  if (ts) {
2210  ts = ast_tone_zone_sound_unref(ts);
2211  }
2212 
2213  if (res) {
2214  ast_log(LOG_WARNING, "Unable to start playtone \'%s\'\n", str);
2215  }
2216 
2217  return res;
2218 }
#define LOG_WARNING
Definition: logger.h:274
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
Definition: indications.h:227
Description of a tone.
Definition: indications.h:35
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Definition: indications.c:455
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302
const char * data
Description of a tone.
Definition: indications.h:52

◆ do_forward()

static void do_forward ( struct chanlist o,
struct cause_args num,
struct ast_flags64 peerflags,
int  single,
int  caller_entertained,
int *  to,
struct ast_party_id forced_clid,
struct ast_party_id stored_clid 
)
static

helper function for wait_for_answer()

Parameters
oOutgoing call channel list.
numIncoming call channel cause accumulation
peerflagsDial option flags
singleTRUE if there is only one outgoing call.
caller_entertainedTRUE if the caller is being entertained by MOH or ringback.
toRemaining call timeout time.
forced_clidOPT_FORCECLID caller id to send
stored_clidCaller id representing the called party if needed

XXX this code is highly suspicious, as it essentially overwrites the outgoing channel without properly deleting it.

Todo:
eventually this function should be intergrated into and replaced by ast_call_forward()

Definition at line 930 of file app_dial.c.

References ast_call(), AST_CAUSE_BUSY, ast_channel_appl_set(), ast_channel_call_forward(), ast_channel_caller(), ast_channel_connected(), ast_channel_context(), ast_channel_data_set(), ast_channel_datastore_inherit(), ast_channel_dialed(), ast_channel_exten(), ast_channel_get_stream_topology(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_macroexten(), ast_channel_make_compatible(), AST_CHANNEL_NAME, ast_channel_name(), ast_channel_publish_dial(), ast_channel_publish_dial_forward(), ast_channel_publish_snapshot(), ast_channel_redirecting(), ast_channel_redirecting_macro(), ast_channel_redirecting_sub(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_BRIDGE_PEER, ast_channel_set_caller_event(), ast_channel_unlock, ast_channel_update_redirecting(), ast_clear_flag64, ast_connected_line_copy_from_caller(), ast_copy_string(), ast_hangup(), ast_ignore_cc(), ast_indicate(), ast_log, ast_max_forwards_decrement(), ast_party_caller_set_init(), ast_party_connected_line_copy(), ast_party_connected_line_init(), ast_party_number_free(), ast_party_number_init(), ast_party_redirecting_copy(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_request_with_stream_topology(), ast_rtp_instance_early_bridge_make_compatible(), ast_set_flag64, ast_strdup, ast_stream_topology_clone(), ast_stream_topology_free(), ast_strlen_zero, ast_test_flag64, ast_verb, c, CAN_EARLY_BRIDGE, chanlist::chan, cause_args::chan, DIAL_CALLERID_ABSENT, DIAL_STILLGOING, ast_party_redirecting::from, handle_cause(), ast_party_caller::id, ast_party_connected_line::id, in, LOG_NOTICE, cause_args::nochan, NULL, ast_party_id::number, OPT_CANCEL_TIMEOUT, OPT_FORCECLID, OPT_IGNORE_CONNECTEDLINE, OPT_IGNORE_FORWARDING, OPT_ORIGINAL_CLID, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_COR, S_OR, ast_party_number::str, chanlist::stuff, chanlist::tech, ast_party_dialed::transit_network_select, and ast_party_number::valid.

Referenced by wait_for_answer().

933 {
934  char tmpchan[256];
935  char forwarder[AST_CHANNEL_NAME];
936  struct ast_channel *original = o->chan;
937  struct ast_channel *c = o->chan; /* the winner */
938  struct ast_channel *in = num->chan; /* the input channel */
939  char *stuff;
940  char *tech;
941  int cause;
942  struct ast_party_caller caller;
943 
944  ast_copy_string(forwarder, ast_channel_name(c), sizeof(forwarder));
945  ast_copy_string(tmpchan, ast_channel_call_forward(c), sizeof(tmpchan));
946  if ((stuff = strchr(tmpchan, '/'))) {
947  *stuff++ = '\0';
948  tech = tmpchan;
949  } else {
950  const char *forward_context;
951  ast_channel_lock(c);
952  forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
953  if (ast_strlen_zero(forward_context)) {
954  forward_context = NULL;
955  }
956  snprintf(tmpchan, sizeof(tmpchan), "%s@%s", ast_channel_call_forward(c), forward_context ? forward_context : ast_channel_context(c));
958  stuff = tmpchan;
959  tech = "Local";
960  }
961  if (!strcasecmp(tech, "Local")) {
962  /*
963  * Drop the connected line update block for local channels since
964  * this is going to run dialplan and the user can change his
965  * mind about what connected line information he wants to send.
966  */
968  }
969 
970  /* Before processing channel, go ahead and check for forwarding */
971  ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", ast_channel_name(in), tech, stuff, ast_channel_name(c));
972  /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
973  if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
974  ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", ast_channel_name(in), tech, stuff);
975  ast_channel_publish_dial_forward(in, original, NULL, NULL, "CANCEL",
976  ast_channel_call_forward(original));
977  c = o->chan = NULL;
978  cause = AST_CAUSE_BUSY;
979  } else {
980  struct ast_stream_topology *topology;
981 
982  ast_channel_lock(in);
984  ast_channel_unlock(in);
985 
986  /* Setup parameters */
987  c = o->chan = ast_request_with_stream_topology(tech, topology, NULL, in, stuff, &cause);
988 
989  ast_stream_topology_free(topology);
990 
991  if (c) {
992  if (single && !caller_entertained) {
994  }
995  ast_channel_lock_both(in, o->chan);
998  pbx_builtin_setvar_helper(o->chan, "FORWARDERNAME", forwarder);
1000  ast_channel_unlock(in);
1002  /* When a call is forwarded, we don't want to track new interfaces
1003  * dialed for CC purposes. Setting the done flag will ensure that
1004  * any Dial operations that happen later won't record CC interfaces.
1005  */
1006  ast_ignore_cc(o->chan);
1007  ast_verb(3, "Not accepting call completion offers from call-forward recipient %s\n",
1008  ast_channel_name(o->chan));
1009  } else
1011  "Forwarding failed to create channel to dial '%s/%s' (cause = %d)\n",
1012  tech, stuff, cause);
1013  }
1014  if (!c) {
1015  ast_channel_publish_dial(in, original, stuff, "BUSY");
1017  handle_cause(cause, num);
1018  ast_hangup(original);
1019  } else {
1020  ast_channel_lock_both(c, original);
1022  ast_channel_redirecting(original));
1023  ast_channel_unlock(c);
1024  ast_channel_unlock(original);
1025 
1026  ast_channel_lock_both(c, in);
1027 
1028  if (single && !caller_entertained && CAN_EARLY_BRIDGE(peerflags, c, in)) {
1030  }
1031 
1032  if (!ast_channel_redirecting(c)->from.number.valid
1033  || ast_strlen_zero(ast_channel_redirecting(c)->from.number.str)) {
1034  /*
1035  * The call was not previously redirected so it is
1036  * now redirected from this number.
1037  */
1043  }
1044 
1046 
1047  /* Determine CallerID to store in outgoing channel. */
1049  if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
1050  caller.id = *stored_clid;
1051  ast_channel_set_caller_event(c, &caller, NULL);
1053  } else if (ast_strlen_zero(S_COR(ast_channel_caller(c)->id.number.valid,
1054  ast_channel_caller(c)->id.number.str, NULL))) {
1055  /*
1056  * The new channel has no preset CallerID number by the channel
1057  * driver. Use the dialplan extension and hint name.
1058  */
1059  caller.id = *stored_clid;
1060  ast_channel_set_caller_event(c, &caller, NULL);
1062  } else {
1064  }
1065 
1066  /* Determine CallerID for outgoing channel to send. */
1067  if (ast_test_flag64(o, OPT_FORCECLID)) {
1069 
1071  connected.id = *forced_clid;
1073  } else {
1075  }
1076 
1078 
1079  ast_channel_appl_set(c, "AppDial");
1080  ast_channel_data_set(c, "(Outgoing Line)");
1082 
1083  ast_channel_unlock(in);
1084  if (single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1085  struct ast_party_redirecting redirecting;
1086 
1087  /*
1088  * Redirecting updates to the caller make sense only on single
1089  * calls.
1090  *
1091  * We must unlock c before calling
1092  * ast_channel_redirecting_macro, because we put c into
1093  * autoservice there. That is pretty much a guaranteed
1094  * deadlock. This is why the handling of c's lock may seem a
1095  * bit unusual here.
1096  */
1097  ast_party_redirecting_init(&redirecting);
1099  ast_channel_unlock(c);
1100  if (ast_channel_redirecting_sub(c, in, &redirecting, 0) &&
1101  ast_channel_redirecting_macro(c, in, &redirecting, 1, 0)) {
1102  ast_channel_update_redirecting(in, &redirecting, NULL);
1103  }
1104  ast_party_redirecting_free(&redirecting);
1105  } else {
1106  ast_channel_unlock(c);
1107  }
1108 
1109  if (ast_test_flag64(peerflags, OPT_CANCEL_TIMEOUT)) {
1110  *to = -1;
1111  }
1112 
1113  if (ast_call(c, stuff, 0)) {
1114  ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n",
1115  tech, stuff);
1116  ast_channel_publish_dial(in, original, stuff, "CONGESTION");
1118  ast_hangup(original);
1119  ast_hangup(c);
1120  c = o->chan = NULL;
1121  num->nochan++;
1122  } else {
1123  ast_channel_publish_dial_forward(in, original, c, NULL, "CANCEL",
1124  ast_channel_call_forward(original));
1125 
1126  ast_channel_publish_dial(in, c, stuff, NULL);
1127 
1128  /* Hangup the original channel now, in case we needed it */
1129  ast_hangup(original);
1130  }
1131  if (single && !caller_entertained) {
1132  ast_indicate(in, -1);
1133  }
1134  }
1135 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
Definition: channel.c:7472
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:528
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Indicate that the redirecting id has changed.
Definition: channel.c:10379
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6553
#define DIAL_STILLGOING
Definition: app_dial.c:701
#define ast_set_flag64(p, flag)
Definition: utils.h:127
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define OPT_CANCEL_TIMEOUT
Definition: app_dial.c:707
const char * ast_channel_call_forward(const struct ast_channel *chan)
#define ast_verb(level,...)
Definition: logger.h:463
static void handle_cause(int cause, struct cause_args *num)
Definition: app_dial.c:859
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define CAN_EARLY_BRIDGE(flags, chan, peer)
Definition: app_dial.c:786
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define DIAL_CALLERID_ABSENT
Definition: app_dial.c:703
Number structure.
Definition: app_followme.c:154
const struct ast_channel_tech * tech
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2373
#define ast_log
Definition: astobj2.c:42
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Definition: channel.c:6817
FILE * in
Definition: utils/frame.c:33
struct ast_channel * chan
Definition: app_dial.c:798
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
Run a redirecting interception subroutine and update a channel&#39;s redirecting information.
Definition: channel.c:10584
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
Definition: channel.c:1644
Caller Party information.
Definition: channel.h:419
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
struct ast_channel * ast_request_with_stream_topology(const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel (specifying stream topology)
Definition: channel.c:6449
int nochan
Definition: app_dial.c:856
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
Definition: channel.c:6526
const char * ast_channel_exten(const struct ast_channel *chan)
void ast_party_number_free(struct ast_party_number *doomed)
Destroy the party number contents.
Definition: channel.c:1691
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
Definition: channel.c:1999
Connected Line/Party information.
Definition: channel.h:457
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
struct ast_channel * chan
Definition: app_dial.c:853
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:523
#define LOG_NOTICE
Definition: logger.h:263
void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
Definition: channel.c:6866
#define AST_CHANNEL_NAME
Definition: channel.h:172
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define ast_clear_flag64(p, flag)
Definition: utils.h:134
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
void ast_ignore_cc(struct ast_channel *chan)
Mark the channel to ignore further CC activity.
Definition: ccss.c:3720
int transit_network_select
Transit Network Select.
Definition: channel.h:398
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2179
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
Definition: channel.c:2031
int ast_max_forwards_decrement(struct ast_channel *chan)
Decrement the max forwards count for a particular channel.
Definition: max_forwards.c:135
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:531
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8389
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
Definition: channel.c:2122
#define AST_CAUSE_BUSY
Definition: causes.h:148
const char * ast_channel_context(const struct ast_channel *chan)
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c_dst, struct ast_channel *c_src)
Make two channels compatible for early bridging.
Definition: rtp_engine.c:2251
char connected
Definition: eagi_proxy.c:82
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
const char * ast_channel_macroexten(const struct ast_channel *chan)
void ast_channel_data_set(struct ast_channel *chan, const char *value)
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Definition: channel.c:2135
int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
Run a redirecting interception macro and update a channel&#39;s redirecting information.
Definition: channel.c:10487
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ end_bridge_callback()

static void end_bridge_callback ( void *  data)
static

Definition at line 2174 of file app_dial.c.

References ast_channel_get_duration_ms(), ast_channel_get_up_time_ms(), ast_channel_lock, ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_unlock, ast_channel::data, and set_duration_var().

Referenced by dial_exec_full().

2175 {
2176  struct ast_channel *chan = data;
2177 
2178  ast_channel_lock(chan);
2180  set_duration_var(chan, "ANSWEREDTIME", ast_channel_get_up_time_ms(chan));
2181  set_duration_var(chan, "DIALEDTIME", ast_channel_get_duration_ms(chan));
2183  ast_channel_unlock(chan);
2184 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
int64_t ast_channel_get_duration_ms(struct ast_channel *chan)
Obtain how long it&#39;s been, in milliseconds, since the channel was created.
Definition: channel.c:2829
int64_t ast_channel_get_up_time_ms(struct ast_channel *chan)
Obtain how long it has been since the channel was answered in ms.
Definition: channel.c:2844
const char * data
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void set_duration_var(struct ast_channel *chan, const char *var_base, int64_t duration)
Definition: app_dial.c:1189

◆ end_bridge_callback_data_fixup()

static void end_bridge_callback_data_fixup ( struct ast_bridge_config bconfig,
struct ast_channel originator,
struct ast_channel terminator 
)
static

Definition at line 2186 of file app_dial.c.

References ast_bridge_config::end_bridge_callback_data.

Referenced by dial_exec_full().

2186  {
2187  bconfig->end_bridge_callback_data = originator;
2188 }
void * end_bridge_callback_data
Definition: channel.h:1092

◆ get_cid_name()

static const char* get_cid_name ( char *  name,
int  namelen,
struct ast_channel chan 
)
static

Definition at line 900 of file app_dial.c.

References ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_macrocontext(), ast_channel_macroexten(), ast_channel_unlock, ast_get_hint(), ast_strdupa, context, exten, name, NULL, and S_OR.

Referenced by dial_exec_full().

901 {
902  const char *context;
903  const char *exten;
904 
905  ast_channel_lock(chan);
908  ast_channel_unlock(chan);
909 
910  return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
911 }
int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
If an extension hint exists, return non-zero.
Definition: pbx.c:4141
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define NULL
Definition: resample.c:96
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static const char name[]
Definition: cdr_mysql.c:74
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_context(const struct ast_channel *chan)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
const char * ast_channel_macrocontext(const struct ast_channel *chan)
const char * ast_channel_macroexten(const struct ast_channel *chan)

◆ handle_cause()

static void handle_cause ( int  cause,
struct cause_args num 
)
static

Definition at line 859 of file app_dial.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_UNREGISTERED, cause_args::busy, cause_args::congestion, and cause_args::nochan.

Referenced by dial_exec_full(), do_forward(), and wait_for_answer().

860 {
861  switch(cause) {
862  case AST_CAUSE_BUSY:
863  num->busy++;
864  break;
866  num->congestion++;
867  break;
870  num->nochan++;
871  break;
872  case AST_CAUSE_NO_ANSWER:
874  break;
875  default:
876  num->nochan++;
877  break;
878  }
879 }
int congestion
Definition: app_dial.c:855
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
int nochan
Definition: app_dial.c:856
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:153
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
int busy
Definition: app_dial.c:854
#define AST_CAUSE_BUSY
Definition: causes.h:148
#define AST_CAUSE_CONGESTION
Definition: causes.h:152

◆ hanguptree()

static void hanguptree ( struct dial_head out_chans,
struct ast_channel exception,
int  hangupcause 
)
static

Definition at line 829 of file app_dial.c.

References ast_channel_hangupcause_set(), ast_hangup(), AST_LIST_REMOVE_HEAD, chanlist::chan, and chanlist_free().

Referenced by dial_exec_full().

830 {
831  /* Hang up a tree of stuff */
832  struct chanlist *outgoing;
833 
834  while ((outgoing = AST_LIST_REMOVE_HEAD(out_chans, node))) {
835  /* Hangup any existing lines we have open */
836  if (outgoing->chan && (outgoing->chan != exception)) {
837  if (hangupcause >= 0) {
838  /* This is for the channel drivers */
839  ast_channel_hangupcause_set(outgoing->chan, hangupcause);
840  }
841  ast_hangup(outgoing->chan);
842  }
843  chanlist_free(outgoing);
844  }
845 }
Definition: test_heap.c:38
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
struct ast_channel * chan
Definition: app_dial.c:798
List of channel drivers.
Definition: app_dial.c:796
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
static void chanlist_free(struct chanlist *outgoing)
Definition: app_dial.c:821

◆ load_module()

static int load_module ( void  )
static

Definition at line 3552 of file app_dial.c.

References app, AST_MODFLAG_DEFAULT, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_register_application_xml, ASTERISK_GPL_KEY, dial_exec(), rapp, retrydial_exec(), and unload_module().

3553 {
3554  int res;
3555 
3558 
3559  return res;
3560 }
static int retrydial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3434
static int dial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3425
static const char app[]
Definition: app_dial.c:663
static const char rapp[]
Definition: app_dial.c:664
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ onedigit_goto()

static int onedigit_goto ( struct ast_channel chan,
const char *  context,
char  exten,
int  pri 
)
static

Definition at line 881 of file app_dial.c.

References ast_channel_context(), ast_channel_macrocontext(), ast_goto_if_exists(), ast_strlen_zero, and exten.

Referenced by retrydial_exec(), and wait_for_answer().

882 {
883  char rexten[2] = { exten, '\0' };
884 
885  if (context) {
886  if (!ast_goto_if_exists(chan, context, rexten, pri))
887  return 1;
888  } else {
889  if (!ast_goto_if_exists(chan, ast_channel_context(chan), rexten, pri))
890  return 1;
891  else if (!ast_strlen_zero(ast_channel_macrocontext(chan))) {
892  if (!ast_goto_if_exists(chan, ast_channel_macrocontext(chan), rexten, pri))
893  return 1;
894  }
895  }
896  return 0;
897 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:8793
const char * ast_channel_context(const struct ast_channel *chan)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
const char * ast_channel_macrocontext(const struct ast_channel *chan)

◆ publish_dial_end_event()

static void publish_dial_end_event ( struct ast_channel in,
struct dial_head out_chans,
struct ast_channel exception,
const char *  status 
)
static

Definition at line 1146 of file app_dial.c.

References ast_channel_publish_dial(), AST_LIST_TRAVERSE, chanlist::chan, and NULL.

Referenced by wait_for_answer().

1147 {
1148  struct chanlist *outgoing;
1149  AST_LIST_TRAVERSE(out_chans, outgoing, node) {
1150  if (!outgoing->chan || outgoing->chan == exception) {
1151  continue;
1152  }
1153  ast_channel_publish_dial(in, outgoing->chan, NULL, status);
1154  }
1155 }
Definition: test_heap.c:38
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
#define NULL
Definition: resample.c:96
struct ast_channel * chan
Definition: app_dial.c:798
List of channel drivers.
Definition: app_dial.c:796
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
jack_status_t status
Definition: app_jack.c:146

◆ retrydial_exec()

static int retrydial_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 3434 of file app_dial.c.

References args, AST_APP_ARG, ast_channel_data_set(), ast_channel_flags(), ast_channel_language(), ast_channel_lock, ast_channel_unlock, AST_DECLARE_APP_ARGS, AST_DIGIT_ANY, ast_fileexists(), AST_FLAG_MOH, ast_log, ast_moh_start(), ast_moh_stop(), AST_PBX_INCOMPLETE, AST_STANDARD_APP_ARGS, ast_strdupa, ast_streamfile(), ast_strlen_zero, ast_test_flag, ast_test_flag64, ast_waitfordigit(), ast_waitstream(), context, dial_exec_full(), done, LOG_ERROR, LOG_WARNING, NULL, onedigit_goto(), OPT_DTMF_EXIT, parse(), pbx_builtin_getvar_helper(), and rapp.

Referenced by load_module().

3435 {
3436  char *parse;
3437  const char *context = NULL;
3438  int sleepms = 0, loops = 0, res = -1;
3439  struct ast_flags64 peerflags = { 0, };
3441  AST_APP_ARG(announce);
3442  AST_APP_ARG(sleep);
3443  AST_APP_ARG(retries);
3444  AST_APP_ARG(dialdata);
3445  );
3446 
3447  if (ast_strlen_zero(data)) {
3448  ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
3449  return -1;
3450  }
3451 
3452  parse = ast_strdupa(data);
3453  AST_STANDARD_APP_ARGS(args, parse);
3454 
3455  if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
3456  sleepms *= 1000;
3457 
3458  if (!ast_strlen_zero(args.retries)) {
3459  loops = atoi(args.retries);
3460  }
3461 
3462  if (!args.dialdata) {
3463  ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
3464  goto done;
3465  }
3466 
3467  if (sleepms < 1000)
3468  sleepms = 10000;
3469 
3470  if (!loops)
3471  loops = -1; /* run forever */
3472 
3473  ast_channel_lock(chan);
3474  context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
3475  context = !ast_strlen_zero(context) ? ast_strdupa(context) : NULL;
3476  ast_channel_unlock(chan);
3477 
3478  res = 0;
3479  while (loops) {
3480  int continue_exec;
3481 
3482  ast_channel_data_set(chan, "Retrying");
3484  ast_moh_stop(chan);
3485 
3486  res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
3487  if (continue_exec)
3488  break;
3489 
3490  if (res == 0) {
3491  if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
3492  if (!ast_strlen_zero(args.announce)) {
3493  if (ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3494  if (!(res = ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3496  } else
3497  ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3498  }
3499  if (!res && sleepms) {
3501  ast_moh_start(chan, NULL, NULL);
3502  res = ast_waitfordigit(chan, sleepms);
3503  }
3504  } else {
3505  if (!ast_strlen_zero(args.announce)) {
3506  if (ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3507  if (!(res = ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3508  res = ast_waitstream(chan, "");
3509  } else
3510  ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3511  }
3512  if (sleepms) {
3514  ast_moh_start(chan, NULL, NULL);
3515  if (!res)
3516  res = ast_waitfordigit(chan, sleepms);
3517  }
3518  }
3519  }
3520 
3521  if (res < 0 || res == AST_PBX_INCOMPLETE) {
3522  break;
3523  } else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
3524  if (onedigit_goto(chan, context, (char) res, 1)) {
3525  res = 0;
3526  break;
3527  }
3528  }
3529  loops--;
3530  }
3531  if (loops == 0)
3532  res = 0;
3533  else if (res == 1)
3534  res = 0;
3535 
3537  ast_moh_stop(chan);
3538  done:
3539  return res;
3540 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
Definition: app_dial.c:881
#define AST_DIGIT_ANY
Definition: file.h:48
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define NULL
Definition: resample.c:96
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
int done
Definition: test_amihooks.c:48
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define AST_PBX_INCOMPLETE
Definition: pbx.h:51
#define LOG_ERROR
Definition: logger.h:285
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7866
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
static const char rapp[]
Definition: app_dial.c:664
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
Definition: app_dial.c:2254
const char * ast_channel_language(const struct ast_channel *chan)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
void ast_channel_data_set(struct ast_channel *chan, const char *value)
#define AST_APP_ARG(name)
Define an application argument.
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ set_duration_var()

static void set_duration_var ( struct ast_channel chan,
const char *  var_base,
int64_t  duration 
)
static

Definition at line 1189 of file app_dial.c.

References buf, and pbx_builtin_setvar_helper().

Referenced by end_bridge_callback(), and wait_for_answer().

1190 {
1191  char buf[32];
1192  char full_var_name[128];
1193 
1194  snprintf(buf, sizeof(buf), "%" PRId64, duration / 1000);
1195  pbx_builtin_setvar_helper(chan, var_base, buf);
1196 
1197  snprintf(full_var_name, sizeof(full_var_name), "%s_MS", var_base);
1198  snprintf(buf, sizeof(buf), "%" PRId64, duration);
1199  pbx_builtin_setvar_helper(chan, full_var_name, buf);
1200 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...

◆ setup_peer_after_bridge_goto()

static void setup_peer_after_bridge_goto ( struct ast_channel chan,
struct ast_channel peer,
struct ast_flags64 opts,
char *  opt_args[] 
)
static

Definition at line 2232 of file app_dial.c.

References ast_bridge_set_after_go_on(), ast_bridge_set_after_h(), ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_priority(), ast_channel_unlock, ast_strdupa, ast_test_flag64, context, OPT_ARG_CALLEE_GO_ON, OPT_CALLEE_GO_ON, OPT_PEER_H, and priority.

Referenced by dial_exec_full().

2233 {
2234  const char *context;
2235  const char *extension;
2236  int priority;
2237 
2238  if (ast_test_flag64(opts, OPT_PEER_H)) {
2239  ast_channel_lock(chan);
2240  context = ast_strdupa(ast_channel_context(chan));
2241  ast_channel_unlock(chan);
2242  ast_bridge_set_after_h(peer, context);
2243  } else if (ast_test_flag64(opts, OPT_CALLEE_GO_ON)) {
2244  ast_channel_lock(chan);
2245  context = ast_strdupa(ast_channel_context(chan));
2246  extension = ast_strdupa(ast_channel_exten(chan));
2247  priority = ast_channel_priority(chan);
2248  ast_channel_unlock(chan);
2249  ast_bridge_set_after_go_on(peer, context, extension, priority,
2250  opt_args[OPT_ARG_CALLEE_GO_ON]);
2251  }
2252 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define OPT_CALLEE_GO_ON
Definition: app_dial.c:706
static int priority
int ast_channel_priority(const struct ast_channel *chan)
void ast_bridge_set_after_h(struct ast_channel *chan, const char *context)
Set channel to run the h exten after the bridge.
Definition: bridge_after.c:631
structure to hold extensions
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define OPT_PEER_H
Definition: app_dial.c:705
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const char * ast_channel_context(const struct ast_channel *chan)
void ast_bridge_set_after_go_on(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *parseable_goto)
Set channel to go on in the dialplan after the bridge.
Definition: bridge_after.c:636
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ setup_privacy_args()

static int setup_privacy_args ( struct privacy_args pa,
struct ast_flags64 opts,
char *  opt_args[],
struct ast_channel chan 
)
static

returns 1 if successful, 0 or <0 if the caller should 'goto out'

Definition at line 2075 of file app_dial.c.

References ast_answer(), ast_channel_caller(), ast_channel_exten(), ast_channel_language(), ast_channel_name(), ast_config_AST_DATA_DIR, ast_copy_string(), ast_dsp_get_threshold_from_settings(), ast_filedelete(), ast_fileexists(), ast_log, ast_mkdir(), ast_play_and_record(), AST_PRIVACY_ALLOW, ast_privacy_check(), AST_PRIVACY_DENY, AST_PRIVACY_KILL, AST_PRIVACY_TORTURE, AST_PRIVACY_UNKNOWN, ast_shrink_phone_number(), ast_strdupa, ast_streamfile(), ast_strlen_zero, ast_test_flag64, ast_verb, ast_waitstream(), LOG_NOTICE, LOG_WARNING, NULL, OPT_ARG_PRIVACY, OPT_PRIVACY, OPT_SCREEN_NOCALLERID, privacy_args::privcid, privacy_args::privdb_val, privacy_args::privintro, silencethreshold, privacy_args::status, and THRESHOLD_SILENCE.

Referenced by dial_exec_full().

2077 {
2078  char callerid[60];
2079  int res;
2080  char *l;
2081 
2082  if (ast_channel_caller(chan)->id.number.valid
2083  && !ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
2084  l = ast_strdupa(ast_channel_caller(chan)->id.number.str);
2086  if (ast_test_flag64(opts, OPT_PRIVACY) ) {
2087  ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
2088  pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
2089  } else {
2090  ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
2092  }
2093  } else {
2094  char *tnam, *tn2;
2095 
2096  tnam = ast_strdupa(ast_channel_name(chan));
2097  /* clean the channel name so slashes don't try to end up in disk file name */
2098  for (tn2 = tnam; *tn2; tn2++) {
2099  if (*tn2 == '/') /* any other chars to be afraid of? */
2100  *tn2 = '=';
2101  }
2102  ast_verb(3, "Privacy-- callerid is empty\n");
2103 
2104  snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", ast_channel_exten(chan), tnam);
2105  l = callerid;
2107  }
2108 
2109  ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
2110 
2111  if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
2112  /* if callerid is set and OPT_SCREEN_NOCALLERID is set also */
2113  ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
2115  } else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
2116  ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
2117  }
2118 
2119  if (pa->privdb_val == AST_PRIVACY_DENY) {
2120  ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
2121  ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
2122  return 0;
2123  } else if (pa->privdb_val == AST_PRIVACY_KILL) {
2124  ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
2125  return 0; /* Is this right? */
2126  } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
2127  ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
2128  return 0; /* is this right??? */
2129  } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
2130  /* Get the user's intro, store it in priv-callerintros/$CID,
2131  unless it is already there-- this should be done before the
2132  call is actually dialed */
2133 
2134  /* make sure the priv-callerintros dir actually exists */
2135  snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
2136  if ((res = ast_mkdir(pa->privintro, 0755))) {
2137  ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
2138  return -1;
2139  }
2140 
2141  snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
2142  if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
2143  /* the DELUX version of this code would allow this caller the
2144  option to hear and retape their previously recorded intro.
2145  */
2146  } else {
2147  int duration; /* for feedback from play_and_wait */
2148  /* the file doesn't exist yet. Let the caller submit his
2149  vocal intro for posterity */
2150  /* priv-recordintro script:
2151  "At the tone, please say your name:"
2152  */
2154  ast_answer(chan);
2155  res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "sln", &duration, NULL, silencethreshold, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */
2156  /* don't think we'll need a lock removed, we took care of
2157  conflicts by naming the pa.privintro file */
2158  if (res == -1) {
2159  /* Delete the file regardless since they hung up during recording */
2161  if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
2162  ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
2163  else
2164  ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
2165  return -1;
2166  }
2167  if (!ast_streamfile(chan, "vm-dialout", ast_channel_language(chan)) )
2168  ast_waitstream(chan, "");
2169  }
2170  }
2171  return 1; /* success */
2172 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define AST_PRIVACY_ALLOW
Definition: privacy.h:31
char privintro[1024]
Definition: app_dial.c:1142
char privcid[256]
Definition: app_dial.c:1141
int ast_privacy_check(char *dest, char *cid)
Definition: privacy.c:46
#define LOG_WARNING
Definition: logger.h:274
#define AST_PRIVACY_TORTURE
Definition: privacy.h:33
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
#define ast_log
Definition: astobj2.c:42
#define AST_PRIVACY_KILL
Definition: privacy.h:32
static int silencethreshold
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_channel_exten(const struct ast_channel *chan)
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
int privdb_val
Definition: app_dial.c:1140
int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path)
Record a file based on input from a channel. Use default accept and cancel DTMF. This function will p...
Definition: main/app.c:1997
#define LOG_NOTICE
Definition: logger.h:263
#define AST_PRIVACY_UNKNOWN
Definition: privacy.h:34
#define AST_PRIVACY_DENY
Definition: privacy.h:30
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
const char * ast_channel_language(const struct ast_channel *chan)
char status[256]
Definition: app_dial.c:1143
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:947
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1996
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: main/utils.c:2231
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 3542 of file app_dial.c.

References app, ast_unregister_application(), and rapp.

Referenced by load_module().

3543 {
3544  int res;
3545 
3548 
3549  return res;
3550 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static const char app[]
Definition: app_dial.c:663
static const char rapp[]
Definition: app_dial.c:664

◆ update_connected_line_from_peer()

static void update_connected_line_from_peer ( struct ast_channel chan,
struct ast_channel peer,
int  is_caller 
)
static

Definition at line 1168 of file app_dial.c.

References ast_channel_caller(), ast_channel_connected_line_macro(), ast_channel_connected_line_sub(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_copy_from_caller(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, ast_party_connected_line_free(), ast_party_connected_line_init(), NULL, and ast_party_connected_line::source.

Referenced by wait_for_answer().

1169 {
1170  struct ast_party_connected_line connected_caller;
1171 
1172  ast_party_connected_line_init(&connected_caller);
1173 
1174  ast_channel_lock(peer);
1175  ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(peer));
1176  ast_channel_unlock(peer);
1177  connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1178  if (ast_channel_connected_line_sub(peer, chan, &connected_caller, 0)
1179  && ast_channel_connected_line_macro(peer, chan, &connected_caller, is_caller, 0)) {
1180  ast_channel_update_connected_line(chan, &connected_caller, NULL);
1181  }
1182  ast_party_connected_line_free(&connected_caller);
1183 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
#define ast_channel_lock(chan)
Definition: channel.h:2945
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame)
Run a connected line interception macro and update a channel&#39;s connected line information.
Definition: channel.c:10435
void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Indicate that the connected line information has changed.
Definition: channel.c:9189
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2072
#define NULL
Definition: resample.c:96
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel&#39;s connected line information...
Definition: channel.c:10539
Connected Line/Party information.
Definition: channel.h:457
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8389

◆ valid_priv_reply()

static int valid_priv_reply ( struct ast_flags64 opts,
int  res 
)
static

◆ wait_for_answer()

static struct ast_channel* wait_for_answer ( struct ast_channel in,
struct dial_head out_chans,
int *  to,
struct ast_flags64 peerflags,
char *  opt_args[],
struct privacy_args pa,
const struct cause_args num_in,
int *  result,
char *  dtmf_progress,
char *  mf_progress,
const int  ignore_cc,
struct ast_party_id forced_clid,
struct ast_party_id stored_clid,
struct ast_bridge_config config 
)
static

Definition at line 1202 of file app_dial.c.

References ast_bridge_config::answer_topology, ao2_bump, chanlist::aoc_s_rate_list, ast_aoc_decode(), ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), ast_aoc_encode(), ast_aoc_get_msg_type(), AST_AOC_S, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL_CLEARING, ast_cc_completed(), ast_cc_failed(), ast_cc_is_recall(), ast_channel_call_forward(), ast_channel_connected(), ast_channel_connected_line_macro(), ast_channel_connected_line_sub(), ast_channel_creationtime(), ast_channel_early_bridge(), ast_channel_exten_set(), ast_channel_hangupcause(), ast_channel_hangupcause_set(), ast_channel_lock, ast_channel_make_compatible(), ast_channel_name(), ast_channel_publish_dial(), ast_channel_redirecting_macro(), ast_channel_redirecting_sub(), ast_channel_sendhtml(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_unlock, ast_channel_update_connected_line(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag64, ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_flags64, ast_deactivate_generator(), ast_debug, ast_dtmf_stream(), AST_FEATURE_MAX_LEN, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_frfree, ast_handle_cc_control_frame(), ast_hangup(), ast_hangup_cause_to_dial_status(), ast_indicate(), ast_indicate_data(), AST_LIST_FIRST, AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_log, AST_MAX_WATCHERS, ast_mf_stream(), ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_set(), ast_party_connected_line_set_init(), ast_read(), ast_remaining_ms(), AST_STATE_UP, ast_str_alloca, ast_str_tmp, ast_strdup, ast_stream_topology_to_str(), ast_strlen_zero, ast_test_flag64, ast_trace, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_verb, ast_waitfor_n(), ast_write(), cause_args::busy, c, CAN_EARLY_BRIDGE, chanlist::chan, cause_args::congestion, chanlist::connected, context, ast_frame::data, ast_frame::datalen, detect_disconnect(), DIAL_CALLERID_ABSENT, DIAL_NOFORWARDHTML, DIAL_STILLGOING, do_forward(), ast_frame::frametype, handle_cause(), in, ast_frame_subclass::integer, LOG_ERROR, LOG_WARNING, ast_channel::name, cause_args::nochan, NULL, onedigit_goto(), OPT_ARG_RINGBACK, OPT_CALLEE_HANGUP, OPT_CALLEE_MIXMONITOR, OPT_CALLEE_MONITOR, OPT_CALLEE_PARK, OPT_CALLEE_TRANSFER, OPT_CALLER_HANGUP, OPT_CALLER_MIXMONITOR, OPT_CALLER_MONITOR, OPT_CALLER_PARK, OPT_CALLER_TRANSFER, OPT_DTMF_EXIT, OPT_IGNORE_CONNECTEDLINE, OPT_MUSICBACK, OPT_RINGBACK, chanlist::orig_chan_name, pbx_builtin_getvar_helper(), chanlist::pending_connected_update, ast_frame::ptr, publish_dial_end_event(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, privacy_args::sentringing, set_duration_var(), privacy_args::status, ast_frame::subclass, ast_frame_subclass::topology, ast_frame::uint32, and update_connected_line_from_peer().

Referenced by dial_exec_full().

1210 {
1211  struct cause_args num = *num_in;
1212  int prestart = num.busy + num.congestion + num.nochan;
1213  int orig = *to;
1214  struct ast_channel *peer = NULL;
1215  struct chanlist *outgoing = AST_LIST_FIRST(out_chans);
1216  /* single is set if only one destination is enabled */
1217  int single = outgoing && !AST_LIST_NEXT(outgoing, node);
1218  int caller_entertained = outgoing
1219  && ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
1220  struct ast_str *featurecode = ast_str_alloca(AST_FEATURE_MAX_LEN + 1);
1221  int cc_recall_core_id;
1222  int is_cc_recall;
1223  int cc_frame_received = 0;
1224  int num_ringing = 0;
1225  int sent_ring = 0;
1226  int sent_progress = 0;
1227  struct timeval start = ast_tvnow();
1228  SCOPE_ENTER(3, "%s\n", ast_channel_name(in));
1229 
1230  if (single) {
1231  /* Turn off hold music, etc */
1232  if (!caller_entertained) {
1234  /* If we are calling a single channel, and not providing ringback or music, */
1235  /* then, make them compatible for in-band tone purpose */
1236  if (ast_channel_make_compatible(in, outgoing->chan) < 0) {
1237  /* If these channels can not be made compatible,
1238  * there is no point in continuing. The bridge
1239  * will just fail if it gets that far.
1240  */
1241  *to = -1;
1242  strcpy(pa->status, "CONGESTION");
1243  ast_channel_publish_dial(in, outgoing->chan, NULL, pa->status);
1244  SCOPE_EXIT_RTN_VALUE(NULL, "%s: can't be made compat with %s\n",
1245  ast_channel_name(in), ast_channel_name(outgoing->chan));
1246  }
1247  }
1248 
1250  && !ast_test_flag64(outgoing, DIAL_CALLERID_ABSENT)) {
1251  update_connected_line_from_peer(in, outgoing->chan, 1);
1252  }
1253  }
1254 
1255  is_cc_recall = ast_cc_is_recall(in, &cc_recall_core_id, NULL);
1256 
1257  while ((*to = ast_remaining_ms(start, orig)) && !peer) {
1258  struct chanlist *o;
1259  int pos = 0; /* how many channels do we handle */
1260  int numlines = prestart;
1261  struct ast_channel *winner;
1262  struct ast_channel *watchers[AST_MAX_WATCHERS];
1263 
1264  watchers[pos++] = in;
1265  AST_LIST_TRAVERSE(out_chans, o, node) {
1266  /* Keep track of important channels */
1267  if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
1268  watchers[pos++] = o->chan;
1269  numlines++;
1270  }
1271  if (o && !o->chan) {
1272  ast_log(LOG_ERROR, "!!! Channel's gone\n");
1273  }
1274  ast_log(LOG_ERROR, "!!! Watcher pos: %d\n", pos);
1275  if (pos == 1) { /* only the input channel is available */
1276  if (numlines == (num.busy + num.congestion + num.nochan)) {
1277  ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1278  if (num.busy)
1279  strcpy(pa->status, "BUSY");
1280  else if (num.congestion)
1281  strcpy(pa->status, "CONGESTION");
1282  else if (num.nochan)
1283  strcpy(pa->status, "CHANUNAVAIL");
1284  } else {
1285  ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1286  }
1287  *to = 0;
1288  if (is_cc_recall) {
1289  ast_cc_failed(cc_recall_core_id, "Everyone is busy/congested for the recall. How sad");
1290  }
1291  SCOPE_EXIT_RTN_VALUE(NULL, "%s: No outging channels available\n", ast_channel_name(in));
1292  }
1293  winner = ast_waitfor_n(watchers, pos, to);
1294  AST_LIST_TRAVERSE(out_chans, o, node) {
1295  struct ast_frame *f;
1296  struct ast_channel *c = o->chan;
1297 
1298  if (c == NULL) {
1299  continue;
1300  }
1302  if (!peer) {
1303  ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1304  if (o->orig_chan_name
1305  && strcmp(o->orig_chan_name, ast_channel_name(c))) {
1306  /*
1307  * The channel name changed so we must generate COLP update.
1308  * Likely because a call pickup channel masqueraded in.
1309  */
1311  } else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1312  if (o->pending_connected_update) {
1313  if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
1314  ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
1316  }
1317  } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1319  }
1320  }
1321  if (o->aoc_s_rate_list) {
1322  size_t encoded_size;
1323  struct ast_aoc_encoded *encoded;
1324  if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1325  ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1326  ast_aoc_destroy_encoded(encoded);
1327  }
1328  }
1329  peer = c;
1330  publish_dial_end_event(in, out_chans, peer, "CANCEL");
1331  ast_copy_flags64(peerflags, o,
1338  ast_channel_dialcontext_set(c, "");
1339  ast_channel_exten_set(c, "");
1340  }
1341  continue;
1342  }
1343  if (c != winner) {
1344  ast_log(LOG_WARNING, "And C2: %s\n", ast_channel_name(c));
1345  continue;
1346  }
1347  /* here, o->chan == c == winner */
1349  pa->sentringing = 0;
1350  if (!ignore_cc && (f = ast_read(c))) {
1352  /* This channel is forwarding the call, and is capable of CC, so
1353  * be sure to add the new device interface to the list
1354  */
1356  }
1357  ast_frfree(f);
1358  }
1359 
1360  if (o->pending_connected_update) {
1361  /*
1362  * Re-seed the chanlist's connected line information with
1363  * previously acquired connected line info from the incoming
1364  * channel. The previously acquired connected line info could
1365  * have been set through the CONNECTED_LINE dialplan function.
1366  */
1367  o->pending_connected_update = 0;
1368  ast_channel_lock(in);
1370  ast_channel_unlock(in);
1371  }
1372 
1373  do_forward(o, &num, peerflags, single, caller_entertained, &orig,
1374  forced_clid, stored_clid);
1375 
1376  if (o->chan) {
1379  if (single
1383  }
1384  }
1385  continue;
1386  }
1387  ast_log(LOG_WARNING, "Let's go read a frame !!!\n");
1388  f = ast_read(winner);
1389  if (!f) {
1390  ast_log(LOG_WARNING, "!!! NULL - no frame!\n");
1393  ast_hangup(c);
1394  c = o->chan = NULL;
1397  continue;
1398  } else {
1399  ast_log(LOG_WARNING, "Frame: %d\n", f->subclass.integer);
1400  }
1401  switch (f->frametype) {
1402  case AST_FRAME_CONTROL:
1403  switch (f->subclass.integer) {
1404  case AST_CONTROL_ANSWER:
1405  /* This is our guy if someone answered. */
1406  if (!peer) {
1407  ast_trace(-1, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1408  ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1409  if (o->orig_chan_name
1410  && strcmp(o->orig_chan_name, ast_channel_name(c))) {
1411  /*
1412  * The channel name changed so we must generate COLP update.
1413  * Likely because a call pickup channel masqueraded in.
1414  */
1416  } else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1417  if (o->pending_connected_update) {
1418  if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
1419  ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
1421  }
1422  } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1424  }
1425  }
1426  if (o->aoc_s_rate_list) {
1427  size_t encoded_size;
1428  struct ast_aoc_encoded *encoded;
1429  if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1430  ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1431  ast_aoc_destroy_encoded(encoded);
1432  }
1433  }
1434  peer = c;
1435  /* Answer can optionally include a topology */
1436  if (f->subclass.topology) {
1437  /*
1438  * We need to bump the refcount on the topology to prevent it
1439  * from being cleaned up when the frame is cleaned up.
1440  */
1441  config->answer_topology = ao2_bump(f->subclass.topology);
1442  ast_trace(-1, "%s Found topology in frame: %p %p %s\n",
1443  ast_channel_name(peer), f, config->answer_topology,
1444  ast_str_tmp(256, ast_stream_topology_to_str(config->answer_topology, &STR_TMP)));
1445  }
1446 
1447  /* Inform everyone else that they've been canceled.
1448  * The dial end event for the peer will be sent out after
1449  * other Dial options have been handled.
1450  */
1451  publish_dial_end_event(in, out_chans, peer, "CANCEL");
1452  ast_copy_flags64(peerflags, o,
1459  ast_channel_dialcontext_set(c, "");
1460  ast_channel_exten_set(c, "");
1461  if (CAN_EARLY_BRIDGE(peerflags, in, peer)) {
1462  /* Setup early bridge if appropriate */
1463  ast_channel_early_bridge(in, peer);
1464  }
1465  }
1466  /* If call has been answered, then the eventual hangup is likely to be normal hangup */
1469  break;
1470  case AST_CONTROL_BUSY:
1471  ast_verb(3, "%s is busy\n", ast_channel_name(c));
1473  ast_channel_publish_dial(in, c, NULL, "BUSY");
1474  ast_hangup(c);
1475  c = o->chan = NULL;
1478  break;
1480  ast_verb(3, "%s is circuit-busy\n", ast_channel_name(c));
1482  ast_channel_publish_dial(in, c, NULL, "CONGESTION");
1483  ast_hangup(c);
1484  c = o->chan = NULL;
1487  break;
1488  case AST_CONTROL_RINGING:
1489  /* This is a tricky area to get right when using a native
1490  * CC agent. The reason is that we do the best we can to send only a
1491  * single ringing notification to the caller.
1492  *
1493  * Call completion complicates the logic used here. CCNR is typically
1494  * offered during a ringing message. Let's say that party A calls
1495  * parties B, C, and D. B and C do not support CC requests, but D
1496  * does. If we were to receive a ringing notification from B before
1497  * the others, then we would end up sending a ringing message to
1498  * A with no CCNR offer present.
1499  *
1500  * The approach that we have taken is that if we receive a ringing
1501  * response from a party and no CCNR offer is present, we need to
1502  * wait. Specifically, we need to wait until either a) a called party
1503  * offers CCNR in its ringing response or b) all called parties have
1504  * responded in some way to our call and none offers CCNR.
1505  *
1506  * The drawback to this is that if one of the parties has a delayed
1507  * response or, god forbid, one just plain doesn't respond to our
1508  * outgoing call, then this will result in a significant delay between
1509  * when the caller places the call and hears ringback.
1510  *
1511  * Note also that if CC is disabled for this call, then it is perfectly
1512  * fine for ringing frames to get sent through.
1513  */
1514  ++num_ringing;
1515  if (ignore_cc || cc_frame_received || num_ringing == numlines) {
1516  ast_verb(3, "%s is ringing\n", ast_channel_name(c));
1517  /* Setup early media if appropriate */
1518  if (single && !caller_entertained
1519  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1520  ast_channel_early_bridge(in, c);
1521  }
1522  if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK) && ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
1524  pa->sentringing++;
1525  }
1526  if (!sent_ring) {
1527  struct timeval now, then;
1528  int64_t diff;
1529 
1530  now = ast_tvnow();
1531 
1532  ast_channel_lock(in);
1534 
1535  then = ast_channel_creationtime(c);
1536  diff = ast_tvzero(then) ? 0 : ast_tvdiff_ms(now, then);
1537  set_duration_var(in, "RINGTIME", diff);
1538 
1540  ast_channel_unlock(in);
1541  sent_ring = 1;
1542  }
1543  }
1544  ast_channel_publish_dial(in, c, NULL, "RINGING");
1545  break;
1546  case AST_CONTROL_PROGRESS:
1547  ast_verb(3, "%s is making progress passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1548  /* Setup early media if appropriate */
1549  if (single && !caller_entertained
1550  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1551  ast_channel_early_bridge(in, c);
1552  }
1553  if (!ast_test_flag64(outgoing, OPT_RINGBACK)) {
1554  if (single || (!single && !pa->sentringing)) {
1556  }
1557  }
1558  if (!sent_progress) {
1559  struct timeval now, then;
1560  int64_t diff;
1561 
1562  now = ast_tvnow();
1563 
1564  ast_channel_lock(in);
1566 
1567  then = ast_channel_creationtime(c);
1568  diff = ast_tvzero(then) ? 0 : ast_tvdiff_ms(now, then);
1569  set_duration_var(in, "PROGRESSTIME", diff);
1570 
1572  ast_channel_unlock(in);
1573  sent_progress = 1;
1574 
1575  if (!ast_strlen_zero(mf_progress)) {
1576  ast_verb(3,
1577  "Sending MF '%s' to the called party as result of "
1578  "receiving a PROGRESS message.\n",
1579  mf_progress);
1580  ast_mf_stream(c, in, mf_progress, 50, 55, 120, 65, 0);
1581  }
1582  if (!ast_strlen_zero(dtmf_progress)) {
1583  ast_verb(3,
1584  "Sending DTMF '%s' to the called party as result of "
1585  "receiving a PROGRESS message.\n",
1586  dtmf_progress);
1587  ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
1588  }
1589  }
1590  ast_channel_publish_dial(in, c, NULL, "PROGRESS");
1591  break;
1592  case AST_CONTROL_VIDUPDATE:
1593  case AST_CONTROL_SRCUPDATE:
1594  case AST_CONTROL_SRCCHANGE:
1595  if (!single || caller_entertained) {
1596  break;
1597  }
1598  ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1600  ast_indicate(in, f->subclass.integer);
1601  break;
1604  ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(in));
1605  break;
1606  }
1607  if (!single) {
1609 
1610  ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n",
1616  o->pending_connected_update = 1;
1617  break;
1618  }
1619  if (ast_channel_connected_line_sub(c, in, f, 1) &&
1620  ast_channel_connected_line_macro(c, in, f, 1, 1)) {
1622  }
1623  break;
1624  case AST_CONTROL_AOC:
1625  {
1626  struct ast_aoc_decoded *decoded = ast_aoc_decode(f->data.ptr, f->datalen, o->chan);
1627  if (decoded && (ast_aoc_get_msg_type(decoded) == AST_AOC_S)) {
1629  o->aoc_s_rate_list = decoded;
1630  } else {
1631  ast_aoc_destroy_decoded(decoded);
1632  }
1633  }
1634  break;
1636  if (!single) {
1637  /*
1638  * Redirecting updates to the caller make sense only on single
1639  * calls.
1640  */
1641  break;
1642  }
1644  ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(in));
1645  break;
1646  }
1647  ast_verb(3, "%s redirecting info has changed, passing it to %s\n",
1649  if (ast_channel_redirecting_sub(c, in, f, 1) &&
1650  ast_channel_redirecting_macro(c, in, f, 1, 1)) {
1652  }
1653  pa->sentringing = 0;
1654  break;
1656  ast_verb(3, "%s is proceeding passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1657  if (single && !caller_entertained
1658  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1659  ast_channel_early_bridge(in, c);
1660  }
1661  if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1663  ast_channel_publish_dial(in, c, NULL, "PROCEEDING");
1664  break;
1665  case AST_CONTROL_HOLD:
1666  /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1667  ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(c));
1669  break;
1670  case AST_CONTROL_UNHOLD:
1671  /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1672  ast_verb(3, "Call on %s left from hold\n", ast_channel_name(c));
1674  break;
1675  case AST_CONTROL_OFFHOOK:
1676  case AST_CONTROL_FLASH:
1677  /* Ignore going off hook and flash */
1678  break;
1679  case AST_CONTROL_CC:
1680  if (!ignore_cc) {
1682  cc_frame_received = 1;
1683  }
1684  break;
1687  break;
1688  case -1:
1689  if (single && !caller_entertained) {
1690  ast_verb(3, "%s stopped sounds\n", ast_channel_name(c));
1691  ast_indicate(in, -1);
1692  pa->sentringing = 0;
1693  }
1694  break;
1695  default:
1696  ast_debug(1, "Dunno what to do with control type %d\n", f->subclass.integer);
1697  break;
1698  }
1699  break;
1700  case AST_FRAME_VIDEO:
1701  case AST_FRAME_VOICE:
1702  case AST_FRAME_IMAGE:
1703  if (caller_entertained) {
1704  break;
1705  }
1706  /* Fall through */
1707  case AST_FRAME_TEXT:
1708  if (single && ast_write(in, f)) {
1709  ast_log(LOG_WARNING, "Unable to write frametype: %u\n",
1710  f->frametype);
1711  }
1712  break;
1713  case AST_FRAME_HTML:
1714  if (single && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML)
1715  && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1716  ast_log(LOG_WARNING, "Unable to send URL\n");
1717  }
1718  break;
1719  default:
1720  break;
1721  }
1722  ast_frfree(f);
1723  } /* end for */
1724  if (winner == in) {
1725  struct ast_frame *f = ast_read(in);
1726 #if 0
1727  if (f && (f->frametype != AST_FRAME_VOICE))
1728  printf("Frame type: %d, %d\n", f->frametype, f->subclass);
1729  else if (!f || (f->frametype != AST_FRAME_VOICE))
1730  printf("Hangup received on %s\n", in->name);
1731 #endif
1732  if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP))) {
1733  /* Got hung up */
1734  *to = -1;
1735  strcpy(pa->status, "CANCEL");
1736  publish_dial_end_event(in, out_chans, NULL, pa->status);
1737  if (f) {
1738  if (f->data.uint32) {
1740  }
1741  ast_frfree(f);
1742  }
1743  if (is_cc_recall) {
1744  ast_cc_completed(in, "CC completed, although the caller hung up (cancelled)");
1745  }
1746  SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller hung up\n", ast_channel_name(in));
1747  }
1748 
1749  /* now f is guaranteed non-NULL */
1750 
1751  if (f->frametype == AST_FRAME_DTMF) {
1752  if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
1753  const char *context;
1754  ast_channel_lock(in);
1755  context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
1756  if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
1757  ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
1758  *to = 0;
1759  *result = f->subclass.integer;
1760  strcpy(pa->status, "CANCEL");
1761  publish_dial_end_event(in, out_chans, NULL, pa->status);
1762  ast_frfree(f);
1763  ast_channel_unlock(in);
1764  if (is_cc_recall) {
1765  ast_cc_completed(in, "CC completed, but the caller used DTMF to exit");
1766  }
1767  SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller pressed %c to end call\n",
1769  }
1770  ast_channel_unlock(in);
1771  }
1772 
1773  if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
1774  detect_disconnect(in, f->subclass.integer, &featurecode)) {
1775  ast_verb(3, "User requested call disconnect.\n");
1776  *to = 0;
1777  strcpy(pa->status, "CANCEL");
1778  publish_dial_end_event(in, out_chans, NULL, pa->status);
1779  ast_frfree(f);
1780  if (is_cc_recall) {
1781  ast_cc_completed(in, "CC completed, but the caller hung up with DTMF");
1782  }
1783  SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller requested disconnect\n",
1784  ast_channel_name(in));
1785  }
1786  }
1787 
1788  /* Send the frame from the in channel to all outgoing channels. */
1789  AST_LIST_TRAVERSE(out_chans, o, node) {
1790  if (!o->chan || !ast_test_flag64(o, DIAL_STILLGOING)) {
1791  /* This outgoing channel has died so don't send the frame to it. */
1792  continue;
1793  }
1794  if (ast_check_hangup_locked(o->chan)) {
1795  ast_log(LOG_WARNING, "!!! Should be dead, but we're not?\n");
1796  continue;
1797  }
1798  switch (f->frametype) {
1799  case AST_FRAME_HTML:
1800  /* Forward HTML stuff */
1802  && ast_channel_sendhtml(o->chan, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1803  ast_log(LOG_WARNING, "Unable to send URL\n");
1804  }
1805  break;
1806  case AST_FRAME_VIDEO:
1807  case AST_FRAME_VOICE:
1808  case AST_FRAME_IMAGE:
1809  if (!single || caller_entertained) {
1810  /*
1811  * We are calling multiple parties or caller is being
1812  * entertained and has thus not been made compatible.
1813  * No need to check any other called parties.
1814  */
1815  goto skip_frame;
1816  }
1817  /* Fall through */
1818  case AST_FRAME_TEXT:
1819  case AST_FRAME_DTMF_BEGIN:
1820  case AST_FRAME_DTMF_END:
1821  if (ast_write(o->chan, f)) {
1822  ast_log(LOG_WARNING, "Unable to forward frametype: %u\n",
1823  f->frametype);
1824  }
1825  break;
1826  case AST_FRAME_CONTROL:
1827  switch (f->subclass.integer) {
1828  case AST_CONTROL_HOLD:
1829  ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(o->chan));
1831  break;
1832  case AST_CONTROL_UNHOLD:
1833  ast_verb(3, "Call on %s left from hold\n", ast_channel_name(o->chan));
1835  break;
1836  case AST_CONTROL_VIDUPDATE:
1837  case AST_CONTROL_SRCUPDATE:
1838  case AST_CONTROL_SRCCHANGE:
1839  if (!single || caller_entertained) {
1840  /*
1841  * We are calling multiple parties or caller is being
1842  * entertained and has thus not been made compatible.
1843  * No need to check any other called parties.
1844  */
1845  goto skip_frame;
1846  }
1847  ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1850  break;
1853  ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(o->chan));
1854  break;
1855  }
1856  if (ast_channel_connected_line_sub(in, o->chan, f, 1) &&
1857  ast_channel_connected_line_macro(in, o->chan, f, 0, 1)) {
1859  }
1860  break;
1863  ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(o->chan));
1864  break;
1865  }
1866  if (ast_channel_redirecting_sub(in, o->chan, f, 1) &&
1867  ast_channel_redirecting_macro(in, o->chan, f, 0, 1)) {
1869  }
1870  break;
1871  default:
1872  /* We are not going to do anything with this frame. */
1873  goto skip_frame;
1874  }
1875  break;
1876  default:
1877  /* We are not going to do anything with this frame. */
1878  goto skip_frame;
1879  }
1880  }
1881 skip_frame:;
1882  ast_frfree(f);
1883  }
1884  }
1885 
1886  if (!*to || ast_check_hangup(in)) {
1887  ast_verb(3, "Nobody picked up in %d ms\n", orig);
1888  publish_dial_end_event(in, out_chans, NULL, "NOANSWER");
1889  }
1890 
1891  if (is_cc_recall) {
1892  ast_cc_completed(in, "Recall completed!");
1893  }
1894  SCOPE_EXIT_RTN_VALUE(peer, "%s: %s%s\n", ast_channel_name(in),
1895  peer ? "Answered by " : "No answer", peer ? ast_channel_name(peer) : "");
1896 }
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
Definition: main/app.c:981
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
Definition: channel.c:3166
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode)
Definition: app_dial.c:1898
int sentringing
Definition: app_dial.c:1139
int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
Bridge two channels together (early)
Definition: channel.c:7512
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
Definition: test_heap.c:38
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame)
Run a connected line interception macro and update a channel&#39;s connected line information.
Definition: channel.c:10435
#define ast_copy_flags64(dest, src, flagz)
Definition: utils.h:141
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
Definition: app_dial.c:881
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
Definition: ccss.c:3879
unsigned int pending_connected_update
Definition: app_dial.c:811
struct ast_stream_topology * answer_topology
Definition: channel.h:1100
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation...
Definition: channel.c:2045
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int congestion
Definition: app_dial.c:855
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
#define LOG_WARNING
Definition: logger.h:274
#define AST_MAX_WATCHERS
Definition: app_dial.c:847
void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Indicate that the connected line information has changed.
Definition: channel.c:9189
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
#define ast_trace(level,...)
Print a basic trace message.
Definition: logger.h:692
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4698
#define DIAL_STILLGOING
Definition: app_dial.c:701
const char * ast_hangup_cause_to_dial_status(int hangup_cause)
Convert a hangup cause to a publishable dial status.
Definition: dial.c:753
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
static struct test_val c
#define ast_str_alloca(init_len)
Definition: strings.h:800
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2072
#define NULL
Definition: resample.c:96
#define AST_FRAME_DTMF
const char * ast_channel_call_forward(const struct ast_channel *chan)
#define ast_verb(level,...)
Definition: logger.h:463
int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char *const monitor_type)
Decide if a call to a particular channel is a CC recall.
Definition: ccss.c:3438
void ast_handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
Properly react to a CC control frame.
Definition: ccss.c:2316
static void handle_cause(int cause, struct cause_args *num)
Definition: app_dial.c:859
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
#define CAN_EARLY_BRIDGE(flags, chan, peer)
Definition: app_dial.c:786
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_cc_completed(struct ast_channel *chan, const char *const debug,...)
Indicate recall has been acknowledged.
Definition: ccss.c:3842
#define DIAL_CALLERID_ABSENT
Definition: app_dial.c:703
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Definition: channel.c:6817
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
Definition: aoc.c:449
FILE * in
Definition: utils/frame.c:33
struct ast_channel * chan
Definition: app_dial.c:798
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
Definition: aoc.c:650
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
Run a redirecting interception subroutine and update a channel&#39;s redirecting information.
Definition: channel.c:10584
List of channel drivers.
Definition: app_dial.c:796
#define DIAL_NOFORWARDHTML
Definition: app_dial.c:702
int nochan
Definition: app_dial.c:856
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
struct ast_party_connected_line connected
Definition: app_dial.c:809
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
Parse connected line indication frame data.
Definition: channel.c:8881
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: main/utils.c:2033
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel&#39;s connected line information...
Definition: channel.c:10539
void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update)
Set the connected line information based on another connected line source.
Definition: channel.c:2054
int ast_mf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
Send a string of MF digits to a channel.
Definition: main/app.c:967
Connected Line/Party information.
Definition: channel.h:457
const ast_string_field name
struct timeval ast_channel_creationtime(struct ast_channel *chan)
int ast_channel_sendhtml(struct ast_channel *channel, int subclass, const char *data, int datalen)
Sends HTML on given channel Send HTML or URL on link.
Definition: channel.c:6725
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_free(a)
Definition: astmm.h:182
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:5189
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:313
static void set_duration_var(struct ast_channel *chan, const char *var_base, int64_t duration)
Definition: app_dial.c:1189
#define ast_clear_flag64(p, flag)
Definition: utils.h:134
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:2902
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
Definition: channel.c:2031
int busy
Definition: app_dial.c:854
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_frfree(fr)
static void publish_dial_end_event(struct ast_channel *in, struct dial_head *out_chans, struct ast_channel *exception, const char *status)
Definition: app_dial.c:1146
static PGresult * result
Definition: cel_pgsql.c:88
#define AST_FEATURE_MAX_LEN
#define AST_CAUSE_BUSY
Definition: causes.h:148
Data structure associated with a single frame of data.
Definition: aoc.h:64
enum ast_aoc_type ast_aoc_get_msg_type(struct ast_aoc_decoded *decoded)
get the message type, AOC-D, AOC-E, or AOC Request
Definition: aoc.c:892
static void do_forward(struct chanlist *o, struct cause_args *num, struct ast_flags64 *peerflags, int single, int caller_entertained, int *to, struct ast_party_id *forced_clid, struct ast_party_id *stored_clid)
Definition: app_dial.c:930
union ast_frame::@263 data
static void update_connected_line_from_peer(struct ast_channel *chan, struct ast_channel *peer, int is_caller)
Definition: app_dial.c:1168
enum ast_frame_type frametype
char status[256]
Definition: app_dial.c:1143
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_aoc_decoded * aoc_s_rate_list
Definition: app_dial.c:812
char connected
Definition: eagi_proxy.c:82
struct ast_stream_topology * topology
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
Run a redirecting interception macro and update a channel&#39;s redirecting information.
Definition: channel.c:10487
char * orig_chan_name
Definition: app_dial.c:806
#define ast_test_flag64(p, flag)
Definition: utils.h:120

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Dialing Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "ccss", }
static

Definition at line 3567 of file app_dial.c.

◆ app

const char app[] = "Dial"
static

Definition at line 663 of file app_dial.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 3567 of file app_dial.c.

◆ dial_exec_options

const struct ast_app_option dial_exec_options[128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'a' ] = { .flag = (1LLU << 40) }, [ 'b' ] = { .flag = (1LLU << 41) , .arg_index = OPT_ARG_PREDIAL_CALLEE + 1 }, [ 'B' ] = { .flag = (1LLU << 42) , .arg_index = OPT_ARG_PREDIAL_CALLER + 1 }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'c' ] = { .flag = (1LLU << 34) }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'e' ] = { .flag = (1LLU << 35) }, [ 'f' ] = { .flag = OPT_FORCECLID , .arg_index = OPT_ARG_FORCECLID + 1 }, [ 'F' ] = { .flag = (1LLU << 36) , .arg_index = OPT_ARG_CALLEE_GO_ON + 1 }, [ 'g' ] = { .flag = OPT_GO_ON }, [ 'G' ] = { .flag = OPT_GOTO , .arg_index = OPT_ARG_GOTO + 1 }, [ 'h' ] = { .flag = OPT_CALLEE_HANGUP }, [ 'H' ] = { .flag = OPT_CALLER_HANGUP }, [ 'i' ] = { .flag = OPT_IGNORE_FORWARDING }, [ 'I' ] = { .flag = OPT_IGNORE_CONNECTEDLINE }, [ 'k' ] = { .flag = OPT_CALLEE_PARK }, [ 'K' ] = { .flag = OPT_CALLER_PARK }, [ 'L' ] = { .flag = OPT_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, [ 'm' ] = { .flag = OPT_MUSICBACK , .arg_index = OPT_ARG_MUSICBACK + 1 }, [ 'M' ] = { .flag = OPT_CALLEE_MACRO , .arg_index = OPT_ARG_CALLEE_MACRO + 1 }, [ 'n' ] = { .flag = OPT_SCREEN_NOINTRO , .arg_index = OPT_ARG_SCREEN_NOINTRO + 1 }, [ 'N' ] = { .flag = OPT_SCREEN_NOCALLERID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID , .arg_index = OPT_ARG_ORIGINAL_CLID + 1 }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'Q' ] = { .flag = (1LLU << 44) , .arg_index = OPT_ARG_HANGUPCAUSE + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK , .arg_index = OPT_ARG_RINGBACK + 1 }, [ 'R' ] = { .flag = (1LLU << 43) }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 's' ] = { .flag = (1LLU << 38) , .arg_index = OPT_ARG_FORCE_CID_TAG + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'u' ] = { .flag = (1LLU << 39) , .arg_index = OPT_ARG_FORCE_CID_PRES + 1 }, [ 'U' ] = { .flag = OPT_CALLEE_GOSUB , .arg_index = OPT_ARG_CALLEE_GOSUB + 1 }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR }, [ 'x' ] = { .flag = OPT_CALLEE_MIXMONITOR }, [ 'X' ] = { .flag = OPT_CALLER_MIXMONITOR }, [ 'z' ] = { .flag = (1LLU << 37) }, }
static

Definition at line 784 of file app_dial.c.

Referenced by dial_exec_full().

◆ rapp

const char rapp[] = "RetryDial"
static

Definition at line 664 of file app_dial.c.

Referenced by load_module(), retrydial_exec(), and unload_module().