Asterisk - The Open Source Telephony Project  GIT-master-a24979a
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_HEARPULSING   (1LLU << 45)
 
#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, char *mf_wink, char *sf_progress, char *sf_wink, const int hearpulsing, 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 = AST_BUILDOPT_SUM, .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 << 45) }, [ '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 886 of file app_dial.c.

◆ CAN_EARLY_BRIDGE

#define CAN_EARLY_BRIDGE (   flags,
  chan,
  peer 
)

Definition at line 825 of file app_dial.c.

◆ DIAL_CALLERID_ABSENT

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

Definition at line 740 of file app_dial.c.

◆ DIAL_NOFORWARDHTML

#define DIAL_NOFORWARDHTML   (1LLU << 32)

Definition at line 739 of file app_dial.c.

◆ DIAL_STILLGOING

#define DIAL_STILLGOING   (1LLU << 31)

Definition at line 738 of file app_dial.c.

◆ OPT_CALLEE_GO_ON

#define OPT_CALLEE_GO_ON   (1LLU << 36)

Definition at line 743 of file app_dial.c.

◆ OPT_CALLER_ANSWER

#define OPT_CALLER_ANSWER   (1LLU << 40)

Definition at line 747 of file app_dial.c.

◆ OPT_CANCEL_ELSEWHERE

#define OPT_CANCEL_ELSEWHERE   (1LLU << 34)

Definition at line 741 of file app_dial.c.

◆ OPT_CANCEL_TIMEOUT

#define OPT_CANCEL_TIMEOUT   (1LLU << 37)

Definition at line 744 of file app_dial.c.

◆ OPT_FORCE_CID_PRES

#define OPT_FORCE_CID_PRES   (1LLU << 39)

Definition at line 746 of file app_dial.c.

◆ OPT_FORCE_CID_TAG

#define OPT_FORCE_CID_TAG   (1LLU << 38)

Definition at line 745 of file app_dial.c.

◆ OPT_HANGUPCAUSE

#define OPT_HANGUPCAUSE   (1LLU << 44)

Definition at line 751 of file app_dial.c.

◆ OPT_HEARPULSING

#define OPT_HEARPULSING   (1LLU << 45)

Definition at line 752 of file app_dial.c.

◆ OPT_PEER_H

#define OPT_PEER_H   (1LLU << 35)

Definition at line 742 of file app_dial.c.

◆ OPT_PREDIAL_CALLEE

#define OPT_PREDIAL_CALLEE   (1LLU << 41)

Definition at line 748 of file app_dial.c.

◆ OPT_PREDIAL_CALLER

#define OPT_PREDIAL_CALLER   (1LLU << 42)

Definition at line 749 of file app_dial.c.

◆ OPT_RING_WITH_EARLY_MEDIA

#define OPT_RING_WITH_EARLY_MEDIA   (1LLU << 43)

Definition at line 750 of file app_dial.c.

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 703 of file app_dial.c.

703  {
704  OPT_ANNOUNCE = (1 << 0),
705  OPT_RESETCDR = (1 << 1),
706  OPT_DTMF_EXIT = (1 << 2),
707  OPT_SENDDTMF = (1 << 3),
708  OPT_FORCECLID = (1 << 4),
709  OPT_GO_ON = (1 << 5),
710  OPT_CALLEE_HANGUP = (1 << 6),
711  OPT_CALLER_HANGUP = (1 << 7),
712  OPT_ORIGINAL_CLID = (1 << 8),
713  OPT_DURATION_LIMIT = (1 << 9),
714  OPT_MUSICBACK = (1 << 10),
715  OPT_CALLEE_MACRO = (1 << 11),
716  OPT_SCREEN_NOINTRO = (1 << 12),
717  OPT_SCREEN_NOCALLERID = (1 << 13),
718  OPT_IGNORE_CONNECTEDLINE = (1 << 14),
719  OPT_SCREENING = (1 << 15),
720  OPT_PRIVACY = (1 << 16),
721  OPT_RINGBACK = (1 << 17),
722  OPT_DURATION_STOP = (1 << 18),
723  OPT_CALLEE_TRANSFER = (1 << 19),
724  OPT_CALLER_TRANSFER = (1 << 20),
725  OPT_CALLEE_MONITOR = (1 << 21),
726  OPT_CALLER_MONITOR = (1 << 22),
727  OPT_GOTO = (1 << 23),
728  OPT_OPERMODE = (1 << 24),
729  OPT_CALLEE_PARK = (1 << 25),
730  OPT_CALLER_PARK = (1 << 26),
731  OPT_IGNORE_FORWARDING = (1 << 27),
732  OPT_CALLEE_GOSUB = (1 << 28),
733  OPT_CALLEE_MIXMONITOR = (1 << 29),
734  OPT_CALLER_MIXMONITOR = (1 << 30),
735 };
@ OPT_RESETCDR
Definition: app_dial.c:705
@ OPT_SCREEN_NOINTRO
Definition: app_dial.c:716
@ OPT_DTMF_EXIT
Definition: app_dial.c:706
@ OPT_ANNOUNCE
Definition: app_dial.c:704
@ OPT_CALLEE_PARK
Definition: app_dial.c:729
@ OPT_DURATION_LIMIT
Definition: app_dial.c:713
@ OPT_SCREEN_NOCALLERID
Definition: app_dial.c:717
@ OPT_IGNORE_FORWARDING
Definition: app_dial.c:731
@ OPT_OPERMODE
Definition: app_dial.c:728
@ OPT_DURATION_STOP
Definition: app_dial.c:722
@ OPT_GO_ON
Definition: app_dial.c:709
@ OPT_CALLEE_MACRO
Definition: app_dial.c:715
@ OPT_RINGBACK
Definition: app_dial.c:721
@ OPT_GOTO
Definition: app_dial.c:727
@ OPT_IGNORE_CONNECTEDLINE
Definition: app_dial.c:718
@ OPT_CALLEE_TRANSFER
Definition: app_dial.c:723
@ OPT_SENDDTMF
Definition: app_dial.c:707
@ OPT_CALLER_MIXMONITOR
Definition: app_dial.c:734
@ OPT_CALLER_PARK
Definition: app_dial.c:730
@ OPT_CALLER_MONITOR
Definition: app_dial.c:726
@ OPT_CALLEE_MONITOR
Definition: app_dial.c:725
@ OPT_CALLEE_GOSUB
Definition: app_dial.c:732
@ OPT_CALLER_HANGUP
Definition: app_dial.c:711
@ OPT_FORCECLID
Definition: app_dial.c:708
@ OPT_CALLEE_HANGUP
Definition: app_dial.c:710
@ OPT_SCREENING
Definition: app_dial.c:719
@ OPT_MUSICBACK
Definition: app_dial.c:714
@ OPT_CALLER_TRANSFER
Definition: app_dial.c:724
@ OPT_CALLEE_MIXMONITOR
Definition: app_dial.c:733
@ OPT_ORIGINAL_CLID
Definition: app_dial.c:712
@ OPT_PRIVACY
Definition: app_dial.c:720

◆ 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 754 of file app_dial.c.

754  {
755  OPT_ARG_ANNOUNCE = 0,
757  OPT_ARG_GOTO,
775  /* note: this entry _MUST_ be the last one in the enum */
777 };
@ OPT_ARG_CALLEE_GO_ON
Definition: app_dial.c:763
@ OPT_ARG_SENDDTMF
Definition: app_dial.c:756
@ OPT_ARG_CALLEE_MACRO
Definition: app_dial.c:760
@ OPT_ARG_DURATION_STOP
Definition: app_dial.c:765
@ OPT_ARG_PREDIAL_CALLEE
Definition: app_dial.c:772
@ OPT_ARG_RINGBACK
Definition: app_dial.c:761
@ OPT_ARG_MUSICBACK
Definition: app_dial.c:759
@ OPT_ARG_CALLEE_GOSUB
Definition: app_dial.c:762
@ OPT_ARG_HANGUPCAUSE
Definition: app_dial.c:774
@ OPT_ARG_FORCE_CID_PRES
Definition: app_dial.c:771
@ OPT_ARG_ANNOUNCE
Definition: app_dial.c:755
@ OPT_ARG_GOTO
Definition: app_dial.c:757
@ OPT_ARG_DURATION_LIMIT
Definition: app_dial.c:758
@ OPT_ARG_ORIGINAL_CLID
Definition: app_dial.c:768
@ OPT_ARG_OPERMODE
Definition: app_dial.c:766
@ OPT_ARG_FORCECLID
Definition: app_dial.c:769
@ OPT_ARG_PREDIAL_CALLER
Definition: app_dial.c:773
@ OPT_ARG_ARRAY_SIZE
Definition: app_dial.c:776
@ OPT_ARG_PRIVACY
Definition: app_dial.c:764
@ OPT_ARG_SCREEN_NOINTRO
Definition: app_dial.c:767
@ OPT_ARG_FORCE_CID_TAG
Definition: app_dial.c:770

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 3644 of file app_dial.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3644 of file app_dial.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 3644 of file app_dial.c.

◆ chanlist_free()

static void chanlist_free ( struct chanlist outgoing)
static

Definition at line 860 of file app_dial.c.

861 {
863  ast_aoc_destroy_decoded(outgoing->aoc_s_rate_list);
864  ast_free(outgoing->orig_chan_name);
866 }
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
#define ast_free(a)
Definition: astmm.h:180
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2066

References ast_aoc_destroy_decoded(), ast_free, and ast_party_connected_line_free().

Referenced by dial_exec_full(), and hanguptree().

◆ detect_disconnect()

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

Definition at line 1958 of file app_dial.c.

1959 {
1960  char disconnect_code[AST_FEATURE_MAX_LEN];
1961  int res;
1962 
1963  ast_str_append(featurecode, 1, "%c", code);
1964 
1965  res = ast_get_builtin_feature(chan, "disconnect", disconnect_code, sizeof(disconnect_code));
1966  if (res) {
1967  ast_str_reset(*featurecode);
1968  return 0;
1969  }
1970 
1971  if (strlen(disconnect_code) > ast_str_strlen(*featurecode)) {
1972  /* Could be a partial match, anyway */
1973  if (strncmp(disconnect_code, ast_str_buffer(*featurecode), ast_str_strlen(*featurecode))) {
1974  ast_str_reset(*featurecode);
1975  }
1976  return 0;
1977  }
1978 
1979  if (strcmp(disconnect_code, ast_str_buffer(*featurecode))) {
1980  ast_str_reset(*featurecode);
1981  return 0;
1982  }
1983 
1984  return 1;
1985 }
#define AST_FEATURE_MAX_LEN
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.
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:1117
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:739
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:674
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:711

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().

◆ dial_exec()

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

Definition at line 3502 of file app_dial.c.

3503 {
3504  struct ast_flags64 peerflags;
3505 
3506  memset(&peerflags, 0, sizeof(peerflags));
3507 
3508  return dial_exec_full(chan, data, &peerflags, NULL);
3509 }
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
Definition: app_dial.c:2312
#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

References dial_exec_full(), and NULL.

◆ 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 2312 of file app_dial.c.

2313 {
2314  int res = -1; /* default: error */
2315  char *rest, *cur; /* scan the list of destinations */
2316  struct dial_head out_chans = AST_LIST_HEAD_NOLOCK_INIT_VALUE; /* list of destinations */
2317  struct chanlist *outgoing;
2318  struct chanlist *tmp;
2319  struct ast_channel *peer = NULL;
2320  int to; /* timeout */
2321  struct cause_args num = { chan, 0, 0, 0 };
2322  int cause, hanguptreecause = -1;
2323 
2324  struct ast_bridge_config config = { { 0, } };
2325  struct timeval calldurationlimit = { 0, };
2326  char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress = NULL;
2327  char *mf_progress = NULL, *mf_wink = NULL;
2328  char *sf_progress = NULL, *sf_wink = NULL;
2329  struct privacy_args pa = {
2330  .sentringing = 0,
2331  .privdb_val = 0,
2332  .status = "INVALIDARGS",
2333  .canceled = 0,
2334  };
2335  int sentringing = 0, moh = 0;
2336  const char *outbound_group = NULL;
2337  int result = 0;
2338  char *parse;
2339  int opermode = 0;
2340  int delprivintro = 0;
2342  AST_APP_ARG(peers);
2343  AST_APP_ARG(timeout);
2345  AST_APP_ARG(url);
2346  );
2347  struct ast_flags64 opts = { 0, };
2348  char *opt_args[OPT_ARG_ARRAY_SIZE];
2349  int fulldial = 0, num_dialed = 0;
2350  int ignore_cc = 0;
2351  char device_name[AST_CHANNEL_NAME];
2352  char forced_clid_name[AST_MAX_EXTENSION];
2353  char stored_clid_name[AST_MAX_EXTENSION];
2354  int force_forwards_only; /*!< TRUE if force CallerID on call forward only. Legacy behaviour.*/
2355  /*!
2356  * \brief Forced CallerID party information to send.
2357  * \note This will not have any malloced strings so do not free it.
2358  */
2359  struct ast_party_id forced_clid;
2360  /*!
2361  * \brief Stored CallerID information if needed.
2362  *
2363  * \note If OPT_ORIGINAL_CLID set then this is the o option
2364  * CallerID. Otherwise it is the dialplan extension and hint
2365  * name.
2366  *
2367  * \note This will not have any malloced strings so do not free it.
2368  */
2369  struct ast_party_id stored_clid;
2370  /*!
2371  * \brief CallerID party information to store.
2372  * \note This will not have any malloced strings so do not free it.
2373  */
2374  struct ast_party_caller caller;
2375  int max_forwards;
2376  SCOPE_ENTER(1, "%s: Data: %s\n", ast_channel_name(chan), data);
2377 
2378  /* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
2379  ast_channel_lock(chan);
2381  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
2382  pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
2383  pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
2384  pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
2385  pbx_builtin_setvar_helper(chan, "ANSWEREDTIME_MS", "");
2386  pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
2387  pbx_builtin_setvar_helper(chan, "DIALEDTIME_MS", "");
2388  pbx_builtin_setvar_helper(chan, "RINGTIME", "");
2389  pbx_builtin_setvar_helper(chan, "RINGTIME_MS", "");
2390  pbx_builtin_setvar_helper(chan, "PROGRESSTIME", "");
2391  pbx_builtin_setvar_helper(chan, "PROGRESSTIME_MS", "");
2394  ast_channel_unlock(chan);
2395 
2396  if (max_forwards <= 0) {
2397  ast_log(LOG_WARNING, "Cannot place outbound call from channel '%s'. Max forwards exceeded\n",
2398  ast_channel_name(chan));
2399  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "BUSY");
2400  SCOPE_EXIT_RTN_VALUE(-1, "%s: Max forwards exceeded\n", ast_channel_name(chan));
2401  }
2402 
2403  if (ast_check_hangup_locked(chan)) {
2404  /*
2405  * Caller hung up before we could dial. If dial is executed
2406  * within an AGI then the AGI has likely eaten all queued
2407  * frames before executing the dial in DeadAGI mode. With
2408  * the caller hung up and no pending frames from the caller's
2409  * read queue, dial would not know that the call has hung up
2410  * until a called channel answers. It is rather annoying to
2411  * whoever just answered the non-existent call.
2412  *
2413  * Dial should not continue execution in DeadAGI mode, hangup
2414  * handlers, or the h exten.
2415  */
2416  ast_verb(3, "Caller hung up before dial.\n");
2417  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "CANCEL");
2418  SCOPE_EXIT_RTN_VALUE(-1, "%s: Caller hung up before dial\n", ast_channel_name(chan));
2419  }
2420 
2421  parse = ast_strdupa(data ?: "");
2422 
2424 
2425  if (!ast_strlen_zero(args.options) &&
2426  ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
2427  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2428  goto done;
2429  }
2430 
2431  if (ast_cc_call_init(chan, &ignore_cc)) {
2432  goto done;
2433  }
2434 
2436  delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
2437 
2438  if (delprivintro < 0 || delprivintro > 1) {
2439  ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
2440  delprivintro = 0;
2441  }
2442  }
2443 
2444  if (!ast_test_flag64(&opts, OPT_RINGBACK)) {
2445  opt_args[OPT_ARG_RINGBACK] = NULL;
2446  }
2447 
2448  if (ast_test_flag64(&opts, OPT_OPERMODE)) {
2449  opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
2450  ast_verb(3, "Setting operator services mode to %d.\n", opermode);
2451  }
2452 
2454  calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
2455  if (!calldurationlimit.tv_sec) {
2456  ast_log(LOG_WARNING, "Dial does not accept S(%s)\n", opt_args[OPT_ARG_DURATION_STOP]);
2457  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2458  goto done;
2459  }
2460  ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
2461  }
2462 
2463  if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
2464  sf_wink = opt_args[OPT_ARG_SENDDTMF];
2465  dtmfcalled = strsep(&sf_wink, ":");
2466  dtmfcalling = strsep(&sf_wink, ":");
2467  dtmf_progress = strsep(&sf_wink, ":");
2468  mf_progress = strsep(&sf_wink, ":");
2469  mf_wink = strsep(&sf_wink, ":");
2470  sf_progress = strsep(&sf_wink, ":");
2471  }
2472 
2474  if (ast_bridge_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
2475  goto done;
2476  }
2477 
2478  /* Setup the forced CallerID information to send if used. */
2479  ast_party_id_init(&forced_clid);
2480  force_forwards_only = 0;
2481  if (ast_test_flag64(&opts, OPT_FORCECLID)) {
2482  if (ast_strlen_zero(opt_args[OPT_ARG_FORCECLID])) {
2483  ast_channel_lock(chan);
2484  forced_clid.number.str = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
2485  ast_channel_unlock(chan);
2486  forced_clid_name[0] = '\0';
2487  forced_clid.name.str = (char *) get_cid_name(forced_clid_name,
2488  sizeof(forced_clid_name), chan);
2489  force_forwards_only = 1;
2490  } else {
2491  /* Note: The opt_args[OPT_ARG_FORCECLID] string value is altered here. */
2492  ast_callerid_parse(opt_args[OPT_ARG_FORCECLID], &forced_clid.name.str,
2493  &forced_clid.number.str);
2494  }
2495  if (!ast_strlen_zero(forced_clid.name.str)) {
2496  forced_clid.name.valid = 1;
2497  }
2498  if (!ast_strlen_zero(forced_clid.number.str)) {
2499  forced_clid.number.valid = 1;
2500  }
2501  }
2503  && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_TAG])) {
2504  forced_clid.tag = opt_args[OPT_ARG_FORCE_CID_TAG];
2505  }
2506  forced_clid.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
2508  && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_PRES])) {
2509  int pres;
2510 
2512  if (0 <= pres) {
2513  forced_clid.number.presentation = pres;
2514  }
2515  }
2516 
2517  /* Setup the stored CallerID information if needed. */
2518  ast_party_id_init(&stored_clid);
2519  if (ast_test_flag64(&opts, OPT_ORIGINAL_CLID)) {
2520  if (ast_strlen_zero(opt_args[OPT_ARG_ORIGINAL_CLID])) {
2521  ast_channel_lock(chan);
2522  ast_party_id_set_init(&stored_clid, &ast_channel_caller(chan)->id);
2523  if (!ast_strlen_zero(ast_channel_caller(chan)->id.name.str)) {
2524  stored_clid.name.str = ast_strdupa(ast_channel_caller(chan)->id.name.str);
2525  }
2526  if (!ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
2527  stored_clid.number.str = ast_strdupa(ast_channel_caller(chan)->id.number.str);
2528  }
2529  if (!ast_strlen_zero(ast_channel_caller(chan)->id.subaddress.str)) {
2530  stored_clid.subaddress.str = ast_strdupa(ast_channel_caller(chan)->id.subaddress.str);
2531  }
2532  if (!ast_strlen_zero(ast_channel_caller(chan)->id.tag)) {
2533  stored_clid.tag = ast_strdupa(ast_channel_caller(chan)->id.tag);
2534  }
2535  ast_channel_unlock(chan);
2536  } else {
2537  /* Note: The opt_args[OPT_ARG_ORIGINAL_CLID] string value is altered here. */
2538  ast_callerid_parse(opt_args[OPT_ARG_ORIGINAL_CLID], &stored_clid.name.str,
2539  &stored_clid.number.str);
2540  if (!ast_strlen_zero(stored_clid.name.str)) {
2541  stored_clid.name.valid = 1;
2542  }
2543  if (!ast_strlen_zero(stored_clid.number.str)) {
2544  stored_clid.number.valid = 1;
2545  }
2546  }
2547  } else {
2548  /*
2549  * In case the new channel has no preset CallerID number by the
2550  * channel driver, setup the dialplan extension and hint name.
2551  */
2552  stored_clid_name[0] = '\0';
2553  stored_clid.name.str = (char *) get_cid_name(stored_clid_name,
2554  sizeof(stored_clid_name), chan);
2555  if (ast_strlen_zero(stored_clid.name.str)) {
2556  stored_clid.name.str = NULL;
2557  } else {
2558  stored_clid.name.valid = 1;
2559  }
2560  ast_channel_lock(chan);
2561  stored_clid.number.str = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
2562  stored_clid.number.valid = 1;
2563  ast_channel_unlock(chan);
2564  }
2565 
2566  if (ast_test_flag64(&opts, OPT_RESETCDR)) {
2567  ast_cdr_reset(ast_channel_name(chan), 0);
2568  }
2569  if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
2570  opt_args[OPT_ARG_PRIVACY] = ast_strdupa(ast_channel_exten(chan));
2571 
2572  if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
2573  res = setup_privacy_args(&pa, &opts, opt_args, chan);
2574  if (res <= 0)
2575  goto out;
2576  res = -1; /* reset default */
2577  }
2578 
2579  if (continue_exec)
2580  *continue_exec = 0;
2581 
2582  /* If a channel group has been specified, get it for use when we create peer channels */
2583 
2584  ast_channel_lock(chan);
2585  if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
2586  outbound_group = ast_strdupa(outbound_group);
2587  pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
2588  } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
2589  outbound_group = ast_strdupa(outbound_group);
2590  }
2591  ast_channel_unlock(chan);
2592 
2593  /* Set per dial instance flags. These flags are also passed back to RetryDial. */
2597 
2598  /* PREDIAL: Run gosub on the caller's channel */
2600  && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {
2602  ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER], 0);
2603  }
2604 
2605  /* loop through the list of dial destinations */
2606  rest = args.peers;
2607  while ((cur = strsep(&rest, "&"))) {
2608  struct ast_channel *tc; /* channel for this destination */
2609  char *number;
2610  char *tech;
2611  int i;
2612  size_t tech_len;
2613  size_t number_len;
2614  struct ast_stream_topology *topology;
2615  struct ast_stream *stream;
2616 
2617  cur = ast_strip(cur);
2618  if (ast_strlen_zero(cur)) {
2619  /* No tech/resource in this position. */
2620  continue;
2621  }
2622 
2623  /* Get a technology/resource pair */
2624  number = cur;
2625  tech = strsep(&number, "/");
2626 
2627  num_dialed++;
2628  if (ast_strlen_zero(number)) {
2629  ast_log(LOG_WARNING, "Dial argument takes format (technology/resource)\n");
2630  goto out;
2631  }
2632 
2633  tech_len = strlen(tech) + 1;
2634  number_len = strlen(number) + 1;
2635  tmp = ast_calloc(1, sizeof(*tmp) + (2 * tech_len) + number_len);
2636  if (!tmp) {
2637  goto out;
2638  }
2639 
2640  /* Save tech, number, and interface. */
2641  cur = tmp->stuff;
2642  strcpy(cur, tech);
2643  tmp->tech = cur;
2644  cur += tech_len;
2645  strcpy(cur, tech);
2646  cur[tech_len - 1] = '/';
2647  tmp->interface = cur;
2648  cur += tech_len;
2649  strcpy(cur, number);
2650  tmp->number = cur;
2651 
2652  if (opts.flags) {
2653  /* Set per outgoing call leg options. */
2654  ast_copy_flags64(tmp, &opts,
2664  }
2665 
2666  /* Request the peer */
2667 
2668  ast_channel_lock(chan);
2669  /*
2670  * Seed the chanlist's connected line information with previously
2671  * acquired connected line info from the incoming channel. The
2672  * previously acquired connected line info could have been set
2673  * through the CONNECTED_LINE dialplan function.
2674  */
2676 
2678 
2679  ast_channel_unlock(chan);
2680 
2681  for (i = 0; i < ast_stream_topology_get_count(topology); ++i) {
2682  stream = ast_stream_topology_get_stream(topology, i);
2683  /* For both recvonly and sendonly the stream state reflects our state, that is we
2684  * are receiving only and we are sending only. Since we are requesting a
2685  * channel for the peer, we need to swap this to reflect what we will be doing.
2686  * That is, if we are receiving from Alice then we want to be sending to Bob,
2687  * so swap recvonly to sendonly and vice versa.
2688  */
2691  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_SENDONLY) {
2693  }
2694  }
2695 
2696  tc = ast_request_with_stream_topology(tmp->tech, topology, NULL, chan, tmp->number, &cause);
2697 
2698  ast_stream_topology_free(topology);
2699 
2700  if (!tc) {
2701  /* If we can't, just go on to the next call */
2702  ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
2703  tmp->tech, cause, ast_cause2str(cause));
2704  handle_cause(cause, &num);
2705  if (!rest) {
2706  /* we are on the last destination */
2707  ast_channel_hangupcause_set(chan, cause);
2708  }
2709  if (!ignore_cc && (cause == AST_CAUSE_BUSY || cause == AST_CAUSE_CONGESTION)) {
2710  if (!ast_cc_callback(chan, tmp->tech, tmp->number, ast_cc_busy_interface)) {
2711  ast_cc_extension_monitor_add_dialstring(chan, tmp->interface, "");
2712  }
2713  }
2714  chanlist_free(tmp);
2715  continue;
2716  }
2717 
2718  ast_channel_get_device_name(tc, device_name, sizeof(device_name));
2719  if (!ignore_cc) {
2720  ast_cc_extension_monitor_add_dialstring(chan, tmp->interface, device_name);
2721  }
2722 
2723  ast_channel_lock_both(tc, chan);
2725 
2726  pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", tmp->number);
2727 
2728  /* Setup outgoing SDP to match incoming one */
2729  if (!AST_LIST_FIRST(&out_chans) && !rest && CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
2730  /* We are on the only destination. */
2732  }
2733 
2734  /* Inherit specially named variables from parent channel */
2738 
2739  ast_channel_appl_set(tc, "AppDial");
2740  ast_channel_data_set(tc, "(Outgoing Line)");
2741 
2742  memset(ast_channel_whentohangup(tc), 0, sizeof(*ast_channel_whentohangup(tc)));
2743 
2744  /* Determine CallerID to store in outgoing channel. */
2746  if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
2747  caller.id = stored_clid;
2748  ast_channel_set_caller_event(tc, &caller, NULL);
2750  } else if (ast_strlen_zero(S_COR(ast_channel_caller(tc)->id.number.valid,
2751  ast_channel_caller(tc)->id.number.str, NULL))) {
2752  /*
2753  * The new channel has no preset CallerID number by the channel
2754  * driver. Use the dialplan extension and hint name.
2755  */
2756  caller.id = stored_clid;
2757  if (!caller.id.name.valid
2758  && !ast_strlen_zero(S_COR(ast_channel_connected(chan)->id.name.valid,
2759  ast_channel_connected(chan)->id.name.str, NULL))) {
2760  /*
2761  * No hint name available. We have a connected name supplied by
2762  * the dialplan we can use instead.
2763  */
2764  caller.id.name.valid = 1;
2765  caller.id.name = ast_channel_connected(chan)->id.name;
2766  }
2767  ast_channel_set_caller_event(tc, &caller, NULL);
2769  } else if (ast_strlen_zero(S_COR(ast_channel_caller(tc)->id.name.valid, ast_channel_caller(tc)->id.name.str,
2770  NULL))) {
2771  /* The new channel has no preset CallerID name by the channel driver. */
2772  if (!ast_strlen_zero(S_COR(ast_channel_connected(chan)->id.name.valid,
2773  ast_channel_connected(chan)->id.name.str, NULL))) {
2774  /*
2775  * We have a connected name supplied by the dialplan we can
2776  * use instead.
2777  */
2778  caller.id.name.valid = 1;
2779  caller.id.name = ast_channel_connected(chan)->id.name;
2780  ast_channel_set_caller_event(tc, &caller, NULL);
2781  }
2782  }
2783 
2784  /* Determine CallerID for outgoing channel to send. */
2785  if (ast_test_flag64(peerflags, OPT_FORCECLID) && !force_forwards_only) {
2787 
2789  connected.id = forced_clid;
2791  } else {
2793  }
2794 
2796 
2798 
2801  ast_channel_musicclass_set(tc, ast_channel_musicclass(chan));
2802  }
2803 
2804  /* Pass ADSI CPE and transfer capability */
2807 
2808  /* If we have an outbound group, set this peer channel to it */
2809  if (outbound_group)
2810  ast_app_group_set_channel(tc, outbound_group);
2811  /* If the calling channel has the ANSWERED_ELSEWHERE flag set, inherit it. This is to support local channels */
2814 
2815  /* Check if we're forced by configuration */
2818 
2819 
2820  /* Inherit context and extension */
2821  ast_channel_dialcontext_set(tc, ast_strlen_zero(ast_channel_macrocontext(chan)) ? ast_channel_context(chan) : ast_channel_macrocontext(chan));
2824  else
2826 
2828 
2829  /* Save the original channel name to detect call pickup masquerading in. */
2830  tmp->orig_chan_name = ast_strdup(ast_channel_name(tc));
2831 
2832  ast_channel_unlock(tc);
2833  ast_channel_unlock(chan);
2834 
2835  /* Put channel in the list of outgoing thingies. */
2836  tmp->chan = tc;
2837  AST_LIST_INSERT_TAIL(&out_chans, tmp, node);
2838  }
2839 
2840  if (AST_LIST_EMPTY(&out_chans)) {
2841  ast_verb(3, "No devices or endpoints to dial (technology/resource)\n");
2842  if (continue_exec) {
2843  /* There is no point in having RetryDial try again */
2844  *continue_exec = 1;
2845  }
2846  strcpy(pa.status, "CHANUNAVAIL");
2847  res = 0;
2848  goto out;
2849  }
2850 
2851  /*
2852  * PREDIAL: Run gosub on all of the callee channels
2853  *
2854  * We run the callee predial before ast_call() in case the user
2855  * wishes to do something on the newly created channels before
2856  * the channel does anything important.
2857  *
2858  * Inside the target gosub we will be able to do something with
2859  * the newly created channel name ie: now the calling channel
2860  * can know what channel will be used to call the destination
2861  * ex: now we will know that SIP/abc-123 is calling SIP/def-124
2862  */
2865  && !AST_LIST_EMPTY(&out_chans)) {
2866  const char *predial_callee;
2867 
2869  predial_callee = ast_app_expand_sub_args(chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
2870  if (predial_callee) {
2871  ast_autoservice_start(chan);
2872  AST_LIST_TRAVERSE(&out_chans, tmp, node) {
2873  ast_pre_call(tmp->chan, predial_callee);
2874  }
2875  ast_autoservice_stop(chan);
2876  ast_free((char *) predial_callee);
2877  }
2878  }
2879 
2880  /* Start all outgoing calls */
2881  AST_LIST_TRAVERSE_SAFE_BEGIN(&out_chans, tmp, node) {
2882  res = ast_call(tmp->chan, tmp->number, 0); /* Place the call, but don't wait on the answer */
2883  ast_channel_lock(chan);
2884 
2885  /* check the results of ast_call */
2886  if (res) {
2887  /* Again, keep going even if there's an error */
2888  ast_debug(1, "ast call on peer returned %d\n", res);
2889  ast_verb(3, "Couldn't call %s\n", tmp->interface);
2890  if (ast_channel_hangupcause(tmp->chan)) {
2892  }
2893  ast_channel_unlock(chan);
2894  ast_cc_call_failed(chan, tmp->chan, tmp->interface);
2895  ast_hangup(tmp->chan);
2896  tmp->chan = NULL;
2898  chanlist_free(tmp);
2899  continue;
2900  }
2901 
2902  ast_channel_publish_dial(chan, tmp->chan, tmp->number, NULL);
2903  ast_channel_unlock(chan);
2904 
2905  ast_verb(3, "Called %s\n", tmp->interface);
2907 
2908  /* If this line is up, don't try anybody else */
2909  if (ast_channel_state(tmp->chan) == AST_STATE_UP) {
2910  break;
2911  }
2912  }
2914 
2915  if (ast_strlen_zero(args.timeout)) {
2916  to = -1;
2917  } else {
2918  to = atoi(args.timeout);
2919  if (to > 0)
2920  to *= 1000;
2921  else {
2922  ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
2923  to = -1;
2924  }
2925  }
2926 
2927  outgoing = AST_LIST_FIRST(&out_chans);
2928  if (!outgoing) {
2929  strcpy(pa.status, "CHANUNAVAIL");
2930  if (fulldial == num_dialed) {
2931  res = -1;
2932  goto out;
2933  }
2934  } else {
2935  /* Our status will at least be NOANSWER */
2936  strcpy(pa.status, "NOANSWER");
2938  moh = 1;
2939  if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
2940  char *original_moh = ast_strdupa(ast_channel_musicclass(chan));
2941  ast_channel_musicclass_set(chan, opt_args[OPT_ARG_MUSICBACK]);
2942  ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
2943  ast_channel_musicclass_set(chan, original_moh);
2944  } else {
2945  ast_moh_start(chan, NULL, NULL);
2946  }
2949  if (!ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
2950  if (dial_handle_playtones(chan, opt_args[OPT_ARG_RINGBACK])){
2952  sentringing++;
2953  } else {
2955  }
2956  } else {
2958  sentringing++;
2959  }
2960  }
2961  }
2962 
2963  peer = wait_for_answer(chan, &out_chans, &to, peerflags, opt_args, &pa, &num, &result,
2964  dtmf_progress, mf_progress, mf_wink, sf_progress, sf_wink,
2965  (ast_test_flag64(&opts, OPT_HEARPULSING) ? 1 : 0),
2966  ignore_cc, &forced_clid, &stored_clid, &config);
2967 
2968  if (!peer) {
2969  if (result) {
2970  res = result;
2971  } else if (to) { /* Musta gotten hung up */
2972  res = -1;
2973  } else { /* Nobody answered, next please? */
2974  res = 0;
2975  }
2976  } else {
2977  const char *number;
2978  const char *name;
2979  int dial_end_raised = 0;
2980  int cause = -1;
2981 
2982  if (ast_test_flag64(&opts, OPT_CALLER_ANSWER)) {
2983  ast_answer(chan);
2984  }
2985 
2986  /* Ah ha! Someone answered within the desired timeframe. Of course after this
2987  we will always return with -1 so that it is hung up properly after the
2988  conversation. */
2989 
2990  if (ast_test_flag64(&opts, OPT_HANGUPCAUSE)
2991  && !ast_strlen_zero(opt_args[OPT_ARG_HANGUPCAUSE])) {
2992  cause = ast_str2cause(opt_args[OPT_ARG_HANGUPCAUSE]);
2993  if (cause <= 0) {
2994  if (!strcasecmp(opt_args[OPT_ARG_HANGUPCAUSE], "NONE")) {
2995  cause = 0;
2996  } else if (sscanf(opt_args[OPT_ARG_HANGUPCAUSE], "%30d", &cause) != 1
2997  || cause < 0) {
2998  ast_log(LOG_WARNING, "Invalid cause given to Dial(...Q(<cause>)): \"%s\"\n",
2999  opt_args[OPT_ARG_HANGUPCAUSE]);
3000  cause = -1;
3001  }
3002  }
3003  }
3004  hanguptree(&out_chans, peer, cause >= 0 ? cause : AST_CAUSE_ANSWERED_ELSEWHERE);
3005 
3006  /* If appropriate, log that we have a destination channel and set the answer time */
3007 
3008  ast_channel_lock(peer);
3010 
3011  number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
3012  if (ast_strlen_zero(number)) {
3013  number = NULL;
3014  } else {
3016  }
3017  ast_channel_unlock(peer);
3018 
3019  ast_channel_lock(chan);
3021 
3022  strcpy(pa.status, "ANSWER");
3023  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
3024 
3025  pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", name);
3026  pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
3027 
3029  ast_channel_unlock(chan);
3030 
3031  if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
3032  ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
3033  ast_channel_sendurl( peer, args.url );
3034  }
3036  if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
3037  ast_channel_publish_dial(chan, peer, NULL, pa.status);
3038  /* hang up on the callee -- he didn't want to talk anyway! */
3040  res = 0;
3041  goto out;
3042  }
3043  }
3044  if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
3045  res = 0;
3046  } else {
3047  int digit = 0;
3048  struct ast_channel *chans[2];
3049  struct ast_channel *active_chan;
3050  char *calledfile = NULL, *callerfile = NULL;
3051  int calledstream = 0, callerstream = 0;
3052 
3053  chans[0] = chan;
3054  chans[1] = peer;
3055 
3056  /* we need to stream the announcement(s) when the OPT_ARG_ANNOUNCE (-A) is set */
3057  callerfile = opt_args[OPT_ARG_ANNOUNCE];
3058  calledfile = strsep(&callerfile, ":");
3059 
3060  /* stream the file(s) */
3061  if (!ast_strlen_zero(calledfile)) {
3062  res = ast_streamfile(peer, calledfile, ast_channel_language(peer));
3063  if (res) {
3064  res = 0;
3065  ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", calledfile);
3066  } else {
3067  calledstream = 1;
3068  }
3069  }
3070  if (!ast_strlen_zero(callerfile)) {
3071  res = ast_streamfile(chan, callerfile, ast_channel_language(chan));
3072  if (res) {
3073  res = 0;
3074  ast_log(LOG_ERROR, "error streaming file '%s' to caller\n", callerfile);
3075  } else {
3076  callerstream = 1;
3077  }
3078  }
3079 
3080  /* can't use ast_waitstream, because we're streaming two files at once, and can't block
3081  We'll need to handle both channels at once. */
3082 
3084  while (ast_channel_stream(peer) || ast_channel_stream(chan)) {
3085  int mspeer, mschan;
3086 
3087  mspeer = ast_sched_wait(ast_channel_sched(peer));
3088  mschan = ast_sched_wait(ast_channel_sched(chan));
3089 
3090  if (calledstream) {
3091  if (mspeer < 0 && !ast_channel_timingfunc(peer)) {
3092  ast_stopstream(peer);
3093  calledstream = 0;
3094  }
3095  }
3096  if (callerstream) {
3097  if (mschan < 0 && !ast_channel_timingfunc(chan)) {
3098  ast_stopstream(chan);
3099  callerstream = 0;
3100  }
3101  }
3102 
3103  if (!calledstream && !callerstream) {
3104  break;
3105  }
3106 
3107  if (mspeer < 0)
3108  mspeer = 1000;
3109 
3110  if (mschan < 0)
3111  mschan = 1000;
3112 
3113  /* wait for the lowest maximum of the two */
3114  active_chan = ast_waitfor_n(chans, 2, (mspeer > mschan ? &mschan : &mspeer));
3115  if (active_chan) {
3116  struct ast_channel *other_chan;
3117  struct ast_frame *fr = ast_read(active_chan);
3118 
3119  if (!fr) {
3121  res = -1;
3122  goto done;
3123  }
3124  switch (fr->frametype) {
3125  case AST_FRAME_DTMF_END:
3126  digit = fr->subclass.integer;
3127  if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
3128  ast_stopstream(peer);
3129  res = ast_senddigit(chan, digit, 0);
3130  }
3131  break;
3132  case AST_FRAME_CONTROL:
3133  switch (fr->subclass.integer) {
3134  case AST_CONTROL_HANGUP:
3135  ast_frfree(fr);
3137  res = -1;
3138  goto done;
3140  /* Pass COLP update to the other channel. */
3141  if (active_chan == chan) {
3142  other_chan = peer;
3143  } else {
3144  other_chan = chan;
3145  }
3146  if (ast_channel_connected_line_sub(active_chan, other_chan, fr, 1)
3147  && ast_channel_connected_line_macro(active_chan,
3148  other_chan, fr, other_chan == chan, 1)) {
3149  ast_indicate_data(other_chan, fr->subclass.integer,
3150  fr->data.ptr, fr->datalen);
3151  }
3152  break;
3153  default:
3154  break;
3155  }
3156  break;
3157  default:
3158  /* Ignore all others */
3159  break;
3160  }
3161  ast_frfree(fr);
3162  }
3165  }
3167  }
3168 
3169  if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
3170  /* chan and peer are going into the PBX; as such neither are considered
3171  * outgoing channels any longer */
3173 
3175  ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
3176  /* peer goes to the same context and extension as chan, so just copy info from chan*/
3177  ast_channel_lock(peer);
3184  ast_channel_unlock(peer);
3185  if (ast_pbx_start(peer)) {
3187  }
3188  if (continue_exec)
3189  *continue_exec = 1;
3190  res = 0;
3191  ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
3192  goto done;
3193  }
3194 
3196  const char *macro_result_peer;
3197  int macro_res;
3198 
3199  /* Set peer->exten and peer->context so that MACRO_EXTEN and MACRO_CONTEXT get set */
3200  ast_channel_lock_both(chan, peer);
3203  ast_channel_unlock(peer);
3204  ast_channel_unlock(chan);
3206  macro_res = ast_app_exec_macro(chan, peer, opt_args[OPT_ARG_CALLEE_MACRO]);
3207 
3208  ast_channel_lock(peer);
3209 
3210  if (!macro_res && (macro_result_peer = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
3211  char *macro_result = ast_strdupa(macro_result_peer);
3212  char *macro_transfer_dest;
3213 
3214  ast_channel_unlock(peer);
3215 
3216  if (!strcasecmp(macro_result, "BUSY")) {
3217  ast_copy_string(pa.status, macro_result, sizeof(pa.status));
3218  ast_set_flag64(peerflags, OPT_GO_ON);
3219  macro_res = -1;
3220  } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
3221  ast_copy_string(pa.status, macro_result, sizeof(pa.status));
3222  ast_set_flag64(peerflags, OPT_GO_ON);
3223  macro_res = -1;
3224  } else if (!strcasecmp(macro_result, "CONTINUE")) {
3225  /* hangup peer and keep chan alive assuming the macro has changed
3226  the context / exten / priority or perhaps
3227  the next priority in the current exten is desired.
3228  */
3229  ast_set_flag64(peerflags, OPT_GO_ON);
3230  macro_res = -1;
3231  } else if (!strcasecmp(macro_result, "ABORT")) {
3232  /* Hangup both ends unless the caller has the g flag */
3233  macro_res = -1;
3234  } else if (!strncasecmp(macro_result, "GOTO:", 5)) {
3235  macro_transfer_dest = macro_result + 5;
3236  macro_res = -1;
3237  /* perform a transfer to a new extension */
3238  if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
3239  ast_replace_subargument_delimiter(macro_transfer_dest);
3240  }
3241  if (!ast_parseable_goto(chan, macro_transfer_dest)) {
3242  ast_set_flag64(peerflags, OPT_GO_ON);
3243  }
3244  }
3245  if (macro_res && !dial_end_raised) {
3246  ast_channel_publish_dial(chan, peer, NULL, macro_result);
3247  dial_end_raised = 1;
3248  }
3249  } else {
3250  ast_channel_unlock(peer);
3251  }
3252  res = macro_res;
3253  }
3254 
3256  const char *gosub_result_peer;
3257  char *gosub_argstart;
3258  char *gosub_args = NULL;
3259  int gosub_res = -1;
3260 
3262  gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
3263  if (gosub_argstart) {
3264  const char *what_is_s = "s";
3265  *gosub_argstart = 0;
3266  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)) &&
3267  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))) {
3268  what_is_s = "~~s~~";
3269  }
3270  if (ast_asprintf(&gosub_args, "%s,%s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s, gosub_argstart + 1) < 0) {
3271  gosub_args = NULL;
3272  }
3273  *gosub_argstart = ',';
3274  } else {
3275  const char *what_is_s = "s";
3276  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)) &&
3277  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))) {
3278  what_is_s = "~~s~~";
3279  }
3280  if (ast_asprintf(&gosub_args, "%s,%s,1", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s) < 0) {
3281  gosub_args = NULL;
3282  }
3283  }
3284  if (gosub_args) {
3285  gosub_res = ast_app_exec_sub(chan, peer, gosub_args, 0);
3286  ast_free(gosub_args);
3287  } else {
3288  ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
3289  }
3290 
3291  ast_channel_lock_both(chan, peer);
3292 
3293  if (!gosub_res && (gosub_result_peer = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
3294  char *gosub_transfer_dest;
3295  char *gosub_result = ast_strdupa(gosub_result_peer);
3296  const char *gosub_retval = pbx_builtin_getvar_helper(peer, "GOSUB_RETVAL");
3297 
3298  /* Inherit return value from the peer, so it can be used in the master */
3299  if (gosub_retval) {
3300  pbx_builtin_setvar_helper(chan, "GOSUB_RETVAL", gosub_retval);
3301  }
3302 
3303  ast_channel_unlock(peer);
3304  ast_channel_unlock(chan);
3305 
3306  if (!strcasecmp(gosub_result, "BUSY")) {
3307  ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
3308  ast_set_flag64(peerflags, OPT_GO_ON);
3309  gosub_res = -1;
3310  } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
3311  ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
3312  ast_set_flag64(peerflags, OPT_GO_ON);
3313  gosub_res = -1;
3314  } else if (!strcasecmp(gosub_result, "CONTINUE")) {
3315  /* Hangup peer and continue with the next extension priority. */
3316  ast_set_flag64(peerflags, OPT_GO_ON);
3317  gosub_res = -1;
3318  } else if (!strcasecmp(gosub_result, "ABORT")) {
3319  /* Hangup both ends unless the caller has the g flag */
3320  gosub_res = -1;
3321  } else if (!strncasecmp(gosub_result, "GOTO:", 5)) {
3322  gosub_transfer_dest = gosub_result + 5;
3323  gosub_res = -1;
3324  /* perform a transfer to a new extension */
3325  if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
3326  ast_replace_subargument_delimiter(gosub_transfer_dest);
3327  }
3328  if (!ast_parseable_goto(chan, gosub_transfer_dest)) {
3329  ast_set_flag64(peerflags, OPT_GO_ON);
3330  }
3331  }
3332  if (gosub_res) {
3333  res = gosub_res;
3334  if (!dial_end_raised) {
3335  ast_channel_publish_dial(chan, peer, NULL, gosub_result);
3336  dial_end_raised = 1;
3337  }
3338  }
3339  } else {
3340  ast_channel_unlock(peer);
3341  ast_channel_unlock(chan);
3342  }
3343  }
3344 
3345  if (!res) {
3346 
3347  /* None of the Dial options changed our status; inform
3348  * everyone that this channel answered
3349  */
3350  if (!dial_end_raised) {
3351  ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
3352  dial_end_raised = 1;
3353  }
3354 
3355  if (!ast_tvzero(calldurationlimit)) {
3356  struct timeval whentohangup = ast_tvadd(ast_tvnow(), calldurationlimit);
3357  ast_channel_lock(peer);
3358  ast_channel_whentohangup_set(peer, &whentohangup);
3359  ast_channel_unlock(peer);
3360  }
3361  if (!ast_strlen_zero(dtmfcalled)) {
3362  ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
3363  res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
3364  }
3365  if (!ast_strlen_zero(dtmfcalling)) {
3366  ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
3367  res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
3368  }
3369  }
3370 
3371  if (res) { /* some error */
3372  if (!ast_check_hangup(chan) && ast_check_hangup(peer)) {
3374  }
3375  setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3376  if (ast_bridge_setup_after_goto(peer)
3377  || ast_pbx_start(peer)) {
3379  }
3380  res = -1;
3381  } else {
3382  if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
3383  ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
3384  if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
3385  ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
3386  if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
3387  ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
3388  if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
3389  ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
3390  if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
3391  ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
3392  if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
3393  ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
3394  if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
3395  ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
3396  if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
3397  ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
3398  if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
3399  ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
3400  if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
3401  ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
3402 
3403  config.end_bridge_callback = end_bridge_callback;
3404  config.end_bridge_callback_data = chan;
3405  config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup;
3406 
3407  if (moh) {
3408  moh = 0;
3409  ast_moh_stop(chan);
3410  } else if (sentringing) {
3411  sentringing = 0;
3412  ast_indicate(chan, -1);
3413  }
3414  /* Be sure no generators are left on it and reset the visible indication */
3417  /* Make sure channels are compatible */
3418  res = ast_channel_make_compatible(chan, peer);
3419  if (res < 0) {
3420  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));
3422  res = -1;
3423  goto done;
3424  }
3425  if (opermode) {
3426  struct oprmode oprmode;
3427 
3428  oprmode.peer = peer;
3429  oprmode.mode = opermode;
3430 
3432  }
3433  setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3434 
3435  res = ast_bridge_call(chan, peer, &config);
3436  }
3437  }
3438 out:
3439  if (moh) {
3440  moh = 0;
3441  ast_moh_stop(chan);
3442  } else if (sentringing) {
3443  sentringing = 0;
3444  ast_indicate(chan, -1);
3445  }
3446 
3447  if (delprivintro && ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3449  if (ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3450  ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
3451  } else {
3452  ast_verb(3, "Successfully deleted %s intro file\n", pa.privintro);
3453  }
3454  }
3455 
3457  /* forward 'answered elsewhere' if we received it */
3459  hanguptreecause = AST_CAUSE_ANSWERED_ELSEWHERE;
3460  } else if (pa.canceled) { /* Caller canceled */
3461  if (ast_channel_hangupcause(chan))
3462  hanguptreecause = ast_channel_hangupcause(chan);
3463  else
3464  hanguptreecause = AST_CAUSE_NORMAL_CLEARING;
3465  }
3466  hanguptree(&out_chans, NULL, hanguptreecause);
3467  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
3468  ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
3469 
3470  if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
3471  if (!ast_tvzero(calldurationlimit))
3472  memset(ast_channel_whentohangup(chan), 0, sizeof(*ast_channel_whentohangup(chan)));
3473  res = 0;
3474  }
3475 
3476 done:
3477  if (config.answer_topology) {
3478  ast_trace(2, "%s Cleaning up topology: %p %s\n",
3479  peer ? ast_channel_name(peer) : "<no channel>", &config.answer_topology,
3480  ast_str_tmp(256, ast_stream_topology_to_str(config.answer_topology, &STR_TMP)));
3481 
3482  /*
3483  * At this point, the channel driver that answered should have bumped the
3484  * topology refcount for itself. Here we're cleaning up the reference we added
3485  * in wait_for_answer().
3486  */
3487  ast_stream_topology_free(config.answer_topology);
3488  }
3489  if (config.warning_sound) {
3490  ast_free((char *)config.warning_sound);
3491  }
3492  if (config.end_sound) {
3493  ast_free((char *)config.end_sound);
3494  }
3495  if (config.start_sound) {
3496  ast_free((char *)config.start_sound);
3497  }
3498  ast_ignore_cc(chan);
3499  SCOPE_EXIT_RTN_VALUE(res, "%s: Done\n", ast_channel_name(chan));
3500 }
char digit
#define DIAL_STILLGOING
Definition: app_dial.c:738
#define OPT_PREDIAL_CALLER
Definition: app_dial.c:749
#define OPT_CANCEL_ELSEWHERE
Definition: app_dial.c:741
static const struct ast_app_option dial_exec_options[128]
Definition: app_dial.c:823
#define OPT_PREDIAL_CALLEE
Definition: app_dial.c:748
#define DIAL_CALLERID_ABSENT
Definition: app_dial.c:740
#define OPT_FORCE_CID_PRES
Definition: app_dial.c:746
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:2290
#define CAN_EARLY_BRIDGE(flags, chan, peer)
Definition: app_dial.c:825
#define OPT_RING_WITH_EARLY_MEDIA
Definition: app_dial.c:750
#define OPT_FORCE_CID_TAG
Definition: app_dial.c:745
#define OPT_HEARPULSING
Definition: app_dial.c:752
#define DIAL_NOFORWARDHTML
Definition: app_dial.c:739
#define OPT_CANCEL_TIMEOUT
Definition: app_dial.c:744
static void chanlist_free(struct chanlist *outgoing)
Definition: app_dial.c:860
static void handle_cause(int cause, struct cause_args *num)
Definition: app_dial.c:898
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'
Definition: app_dial.c:2135
#define OPT_HANGUPCAUSE
Definition: app_dial.c:751
static void hanguptree(struct dial_head *out_chans, struct ast_channel *exception, int hangupcause)
Definition: app_dial.c:868
static int dial_handle_playtones(struct ast_channel *chan, const char *data)
Definition: app_dial.c:2250
static void end_bridge_callback(void *data)
Definition: app_dial.c:2234
#define OPT_CALLER_ANSWER
Definition: app_dial.c:747
static const char * get_cid_name(char *name, int namelen, struct ast_channel *chan)
Definition: app_dial.c:939
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
Definition: app_dial.c:2246
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, char *mf_wink, char *sf_progress, char *sf_wink, const int hearpulsing, 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:1240
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:435
static int tmp()
Definition: bt_open.c:389
#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:332
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_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1008
#define AST_CAUSE_CONGESTION
Definition: causes.h:153
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:114
#define AST_CAUSE_BUSY
Definition: causes.h:149
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
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:4197
void ast_ignore_cc(struct ast_channel *chan)
Mark the channel to ignore further CC activity.
Definition: ccss.c:3718
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:4230
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:2006
int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
Start the CC process on a call.
Definition: ccss.c:2409
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:4242
int ast_cdr_reset(const char *channel_name, int keep_variables)
Reset the detail record.
Definition: cdr.c:3620
static PGresult * result
Definition: cel_pgsql.c:84
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1844
static const char config[]
Definition: chan_ooh323.c:111
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
int ast_str2cause(const char *name) attribute_pure
Convert the string form of a cause code to a number.
Definition: channel.c:625
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
void ast_channel_visible_indication_set(struct ast_channel *chan, int value)
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:10682
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6539
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11220
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
Definition: channel.c:1751
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's connected line information.
Definition: channel.c:10524
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2542
@ AST_FEATURE_AUTOMIXMON
Definition: channel.h:1069
@ AST_FEATURE_REDIRECT
Definition: channel.h:1064
@ AST_FEATURE_PARKCALL
Definition: channel.h:1068
@ AST_FEATURE_AUTOMON
Definition: channel.h:1067
@ AST_FEATURE_DISCONNECT
Definition: channel.h:1065
@ AST_CHANNEL_REQUESTOR_BRIDGE_PEER
Definition: channel.h:1477
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:8391
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:6437
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:7455
int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
Send a DTMF digit to a channel.
Definition: channel.c:5009
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Definition: channel.c:6798
void ast_channel_data_set(struct ast_channel *chan, const char *value)
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
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:2025
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2929
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2367
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:6512
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:2894
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4292
ast_channel_adsicpe
Definition: channel.h:868
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:1993
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:1774
@ AST_FLAG_OUTGOING
Definition: channel.h:999
@ AST_FLAG_END_DTMF_ONLY
Definition: channel.h:1007
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:6849
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_channel_supports_html(struct ast_channel *channel)
Checks for HTML support on a channel.
Definition: channel.c:6701
const char * ast_channel_language(const struct ast_channel *chan)
const char * ast_channel_musicclass(const struct ast_channel *chan)
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_channel_exten(const struct ast_channel *chan)
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:4688
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's connected line information.
Definition: channel.c:10420
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
Definition: channel.c:11213
ast_timing_func_t ast_channel_timingfunc(const struct ast_channel *chan)
#define AST_CHANNEL_NAME
Definition: channel.h:171
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:6713
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
const char * ast_channel_macroexten(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
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:8376
struct ast_sched_context * ast_channel_sched(const struct ast_channel *chan)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
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:6522
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:7505
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:2039
const char * ast_channel_macrocontext(const struct ast_channel *chan)
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
void ast_channel_priority_set(struct ast_channel *chan, int value)
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
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_channel_whentohangup_set(struct ast_channel *chan, struct timeval *value)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2806
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:3158
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
Bridge two channels together (early)
Definition: channel.c:7495
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4312
#define ast_channel_unlock(chan)
Definition: channel.h:2923
#define AST_MAX_EXTENSION
Definition: channel.h:134
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:2129
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
char connected
Definition: eagi_proxy.c:82
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:712
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,...
Definition: features.c:882
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1291
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1127
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1139
#define AST_DIGIT_ANY
Definition: file.h:48
static const char name[]
Definition: format_mp3.c:68
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_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_APP_ARG(name)
Define an application argument.
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:348
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:2253
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
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:270
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
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:367
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:1197
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:3131
char * strsep(char **str, const char *delims)
#define AST_OPTION_OPRMODE
#define ast_frfree(fr)
@ AST_FRAME_DTMF_END
@ AST_FRAME_CONTROL
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_RINGING
@ AST_CONTROL_HANGUP
@ AST_CONTROL_CONNECTED_LINE
#define ast_debug(level,...)
Log a DEBUG message.
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_ENTER(level,...)
#define ast_trace(level,...)
#define LOG_ERROR
#define ast_verb(level,...)
#define LOG_NOTICE
#define LOG_WARNING
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
Definition: linkedlists.h:252
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
int ast_max_forwards_decrement(struct ast_channel *chan)
Decrement the max forwards count for a particular channel.
Definition: max_forwards.c:135
int ast_max_forwards_get(struct ast_channel *chan)
Get the current max forwards for a particular channel.
Definition: max_forwards.c:121
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:7849
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7859
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:4182
#define AST_PBX_INCOMPLETE
Definition: pbx.h:51
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.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4715
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
#define AST_PRIVACY_UNKNOWN
Definition: privacy.h:34
static char url[512]
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:2243
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:786
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:433
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
@ AST_STREAM_STATE_RECVONLY
Set when the stream is receiving media only.
Definition: stream.h:90
@ AST_STREAM_STATE_SENDONLY
Set when the stream is sending media only.
Definition: stream.h:86
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
void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
Set the state of a stream.
Definition: stream.c:380
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definition: stream.c:788
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
#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:87
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
Definition: strings.h:1167
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:406
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
bridge configuration
Definition: channel.h:1076
Main Channel structure associated with a channel.
const struct ast_channel_tech * tech
uint64_t flags
Definition: utils.h:205
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@254 data
enum ast_frame_type frametype
Caller Party information.
Definition: channel.h:418
Connected Line/Party information.
Definition: channel.h:456
struct ast_party_id id
Connected party ID.
Definition: channel.h:458
int transit_network_select
Transit Network Select.
Definition: channel.h:397
Information needed to identify an endpoint in a call.
Definition: channel.h:338
struct ast_party_name name
Subscriber name.
Definition: channel.h:340
struct ast_channel * chan
Definition: app_dial.c:892
List of channel drivers.
Definition: app_dial.c:835
Definition: astman.c:88
Channel datastore data for max forwards.
Definition: max_forwards.c:29
Definition: test_heap.c:38
Number structure.
Definition: app_followme.c:154
struct ast_channel * peer
char status[256]
Definition: app_dial.c:1182
int privdb_val
Definition: app_dial.c:1179
int sentringing
Definition: app_dial.c:1178
char privintro[1024]
Definition: app_dial.c:1181
int done
Definition: test_amihooks.c:48
const char * args
static struct test_options options
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:115
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:157
FILE * out
Definition: utils/frame.c:33
#define ast_set2_flag64(p, value, flag)
Definition: utils.h:151
#define ast_test_flag64(p, flag)
Definition: utils.h:120
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ast_copy_flags64(dest, src, flagz)
Definition: utils.h:141
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_set_flag(p, flag)
Definition: utils.h:70
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
Definition: main/utils.c:2241

References 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_CAUSE_NORMAL_CLEARING, 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_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_get_state(), ast_stream_set_state(), AST_STREAM_STATE_RECVONLY, AST_STREAM_STATE_SENDONLY, ast_stream_topology_clone(), ast_stream_topology_free(), ast_stream_topology_get_count(), ast_stream_topology_get_stream(), 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, privacy_args::canceled, cause_args::chan, chanlist_free(), config, connected, ast_frame::data, ast_frame::datalen, DIAL_CALLERID_ABSENT, dial_exec_options, dial_handle_playtones(), DIAL_NOFORWARDHTML, DIAL_STILLGOING, digit, done, end_bridge_callback(), end_bridge_callback_data_fixup(), 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, LOG_ERROR, LOG_NOTICE, LOG_WARNING, oprmode::mode, name, ast_party_id::name, NULL, ast_party_id::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_HEARPULSING, 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, 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(), privacy_args::status, ast_party_name::str, ast_party_number::str, ast_party_subaddress::str, strsep(), ast_party_id::subaddress, ast_frame::subclass, ast_party_id::tag, ast_channel::tech, tmp(), ast_party_dialed::transit_network_select, url, ast_party_name::valid, ast_party_number::valid, and wait_for_answer().

Referenced by dial_exec(), and retrydial_exec().

◆ dial_handle_playtones()

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

Definition at line 2250 of file app_dial.c.

2251 {
2252  struct ast_tone_zone_sound *ts = NULL;
2253  int res;
2254  const char *str = data;
2255 
2256  if (ast_strlen_zero(str)) {
2257  ast_debug(1,"Nothing to play\n");
2258  return -1;
2259  }
2260 
2262 
2263  if (ts && ts->data[0]) {
2264  res = ast_playtones_start(chan, 0, ts->data, 0);
2265  } else {
2266  res = -1;
2267  }
2268 
2269  if (ts) {
2270  ts = ast_tone_zone_sound_unref(ts);
2271  }
2272 
2273  if (res) {
2274  ast_log(LOG_WARNING, "Unable to start playtone \'%s\'\n", str);
2275  }
2276 
2277  return res;
2278 }
const char * str
Definition: app_jack.c:147
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
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
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
const char * data
Description of a tone.
Definition: indications.h:52

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().

◆ 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 integrated into and replaced by ast_call_forward()

Definition at line 969 of file app_dial.c.

972 {
973  char tmpchan[256];
974  char forwarder[AST_CHANNEL_NAME];
975  struct ast_channel *original = o->chan;
976  struct ast_channel *c = o->chan; /* the winner */
977  struct ast_channel *in = num->chan; /* the input channel */
978  char *stuff;
979  char *tech;
980  int cause;
981  struct ast_party_caller caller;
982 
983  ast_copy_string(forwarder, ast_channel_name(c), sizeof(forwarder));
984  ast_copy_string(tmpchan, ast_channel_call_forward(c), sizeof(tmpchan));
985  if ((stuff = strchr(tmpchan, '/'))) {
986  *stuff++ = '\0';
987  tech = tmpchan;
988  } else {
989  const char *forward_context;
991  forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
992  if (ast_strlen_zero(forward_context)) {
993  forward_context = NULL;
994  }
995  snprintf(tmpchan, sizeof(tmpchan), "%s@%s", ast_channel_call_forward(c), forward_context ? forward_context : ast_channel_context(c));
997  stuff = tmpchan;
998  tech = "Local";
999  }
1000  if (!strcasecmp(tech, "Local")) {
1001  /*
1002  * Drop the connected line update block for local channels since
1003  * this is going to run dialplan and the user can change his
1004  * mind about what connected line information he wants to send.
1005  */
1007  }
1008 
1009  /* Before processing channel, go ahead and check for forwarding */
1010  ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", ast_channel_name(in), tech, stuff, ast_channel_name(c));
1011  /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
1012  if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
1013  ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", ast_channel_name(in), tech, stuff);
1014  ast_channel_publish_dial_forward(in, original, NULL, NULL, "CANCEL",
1015  ast_channel_call_forward(original));
1016  c = o->chan = NULL;
1017  cause = AST_CAUSE_BUSY;
1018  } else {
1019  struct ast_stream_topology *topology;
1020 
1024 
1025  /* Setup parameters */
1026  c = o->chan = ast_request_with_stream_topology(tech, topology, NULL, in, stuff, &cause);
1027 
1028  ast_stream_topology_free(topology);
1029 
1030  if (c) {
1031  if (single && !caller_entertained) {
1033  }
1037  pbx_builtin_setvar_helper(o->chan, "FORWARDERNAME", forwarder);
1041  /* When a call is forwarded, we don't want to track new interfaces
1042  * dialed for CC purposes. Setting the done flag will ensure that
1043  * any Dial operations that happen later won't record CC interfaces.
1044  */
1045  ast_ignore_cc(o->chan);
1046  ast_verb(3, "Not accepting call completion offers from call-forward recipient %s\n",
1047  ast_channel_name(o->chan));
1048  } else
1050  "Forwarding failed to create channel to dial '%s/%s' (cause = %d)\n",
1051  tech, stuff, cause);
1052  }
1053  if (!c) {
1054  ast_channel_publish_dial(in, original, stuff, "BUSY");
1056  handle_cause(cause, num);
1057  ast_hangup(original);
1058  } else {
1059  ast_channel_lock_both(c, original);
1061  ast_channel_redirecting(original));
1063  ast_channel_unlock(original);
1064 
1066 
1067  if (single && !caller_entertained && CAN_EARLY_BRIDGE(peerflags, c, in)) {
1069  }
1070 
1071  if (!ast_channel_redirecting(c)->from.number.valid
1072  || ast_strlen_zero(ast_channel_redirecting(c)->from.number.str)) {
1073  /*
1074  * The call was not previously redirected so it is
1075  * now redirected from this number.
1076  */
1082  }
1083 
1085 
1086  /* Determine CallerID to store in outgoing channel. */
1088  if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
1089  caller.id = *stored_clid;
1090  ast_channel_set_caller_event(c, &caller, NULL);
1092  } else if (ast_strlen_zero(S_COR(ast_channel_caller(c)->id.number.valid,
1093  ast_channel_caller(c)->id.number.str, NULL))) {
1094  /*
1095  * The new channel has no preset CallerID number by the channel
1096  * driver. Use the dialplan extension and hint name.
1097  */
1098  caller.id = *stored_clid;
1099  ast_channel_set_caller_event(c, &caller, NULL);
1101  } else {
1103  }
1104 
1105  /* Determine CallerID for outgoing channel to send. */
1106  if (ast_test_flag64(o, OPT_FORCECLID)) {
1108 
1110  connected.id = *forced_clid;
1112  } else {
1114  }
1115 
1117 
1118  ast_channel_appl_set(c, "AppDial");
1119  ast_channel_data_set(c, "(Outgoing Line)");
1121 
1123  if (single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1124  struct ast_party_redirecting redirecting;
1125 
1126  /*
1127  * Redirecting updates to the caller make sense only on single
1128  * calls.
1129  *
1130  * We must unlock c before calling
1131  * ast_channel_redirecting_macro, because we put c into
1132  * autoservice there. That is pretty much a guaranteed
1133  * deadlock. This is why the handling of c's lock may seem a
1134  * bit unusual here.
1135  */
1136  ast_party_redirecting_init(&redirecting);
1139  if (ast_channel_redirecting_sub(c, in, &redirecting, 0) &&
1140  ast_channel_redirecting_macro(c, in, &redirecting, 1, 0)) {
1141  ast_channel_update_redirecting(in, &redirecting, NULL);
1142  }
1143  ast_party_redirecting_free(&redirecting);
1144  } else {
1146  }
1147 
1148  if (ast_test_flag64(peerflags, OPT_CANCEL_TIMEOUT)) {
1149  *to = -1;
1150  }
1151 
1152  if (ast_call(c, stuff, 0)) {
1153  ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n",
1154  tech, stuff);
1155  ast_channel_publish_dial(in, original, stuff, "CONGESTION");
1157  ast_hangup(original);
1158  ast_hangup(c);
1159  c = o->chan = NULL;
1160  num->nochan++;
1161  } else {
1162  ast_channel_publish_dial_forward(in, original, c, NULL, "CANCEL",
1163  ast_channel_call_forward(original));
1164 
1165  ast_channel_publish_dial(in, c, stuff, NULL);
1166 
1167  /* Hangup the original channel now, in case we needed it */
1168  ast_hangup(original);
1169  }
1170  if (single && !caller_entertained) {
1171  ast_indicate(in, -1);
1172  }
1173  }
1174 }
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
Definition: channel.c:2116
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
Definition: channel.c:1638
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's redirecting information.
Definition: channel.c:10472
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's redirecting information.
Definition: channel.c:10569
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:10366
void ast_party_number_free(struct ast_party_number *doomed)
Destroy the party number contents.
Definition: channel.c:1685
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2016
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2173
const char * ast_channel_call_forward(const struct ast_channel *chan)
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
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...
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:342
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:297
char * str
Subscriber phone number (Malloced)
Definition: channel.h:291
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:522
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:527
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:530
int nochan
Definition: app_dial.c:895
struct ast_channel * chan
Definition: app_dial.c:837
static struct test_val c
FILE * in
Definition: utils/frame.c:33
#define ast_clear_flag64(p, flag)
Definition: utils.h:134

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, connected, DIAL_CALLERID_ABSENT, DIAL_STILLGOING, ast_party_redirecting::from, handle_cause(), ast_party_caller::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, ast_channel::tech, ast_party_redirecting::to, ast_party_dialed::transit_network_select, and ast_party_number::valid.

Referenced by wait_for_answer().

◆ end_bridge_callback()

static void end_bridge_callback ( void *  data)
static

Definition at line 2234 of file app_dial.c.

2235 {
2236  struct ast_channel *chan = data;
2237 
2238  ast_channel_lock(chan);
2240  set_duration_var(chan, "ANSWEREDTIME", ast_channel_get_up_time_ms(chan));
2241  set_duration_var(chan, "DIALEDTIME", ast_channel_get_duration_ms(chan));
2243  ast_channel_unlock(chan);
2244 }
static void set_duration_var(struct ast_channel *chan, const char *var_base, int64_t duration)
Definition: app_dial.c:1227
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:2836
int64_t ast_channel_get_duration_ms(struct ast_channel *chan)
Obtain how long it's been, in milliseconds, since the channel was created.
Definition: channel.c:2821
const char * data

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().

◆ 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 2246 of file app_dial.c.

2246  {
2247  bconfig->end_bridge_callback_data = originator;
2248 }
void * end_bridge_callback_data
Definition: channel.h:1091

References ast_bridge_config::end_bridge_callback_data.

Referenced by dial_exec_full().

◆ get_cid_name()

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

Definition at line 939 of file app_dial.c.

940 {
941  const char *context;
942  const char *exten;
943 
944  ast_channel_lock(chan);
947  ast_channel_unlock(chan);
948 
949  return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
950 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:122
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:120
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:4144

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().

◆ handle_cause()

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

Definition at line 898 of file app_dial.c.

899 {
900  switch(cause) {
901  case AST_CAUSE_BUSY:
902  num->busy++;
903  break;
905  num->congestion++;
906  break;
909  num->nochan++;
910  break;
911  case AST_CAUSE_NO_ANSWER:
913  break;
914  default:
915  num->nochan++;
916  break;
917  }
918 }
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:100
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:154
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:109
int congestion
Definition: app_dial.c:894
int busy
Definition: app_dial.c:893

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().

◆ hanguptree()

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

Definition at line 868 of file app_dial.c.

869 {
870  /* Hang up a tree of stuff */
871  struct chanlist *outgoing;
872 
873  while ((outgoing = AST_LIST_REMOVE_HEAD(out_chans, node))) {
874  /* Hangup any existing lines we have open */
875  if (outgoing->chan && (outgoing->chan != exception)) {
876  if (hangupcause >= 0) {
877  /* This is for the channel drivers */
878  ast_channel_hangupcause_set(outgoing->chan, hangupcause);
879  }
880  ast_hangup(outgoing->chan);
881  }
883  }
884 }
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833

References ast_channel_hangupcause_set(), ast_hangup(), AST_LIST_REMOVE_HEAD, and chanlist_free().

Referenced by dial_exec_full().

◆ load_module()

static int load_module ( void  )
static

Definition at line 3629 of file app_dial.c.

3630 {
3631  int res;
3632 
3635 
3636  return res;
3637 }
static const char app[]
Definition: app_dial.c:700
static int dial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3502
static const char rapp[]
Definition: app_dial.c:701
static int retrydial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3511
#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 920 of file app_dial.c.

921 {
922  char rexten[2] = { exten, '\0' };
923 
924  if (context) {
925  if (!ast_goto_if_exists(chan, context, rexten, pri))
926  return 1;
927  } else {
928  if (!ast_goto_if_exists(chan, ast_channel_context(chan), rexten, pri))
929  return 1;
930  else if (!ast_strlen_zero(ast_channel_macrocontext(chan))) {
931  if (!ast_goto_if_exists(chan, ast_channel_macrocontext(chan), rexten, pri))
932  return 1;
933  }
934  }
935  return 0;
936 }
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)

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

Referenced by retrydial_exec(), and wait_for_answer().

◆ 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 1186 of file app_dial.c.

1187 {
1188  struct chanlist *outgoing;
1189  AST_LIST_TRAVERSE(out_chans, outgoing, node) {
1190  if (!outgoing->chan || outgoing->chan == exception) {
1191  continue;
1192  }
1194  }
1195 }
jack_status_t status
Definition: app_jack.c:146

References ast_channel_publish_dial(), AST_LIST_TRAVERSE, in, NULL, and status.

Referenced by wait_for_answer().

◆ retrydial_exec()

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

Definition at line 3511 of file app_dial.c.

3512 {
3513  char *parse;
3514  const char *context = NULL;
3515  int sleepms = 0, loops = 0, res = -1;
3516  struct ast_flags64 peerflags = { 0, };
3518  AST_APP_ARG(announce);
3519  AST_APP_ARG(sleep);
3520  AST_APP_ARG(retries);
3521  AST_APP_ARG(dialdata);
3522  );
3523 
3524  if (ast_strlen_zero(data)) {
3525  ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
3526  return -1;
3527  }
3528 
3529  parse = ast_strdupa(data);
3531 
3532  if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
3533  sleepms *= 1000;
3534 
3535  if (!ast_strlen_zero(args.retries)) {
3536  loops = atoi(args.retries);
3537  }
3538 
3539  if (!args.dialdata) {
3540  ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
3541  goto done;
3542  }
3543 
3544  if (sleepms < 1000)
3545  sleepms = 10000;
3546 
3547  if (!loops)
3548  loops = -1; /* run forever */
3549 
3550  ast_channel_lock(chan);
3551  context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
3553  ast_channel_unlock(chan);
3554 
3555  res = 0;
3556  while (loops) {
3557  int continue_exec;
3558 
3559  ast_channel_data_set(chan, "Retrying");
3561  ast_moh_stop(chan);
3562 
3563  res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
3564  if (continue_exec)
3565  break;
3566 
3567  if (res == 0) {
3568  if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
3569  if (!ast_strlen_zero(args.announce)) {
3570  if (ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3571  if (!(res = ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3573  } else
3574  ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3575  }
3576  if (!res && sleepms) {
3578  ast_moh_start(chan, NULL, NULL);
3579  res = ast_waitfordigit(chan, sleepms);
3580  }
3581  } else {
3582  if (!ast_strlen_zero(args.announce)) {
3583  if (ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3584  if (!(res = ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3585  res = ast_waitstream(chan, "");
3586  } else
3587  ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3588  }
3589  if (sleepms) {
3591  ast_moh_start(chan, NULL, NULL);
3592  if (!res)
3593  res = ast_waitfordigit(chan, sleepms);
3594  }
3595  }
3596  }
3597 
3598  if (res < 0 || res == AST_PBX_INCOMPLETE) {
3599  break;
3600  } else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
3601  if (onedigit_goto(chan, context, (char) res, 1)) {
3602  res = 0;
3603  break;
3604  }
3605  }
3606  loops--;
3607  }
3608  if (loops == 0)
3609  res = 0;
3610  else if (res == 1)
3611  res = 0;
3612 
3614  ast_moh_stop(chan);
3615  done:
3616  return res;
3617 }
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
Definition: app_dial.c:920
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3176
@ AST_FLAG_MOH
Definition: channel.h:991
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1817
#define ast_test_flag(p, flag)
Definition: utils.h:63

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.

◆ set_duration_var()

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

Definition at line 1227 of file app_dial.c.

1228 {
1229  char buf[32];
1230  char full_var_name[128];
1231 
1232  snprintf(buf, sizeof(buf), "%" PRId64, duration / 1000);
1233  pbx_builtin_setvar_helper(chan, var_base, buf);
1234 
1235  snprintf(full_var_name, sizeof(full_var_name), "%s_MS", var_base);
1236  snprintf(buf, sizeof(buf), "%" PRId64, duration);
1237  pbx_builtin_setvar_helper(chan, full_var_name, buf);
1238 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

References buf, and pbx_builtin_setvar_helper().

Referenced by end_bridge_callback(), and wait_for_answer().

◆ 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 2290 of file app_dial.c.

2291 {
2292  const char *context;
2293  const char *extension;
2294  int priority;
2295 
2296  if (ast_test_flag64(opts, OPT_PEER_H)) {
2297  ast_channel_lock(chan);
2299  ast_channel_unlock(chan);
2301  } else if (ast_test_flag64(opts, OPT_CALLEE_GO_ON)) {
2302  ast_channel_lock(chan);
2306  ast_channel_unlock(chan);
2308  opt_args[OPT_ARG_CALLEE_GO_ON]);
2309  }
2310 }
#define OPT_PEER_H
Definition: app_dial.c:742
#define OPT_CALLEE_GO_ON
Definition: app_dial.c:743
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:622
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:617
static int priority
structure to hold extensions

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().

◆ 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 2135 of file app_dial.c.

2137 {
2138  char callerid[60];
2139  int res;
2140  char *l;
2141 
2142  if (ast_channel_caller(chan)->id.number.valid
2143  && !ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
2144  l = ast_strdupa(ast_channel_caller(chan)->id.number.str);
2146  if (ast_test_flag64(opts, OPT_PRIVACY) ) {
2147  ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
2148  pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
2149  } else {
2150  ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
2152  }
2153  } else {
2154  char *tnam, *tn2;
2155 
2156  tnam = ast_strdupa(ast_channel_name(chan));
2157  /* clean the channel name so slashes don't try to end up in disk file name */
2158  for (tn2 = tnam; *tn2; tn2++) {
2159  if (*tn2 == '/') /* any other chars to be afraid of? */
2160  *tn2 = '=';
2161  }
2162  ast_verb(3, "Privacy-- callerid is empty\n");
2163 
2164  snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", ast_channel_exten(chan), tnam);
2165  l = callerid;
2167  }
2168 
2169  ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
2170 
2171  if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
2172  /* if callerid is set and OPT_SCREEN_NOCALLERID is set also */
2173  ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
2175  } else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
2176  ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
2177  }
2178 
2179  if (pa->privdb_val == AST_PRIVACY_DENY) {
2180  ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
2181  ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
2182  return 0;
2183  } else if (pa->privdb_val == AST_PRIVACY_KILL) {
2184  ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
2185  return 0; /* Is this right? */
2186  } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
2187  ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
2188  return 0; /* is this right??? */
2189  } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
2190  /* Get the user's intro, store it in priv-callerintros/$CID,
2191  unless it is already there-- this should be done before the
2192  call is actually dialed */
2193 
2194  /* make sure the priv-callerintros dir actually exists */
2195  snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
2196  if ((res = ast_mkdir(pa->privintro, 0755))) {
2197  ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
2198  return -1;
2199  }
2200 
2201  snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
2202  if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
2203  /* the DELUX version of this code would allow this caller the
2204  option to hear and retape their previously recorded intro.
2205  */
2206  } else {
2207  int duration; /* for feedback from play_and_wait */
2208  /* the file doesn't exist yet. Let the caller submit his
2209  vocal intro for posterity */
2210  /* priv-recordintro script:
2211  "At the tone, please say your name:"
2212  */
2214  ast_answer(chan);
2215  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 */
2216  /* don't think we'll need a lock removed, we took care of
2217  conflicts by naming the pa.privintro file */
2218  if (res == -1) {
2219  /* Delete the file regardless since they hung up during recording */
2221  if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
2222  ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
2223  else
2224  ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
2225  return -1;
2226  }
2227  if (!ast_streamfile(chan, "vm-dialout", ast_channel_language(chan)) )
2228  ast_waitstream(chan, "");
2229  }
2230  }
2231  return 1; /* success */
2232 }
static int silencethreshold
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
Definition: callerid.c:947
@ THRESHOLD_SILENCE
Definition: dsp.h:73
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1999
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:2214
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
#define AST_PRIVACY_KILL
Definition: privacy.h:32
#define AST_PRIVACY_ALLOW
Definition: privacy.h:31
#define AST_PRIVACY_DENY
Definition: privacy.h:30
int ast_privacy_check(char *dest, char *cid)
Definition: privacy.c:46
#define AST_PRIVACY_TORTURE
Definition: privacy.h:33
char privcid[256]
Definition: app_dial.c:1180
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: main/utils.c:2377

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().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 3619 of file app_dial.c.

3620 {
3621  int res;
3622 
3625 
3626  return res;
3627 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References app, ast_unregister_application(), and rapp.

◆ 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 1206 of file app_dial.c.

1207 {
1208  struct ast_party_connected_line connected_caller;
1209 
1210  ast_party_connected_line_init(&connected_caller);
1211 
1212  ast_channel_lock(peer);
1213  ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(peer));
1214  ast_channel_unlock(peer);
1215  connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1216  if (ast_channel_connected_line_sub(peer, chan, &connected_caller, 0)
1217  && ast_channel_connected_line_macro(peer, chan, &connected_caller, is_caller, 0)) {
1218  ast_channel_update_connected_line(chan, &connected_caller, NULL);
1219  }
1220  ast_party_connected_line_free(&connected_caller);
1221 }
@ AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER
Definition: callerid.h:446
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:9176

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().

◆ valid_priv_reply()

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

Definition at line 1988 of file app_dial.c.

1989 {
1990  if (res < '1')
1991  return 0;
1992  if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
1993  return 1;
1994  if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
1995  return 1;
1996  return 0;
1997 }

References ast_test_flag64, OPT_PRIVACY, and OPT_SCREENING.

◆ 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,
char *  mf_wink,
char *  sf_progress,
char *  sf_wink,
const int  hearpulsing,
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 1240 of file app_dial.c.

1251 {
1252  struct cause_args num = *num_in;
1253  int prestart = num.busy + num.congestion + num.nochan;
1254  int orig = *to;
1255  struct ast_channel *peer = NULL;
1256  struct chanlist *outgoing = AST_LIST_FIRST(out_chans);
1257  /* single is set if only one destination is enabled */
1258  int single = outgoing && !AST_LIST_NEXT(outgoing, node);
1259  int caller_entertained = outgoing
1261  struct ast_str *featurecode = ast_str_alloca(AST_FEATURE_MAX_LEN + 1);
1262  int cc_recall_core_id;
1263  int is_cc_recall;
1264  int cc_frame_received = 0;
1265  int num_ringing = 0;
1266  int sent_ring = 0;
1267  int sent_progress = 0, sent_wink = 0;
1268  struct timeval start = ast_tvnow();
1269  SCOPE_ENTER(3, "%s\n", ast_channel_name(in));
1270 
1271  if (single) {
1272  /* Turn off hold music, etc */
1273  if (!caller_entertained) {
1275  /* If we are calling a single channel, and not providing ringback or music, */
1276  /* then, make them compatible for in-band tone purpose */
1277  if (ast_channel_make_compatible(in, outgoing->chan) < 0) {
1278  /* If these channels can not be made compatible,
1279  * there is no point in continuing. The bridge
1280  * will just fail if it gets that far.
1281  */
1282  *to = -1;
1283  strcpy(pa->status, "CONGESTION");
1285  SCOPE_EXIT_RTN_VALUE(NULL, "%s: can't be made compat with %s\n",
1287  }
1288  }
1289 
1293  }
1294  }
1295 
1296  is_cc_recall = ast_cc_is_recall(in, &cc_recall_core_id, NULL);
1297 
1298  while ((*to = ast_remaining_ms(start, orig)) && !peer) {
1299  struct chanlist *o;
1300  int pos = 0; /* how many channels do we handle */
1301  int numlines = prestart;
1302  struct ast_channel *winner;
1303  struct ast_channel *watchers[AST_MAX_WATCHERS];
1304 
1305  watchers[pos++] = in;
1306  AST_LIST_TRAVERSE(out_chans, o, node) {
1307  /* Keep track of important channels */
1308  if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
1309  watchers[pos++] = o->chan;
1310  numlines++;
1311  }
1312  if (pos == 1) { /* only the input channel is available */
1313  if (numlines == (num.busy + num.congestion + num.nochan)) {
1314  ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1315  if (num.busy)
1316  strcpy(pa->status, "BUSY");
1317  else if (num.congestion)
1318  strcpy(pa->status, "CONGESTION");
1319  else if (num.nochan)
1320  strcpy(pa->status, "CHANUNAVAIL");
1321  } else {
1322  ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1323  }
1324  *to = 0;
1325  if (is_cc_recall) {
1326  ast_cc_failed(cc_recall_core_id, "Everyone is busy/congested for the recall. How sad");
1327  }
1328  SCOPE_EXIT_RTN_VALUE(NULL, "%s: No outging channels available\n", ast_channel_name(in));
1329  }
1330  winner = ast_waitfor_n(watchers, pos, to);
1331  AST_LIST_TRAVERSE(out_chans, o, node) {
1332  struct ast_frame *f;
1333  struct ast_channel *c = o->chan;
1334 
1335  if (c == NULL)
1336  continue;
1338  if (!peer) {
1339  ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1340  if (o->orig_chan_name
1341  && strcmp(o->orig_chan_name, ast_channel_name(c))) {
1342  /*
1343  * The channel name changed so we must generate COLP update.
1344  * Likely because a call pickup channel masqueraded in.
1345  */
1347  } else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1348  if (o->pending_connected_update) {
1349  if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
1352  }
1353  } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1355  }
1356  }
1357  if (o->aoc_s_rate_list) {
1358  size_t encoded_size;
1359  struct ast_aoc_encoded *encoded;
1360  if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1361  ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1362  ast_aoc_destroy_encoded(encoded);
1363  }
1364  }
1365  peer = c;
1366  publish_dial_end_event(in, out_chans, peer, "CANCEL");
1367  ast_copy_flags64(peerflags, o,
1374  ast_channel_dialcontext_set(c, "");
1375  ast_channel_exten_set(c, "");
1376  }
1377  continue;
1378  }
1379  if (c != winner)
1380  continue;
1381  /* here, o->chan == c == winner */
1383  pa->sentringing = 0;
1384  if (!ignore_cc && (f = ast_read(c))) {
1386  /* This channel is forwarding the call, and is capable of CC, so
1387  * be sure to add the new device interface to the list
1388  */
1390  }
1391  ast_frfree(f);
1392  }
1393 
1394  if (o->pending_connected_update) {
1395  /*
1396  * Re-seed the chanlist's connected line information with
1397  * previously acquired connected line info from the incoming
1398  * channel. The previously acquired connected line info could
1399  * have been set through the CONNECTED_LINE dialplan function.
1400  */
1401  o->pending_connected_update = 0;
1405  }
1406 
1407  do_forward(o, &num, peerflags, single, caller_entertained, &orig,
1408  forced_clid, stored_clid);
1409 
1410  if (o->chan) {
1413  if (single
1417  }
1418  }
1419  continue;
1420  }
1421  f = ast_read(winner);
1422  if (!f) {
1425  ast_hangup(c);
1426  c = o->chan = NULL;
1429  continue;
1430  }
1431  switch (f->frametype) {
1432  case AST_FRAME_CONTROL:
1433  switch (f->subclass.integer) {
1434  case AST_CONTROL_ANSWER:
1435  /* This is our guy if someone answered. */
1436  if (!peer) {
1437  ast_trace(-1, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1438  ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1439  if (o->orig_chan_name
1440  && strcmp(o->orig_chan_name, ast_channel_name(c))) {
1441  /*
1442  * The channel name changed so we must generate COLP update.
1443  * Likely because a call pickup channel masqueraded in.
1444  */
1446  } else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1447  if (o->pending_connected_update) {
1448  if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
1451  }
1452  } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1454  }
1455  }
1456  if (o->aoc_s_rate_list) {
1457  size_t encoded_size;
1458  struct ast_aoc_encoded *encoded;
1459  if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1460  ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1461  ast_aoc_destroy_encoded(encoded);
1462  }
1463  }
1464  peer = c;
1465  /* Answer can optionally include a topology */
1466  if (f->subclass.topology) {
1467  /*
1468  * We need to bump the refcount on the topology to prevent it
1469  * from being cleaned up when the frame is cleaned up.
1470  */
1471  config->answer_topology = ao2_bump(f->subclass.topology);
1472  ast_trace(-1, "%s Found topology in frame: %p %p %s\n",
1473  ast_channel_name(peer), f, config->answer_topology,
1474  ast_str_tmp(256, ast_stream_topology_to_str(config->answer_topology, &STR_TMP)));
1475  }
1476 
1477  /* Inform everyone else that they've been canceled.
1478  * The dial end event for the peer will be sent out after
1479  * other Dial options have been handled.
1480  */
1481  publish_dial_end_event(in, out_chans, peer, "CANCEL");
1482  ast_copy_flags64(peerflags, o,
1489  ast_channel_dialcontext_set(c, "");
1490  ast_channel_exten_set(c, "");
1491  if (CAN_EARLY_BRIDGE(peerflags, in, peer)) {
1492  /* Setup early bridge if appropriate */
1494  }
1495  }
1496  /* If call has been answered, then the eventual hangup is likely to be normal hangup */
1499  break;
1500  case AST_CONTROL_BUSY:
1501  ast_verb(3, "%s is busy\n", ast_channel_name(c));
1503  ast_channel_publish_dial(in, c, NULL, "BUSY");
1504  ast_hangup(c);
1505  c = o->chan = NULL;
1508  break;
1510  ast_verb(3, "%s is circuit-busy\n", ast_channel_name(c));
1512  ast_channel_publish_dial(in, c, NULL, "CONGESTION");
1513  ast_hangup(c);
1514  c = o->chan = NULL;
1517  break;
1518  case AST_CONTROL_RINGING:
1519  /* This is a tricky area to get right when using a native
1520  * CC agent. The reason is that we do the best we can to send only a
1521  * single ringing notification to the caller.
1522  *
1523  * Call completion complicates the logic used here. CCNR is typically
1524  * offered during a ringing message. Let's say that party A calls
1525  * parties B, C, and D. B and C do not support CC requests, but D
1526  * does. If we were to receive a ringing notification from B before
1527  * the others, then we would end up sending a ringing message to
1528  * A with no CCNR offer present.
1529  *
1530  * The approach that we have taken is that if we receive a ringing
1531  * response from a party and no CCNR offer is present, we need to
1532  * wait. Specifically, we need to wait until either a) a called party
1533  * offers CCNR in its ringing response or b) all called parties have
1534  * responded in some way to our call and none offers CCNR.
1535  *
1536  * The drawback to this is that if one of the parties has a delayed
1537  * response or, god forbid, one just plain doesn't respond to our
1538  * outgoing call, then this will result in a significant delay between
1539  * when the caller places the call and hears ringback.
1540  *
1541  * Note also that if CC is disabled for this call, then it is perfectly
1542  * fine for ringing frames to get sent through.
1543  */
1544  ++num_ringing;
1545  if (ignore_cc || cc_frame_received || num_ringing == numlines) {
1546  ast_verb(3, "%s is ringing\n", ast_channel_name(c));
1547  /* Setup early media if appropriate */
1548  if (single && !caller_entertained
1549  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1551  }
1554  pa->sentringing++;
1555  }
1556  if (!sent_ring) {
1557  struct timeval now, then;
1558  int64_t diff;
1559 
1560  now = ast_tvnow();
1561 
1564 
1565  then = ast_channel_creationtime(c);
1566  diff = ast_tvzero(then) ? 0 : ast_tvdiff_ms(now, then);
1567  set_duration_var(in, "RINGTIME", diff);
1568 
1571  sent_ring = 1;
1572  }
1573  }
1574  ast_channel_publish_dial(in, c, NULL, "RINGING");
1575  break;
1576  case AST_CONTROL_PROGRESS:
1577  ast_verb(3, "%s is making progress passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1578  /* Setup early media if appropriate */
1579  if (single && !caller_entertained
1580  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1582  }
1584  if (single || (!single && !pa->sentringing)) {
1586  }
1587  }
1588  if (!sent_progress) {
1589  struct timeval now, then;
1590  int64_t diff;
1591 
1592  now = ast_tvnow();
1593 
1596 
1597  then = ast_channel_creationtime(c);
1598  diff = ast_tvzero(then) ? 0 : ast_tvdiff_ms(now, then);
1599  set_duration_var(in, "PROGRESSTIME", diff);
1600 
1603  sent_progress = 1;
1604 
1605  if (!ast_strlen_zero(mf_progress)) {
1606  ast_verb(3,
1607  "Sending MF '%s' to %s as result of "
1608  "receiving a PROGRESS message.\n",
1609  mf_progress, hearpulsing ? "parties" : "called party");
1610  ast_mf_stream(c, (hearpulsing ? NULL : in),
1611  (hearpulsing ? in : NULL), mf_progress, 50, 55, 120, 65, 0);
1612  }
1613  if (!ast_strlen_zero(sf_progress)) {
1614  ast_verb(3,
1615  "Sending SF '%s' to %s as result of "
1616  "receiving a PROGRESS message.\n",
1617  sf_progress, (hearpulsing ? "parties" : "called party"));
1618  ast_sf_stream(c, (hearpulsing ? NULL : in),
1619  (hearpulsing ? in : NULL), sf_progress, 0, 0);
1620  }
1621  if (!ast_strlen_zero(dtmf_progress)) {
1622  ast_verb(3,
1623  "Sending DTMF '%s' to the called party as result of "
1624  "receiving a PROGRESS message.\n",
1625  dtmf_progress);
1626  ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
1627  }
1628  }
1629  ast_channel_publish_dial(in, c, NULL, "PROGRESS");
1630  break;
1631  case AST_CONTROL_WINK:
1632  ast_verb(3, "%s winked, passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1633  if (!sent_wink) {
1634  sent_wink = 1;
1635  if (!ast_strlen_zero(mf_wink)) {
1636  ast_verb(3,
1637  "Sending MF '%s' to %s as result of "
1638  "receiving a WINK message.\n",
1639  mf_wink, (hearpulsing ? "parties" : "called party"));
1640  ast_mf_stream(c, (hearpulsing ? NULL : in),
1641  (hearpulsing ? in : NULL), mf_wink, 50, 55, 120, 65, 0);
1642  }
1643  if (!ast_strlen_zero(sf_wink)) {
1644  ast_verb(3,
1645  "Sending SF '%s' to %s as result of "
1646  "receiving a WINK message.\n",
1647  sf_wink, (hearpulsing ? "parties" : "called party"));
1648  ast_sf_stream(c, (hearpulsing ? NULL : in),
1649  (hearpulsing ? in : NULL), sf_wink, 0, 0);
1650  }
1651  }
1653  break;
1654  case AST_CONTROL_VIDUPDATE:
1655  case AST_CONTROL_SRCUPDATE:
1656  case AST_CONTROL_SRCCHANGE:
1657  if (!single || caller_entertained) {
1658  break;
1659  }
1660  ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1663  break;
1666  ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(in));
1667  break;
1668  }
1669  if (!single) {
1671 
1672  ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n",
1678  o->pending_connected_update = 1;
1679  break;
1680  }
1681  if (ast_channel_connected_line_sub(c, in, f, 1) &&
1682  ast_channel_connected_line_macro(c, in, f, 1, 1)) {
1684  }
1685  break;
1686  case AST_CONTROL_AOC:
1687  {
1688  struct ast_aoc_decoded *decoded = ast_aoc_decode(f->data.ptr, f->datalen, o->chan);
1689  if (decoded && (ast_aoc_get_msg_type(decoded) == AST_AOC_S)) {
1691  o->aoc_s_rate_list = decoded;
1692  } else {
1693  ast_aoc_destroy_decoded(decoded);
1694  }
1695  }
1696  break;
1698  if (!single) {
1699  /*
1700  * Redirecting updates to the caller make sense only on single
1701  * calls.
1702  */
1703  break;
1704  }
1706  ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(in));
1707  break;
1708  }
1709  ast_verb(3, "%s redirecting info has changed, passing it to %s\n",
1711  if (ast_channel_redirecting_sub(c, in, f, 1) &&
1712  ast_channel_redirecting_macro(c, in, f, 1, 1)) {
1714  }
1715  pa->sentringing = 0;
1716  break;
1718  ast_verb(3, "%s is proceeding passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1719  if (single && !caller_entertained
1720  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1722  }
1725  ast_channel_publish_dial(in, c, NULL, "PROCEEDING");
1726  break;
1727  case AST_CONTROL_HOLD:
1728  /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1729  ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(c));
1731  break;
1732  case AST_CONTROL_UNHOLD:
1733  /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1734  ast_verb(3, "Call on %s left from hold\n", ast_channel_name(c));
1736  break;
1737  case AST_CONTROL_OFFHOOK:
1738  case AST_CONTROL_FLASH:
1739  /* Ignore going off hook and flash */
1740  break;
1741  case AST_CONTROL_CC:
1742  if (!ignore_cc) {
1744  cc_frame_received = 1;
1745  }
1746  break;
1749  break;
1750  case -1:
1751  if (single && !caller_entertained) {
1752  ast_verb(3, "%s stopped sounds\n", ast_channel_name(c));
1753  ast_indicate(in, -1);
1754  pa->sentringing = 0;
1755  }
1756  break;
1757  default:
1758  ast_debug(1, "Dunno what to do with control type %d\n", f->subclass.integer);
1759  break;
1760  }
1761  break;
1762  case AST_FRAME_VIDEO:
1763  case AST_FRAME_VOICE:
1764  case AST_FRAME_IMAGE:
1765  if (caller_entertained) {
1766  break;
1767  }
1768  /* Fall through */
1769  case AST_FRAME_TEXT:
1770  if (single && ast_write(in, f)) {
1771  ast_log(LOG_WARNING, "Unable to write frametype: %u\n",
1772  f->frametype);
1773  }
1774  break;
1775  case AST_FRAME_HTML:
1777  && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1778  ast_log(LOG_WARNING, "Unable to send URL\n");
1779  }
1780  break;
1781  default:
1782  break;
1783  }
1784  ast_frfree(f);
1785  } /* end for */
1786  if (winner == in) {
1787  struct ast_frame *f = ast_read(in);
1788 #if 0
1789  if (f && (f->frametype != AST_FRAME_VOICE))
1790  printf("Frame type: %d, %d\n", f->frametype, f->subclass);
1791  else if (!f || (f->frametype != AST_FRAME_VOICE))
1792  printf("Hangup received on %s\n", in->name);
1793 #endif
1794  if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP))) {
1795  /* Got hung up */
1796  *to = -1;
1797  strcpy(pa->status, "CANCEL");
1798  pa->canceled = 1;
1799  publish_dial_end_event(in, out_chans, NULL, pa->status);
1800  if (f) {
1801  if (f->data.uint32) {
1803  }
1804  ast_frfree(f);
1805  }
1806  if (is_cc_recall) {
1807  ast_cc_completed(in, "CC completed, although the caller hung up (cancelled)");
1808  }
1809  SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller hung up\n", ast_channel_name(in));
1810  }
1811 
1812  /* now f is guaranteed non-NULL */
1813  if (f->frametype == AST_FRAME_DTMF) {
1814  if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
1815  const char *context;
1817  context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
1818  if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
1819  ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
1820  *to = 0;
1821  *result = f->subclass.integer;
1822  strcpy(pa->status, "CANCEL");
1823  pa->canceled = 1;
1824  publish_dial_end_event(in, out_chans, NULL, pa->status);
1825  ast_frfree(f);
1827  if (is_cc_recall) {
1828  ast_cc_completed(in, "CC completed, but the caller used DTMF to exit");
1829  }
1830  SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller pressed %c to end call\n",
1832  }
1834  }
1835 
1836  if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
1837  detect_disconnect(in, f->subclass.integer, &featurecode)) {
1838  ast_verb(3, "User requested call disconnect.\n");
1839  *to = 0;
1840  strcpy(pa->status, "CANCEL");
1841  pa->canceled = 1;
1842  publish_dial_end_event(in, out_chans, NULL, pa->status);
1843  ast_frfree(f);
1844  if (is_cc_recall) {
1845  ast_cc_completed(in, "CC completed, but the caller hung up with DTMF");
1846  }
1847  SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller requested disconnect\n",
1848  ast_channel_name(in));
1849  }
1850  }
1851 
1852  /* Send the frame from the in channel to all outgoing channels. */
1853  AST_LIST_TRAVERSE(out_chans, o, node) {
1854  if (!o->chan || !ast_test_flag64(o, DIAL_STILLGOING)) {
1855  /* This outgoing channel has died so don't send the frame to it. */
1856  continue;
1857  }
1858  switch (f->frametype) {
1859  case AST_FRAME_HTML:
1860  /* Forward HTML stuff */
1862  && ast_channel_sendhtml(o->chan, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1863  ast_log(LOG_WARNING, "Unable to send URL\n");
1864  }
1865  break;
1866  case AST_FRAME_VIDEO:
1867  case AST_FRAME_VOICE:
1868  case AST_FRAME_IMAGE:
1869  if (!single || caller_entertained) {
1870  /*
1871  * We are calling multiple parties or caller is being
1872  * entertained and has thus not been made compatible.
1873  * No need to check any other called parties.
1874  */
1875  goto skip_frame;
1876  }
1877  /* Fall through */
1878  case AST_FRAME_TEXT:
1879  case AST_FRAME_DTMF_BEGIN:
1880  case AST_FRAME_DTMF_END:
1881  if (ast_write(o->chan, f)) {
1882  ast_log(LOG_WARNING, "Unable to forward frametype: %u\n",
1883  f->frametype);
1884  }
1885  break;
1886  case AST_FRAME_CONTROL:
1887  switch (f->subclass.integer) {
1888  case AST_CONTROL_HOLD:
1889  ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(o->chan));
1891  break;
1892  case AST_CONTROL_UNHOLD:
1893  ast_verb(3, "Call on %s left from hold\n", ast_channel_name(o->chan));
1895  break;
1896  case AST_CONTROL_VIDUPDATE:
1897  case AST_CONTROL_SRCUPDATE:
1898  case AST_CONTROL_SRCCHANGE:
1899  if (!single || caller_entertained) {
1900  /*
1901  * We are calling multiple parties or caller is being
1902  * entertained and has thus not been made compatible.
1903  * No need to check any other called parties.
1904  */
1905  goto skip_frame;
1906  }
1907  ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1910  break;
1913  ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(o->chan));
1914  break;
1915  }
1916  if (ast_channel_connected_line_sub(in, o->chan, f, 1) &&
1917  ast_channel_connected_line_macro(in, o->chan, f, 0, 1)) {
1919  }
1920  break;
1923  ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(o->chan));
1924  break;
1925  }
1926  if (ast_channel_redirecting_sub(in, o->chan, f, 1) &&
1927  ast_channel_redirecting_macro(in, o->chan, f, 0, 1)) {
1929  }
1930  break;
1931  default:
1932  /* We are not going to do anything with this frame. */
1933  goto skip_frame;
1934  }
1935  break;
1936  default:
1937  /* We are not going to do anything with this frame. */
1938  goto skip_frame;
1939  }
1940  }
1941 skip_frame:;
1942  ast_frfree(f);
1943  }
1944  }
1945 
1946  if (!*to || ast_check_hangup(in)) {
1947  ast_verb(3, "Nobody picked up in %d ms\n", orig);
1948  publish_dial_end_event(in, out_chans, NULL, "NOANSWER");
1949  }
1950 
1951  if (is_cc_recall) {
1952  ast_cc_completed(in, "Recall completed!");
1953  }
1954  SCOPE_EXIT_RTN_VALUE(peer, "%s: %s%s\n", ast_channel_name(in),
1955  peer ? "Answered by " : "No answer", peer ? ast_channel_name(peer) : "");
1956 }
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
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
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:313
@ AST_AOC_S
Definition: aoc.h:64
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
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:969
#define AST_MAX_WATCHERS
Definition: app_dial.c:886
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:1186
static void update_connected_line_from_peer(struct ast_channel *chan, struct ast_channel *peer, int is_caller)
Definition: app_dial.c:1206
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode)
Definition: app_dial.c:1958
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
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
int ast_cc_completed(struct ast_channel *chan, const char *const debug,...)
Indicate recall has been acknowledged.
Definition: ccss.c:3840
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
Definition: ccss.c:3877
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:6706
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:2048
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:5179
struct timeval ast_channel_creationtime(struct ast_channel *chan)
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:8868
const char * ast_hangup_cause_to_dial_status(int hangup_cause)
Convert a hangup cause to a publishable dial status.
Definition: dial.c:753
int ast_sf_stream(struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *chan2, const char *digits, int frequency, int is_external)
Send a string of SF digits to a channel.
Definition: main/app.c:1167
int ast_mf_stream(struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *chan2, 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:1183
#define AST_FRAME_DTMF
@ AST_FRAME_VIDEO
@ AST_FRAME_HTML
@ AST_FRAME_IMAGE
@ AST_FRAME_DTMF_BEGIN
@ AST_FRAME_VOICE
@ AST_FRAME_TEXT
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_WINK
@ AST_CONTROL_OFFHOOK
@ AST_CONTROL_BUSY
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_CC
@ AST_CONTROL_ANSWER
@ AST_CONTROL_HOLD
@ AST_CONTROL_FLASH
@ AST_CONTROL_AOC
@ AST_CONTROL_SRCCHANGE
@ AST_CONTROL_PVT_CAUSE_CODE
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
#define ast_str_alloca(init_len)
Definition: strings.h:826
struct ast_stream_topology * topology
Support for dynamic strings.
Definition: strings.h:604
struct ast_aoc_decoded * aoc_s_rate_list
Definition: app_dial.c:851
struct ast_party_connected_line connected
Definition: app_dial.c:848
char * orig_chan_name
Definition: app_dial.c:845
unsigned int pending_connected_update
Definition: app_dial.c:850
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: main/utils.c:2179
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:105

References 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_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_CONTROL_WINK, 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_sf_stream(), 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, privacy_args::canceled, chanlist::chan, config, cause_args::congestion, chanlist::connected, 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_WARNING, 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(), result, 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().

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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "ccss", }
static

Definition at line 3629 of file app_dial.c.

◆ app

const char app[] = "Dial"
static

Definition at line 700 of file app_dial.c.

Referenced by unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 3644 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 << 45) }, [ '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'