Asterisk - The Open Source Telephony Project GIT-master-4f52ed6
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_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_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 }, [ '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 839 of file app_dial.c.

◆ CAN_EARLY_BRIDGE

#define CAN_EARLY_BRIDGE (   flags,
  chan,
  peer 
)

Definition at line 778 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 695 of file app_dial.c.

◆ DIAL_NOFORWARDHTML

#define DIAL_NOFORWARDHTML   (1LLU << 32)

Definition at line 694 of file app_dial.c.

◆ DIAL_STILLGOING

#define DIAL_STILLGOING   (1LLU << 31)

Definition at line 693 of file app_dial.c.

◆ OPT_CALLEE_GO_ON

#define OPT_CALLEE_GO_ON   (1LLU << 36)

Definition at line 698 of file app_dial.c.

◆ OPT_CALLER_ANSWER

#define OPT_CALLER_ANSWER   (1LLU << 40)

Definition at line 702 of file app_dial.c.

◆ OPT_CANCEL_ELSEWHERE

#define OPT_CANCEL_ELSEWHERE   (1LLU << 34)

Definition at line 696 of file app_dial.c.

◆ OPT_CANCEL_TIMEOUT

#define OPT_CANCEL_TIMEOUT   (1LLU << 37)

Definition at line 699 of file app_dial.c.

◆ OPT_FORCE_CID_PRES

#define OPT_FORCE_CID_PRES   (1LLU << 39)

Definition at line 701 of file app_dial.c.

◆ OPT_FORCE_CID_TAG

#define OPT_FORCE_CID_TAG   (1LLU << 38)

Definition at line 700 of file app_dial.c.

◆ OPT_HANGUPCAUSE

#define OPT_HANGUPCAUSE   (1LLU << 44)

Definition at line 706 of file app_dial.c.

◆ OPT_HEARPULSING

#define OPT_HEARPULSING   (1LLU << 45)

Definition at line 707 of file app_dial.c.

◆ OPT_PEER_H

#define OPT_PEER_H   (1LLU << 35)

Definition at line 697 of file app_dial.c.

◆ OPT_PREDIAL_CALLEE

#define OPT_PREDIAL_CALLEE   (1LLU << 41)

Definition at line 703 of file app_dial.c.

◆ OPT_PREDIAL_CALLER

#define OPT_PREDIAL_CALLER   (1LLU << 42)

Definition at line 704 of file app_dial.c.

◆ OPT_RING_WITH_EARLY_MEDIA

#define OPT_RING_WITH_EARLY_MEDIA   (1LLU << 43)

Definition at line 705 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_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 659 of file app_dial.c.

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

◆ anonymous enum

anonymous enum
Enumerator
OPT_ARG_ANNOUNCE 
OPT_ARG_SENDDTMF 
OPT_ARG_GOTO 
OPT_ARG_DURATION_LIMIT 
OPT_ARG_MUSICBACK 
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 709 of file app_dial.c.

709 {
729 /* note: this entry _MUST_ be the last one in the enum */
731};
@ OPT_ARG_CALLEE_GO_ON
Definition: app_dial.c:717
@ OPT_ARG_SENDDTMF
Definition: app_dial.c:711
@ OPT_ARG_DURATION_STOP
Definition: app_dial.c:719
@ OPT_ARG_PREDIAL_CALLEE
Definition: app_dial.c:726
@ OPT_ARG_RINGBACK
Definition: app_dial.c:715
@ OPT_ARG_MUSICBACK
Definition: app_dial.c:714
@ OPT_ARG_CALLEE_GOSUB
Definition: app_dial.c:716
@ OPT_ARG_HANGUPCAUSE
Definition: app_dial.c:728
@ OPT_ARG_FORCE_CID_PRES
Definition: app_dial.c:725
@ OPT_ARG_ANNOUNCE
Definition: app_dial.c:710
@ OPT_ARG_GOTO
Definition: app_dial.c:712
@ OPT_ARG_DURATION_LIMIT
Definition: app_dial.c:713
@ OPT_ARG_ORIGINAL_CLID
Definition: app_dial.c:722
@ OPT_ARG_OPERMODE
Definition: app_dial.c:720
@ OPT_ARG_FORCECLID
Definition: app_dial.c:723
@ OPT_ARG_PREDIAL_CALLER
Definition: app_dial.c:727
@ OPT_ARG_ARRAY_SIZE
Definition: app_dial.c:730
@ OPT_ARG_PRIVACY
Definition: app_dial.c:718
@ OPT_ARG_SCREEN_NOINTRO
Definition: app_dial.c:721
@ OPT_ARG_FORCE_CID_TAG
Definition: app_dial.c:724

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 3535 of file app_dial.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3535 of file app_dial.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 3535 of file app_dial.c.

◆ chanlist_free()

static void chanlist_free ( struct chanlist outgoing)
static

Definition at line 813 of file app_dial.c.

814{
816 ast_aoc_destroy_decoded(outgoing->aoc_s_rate_list);
817 ast_free(outgoing->orig_chan_name);
819}
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 1911 of file app_dial.c.

1912{
1913 char disconnect_code[AST_FEATURE_MAX_LEN];
1914 int res;
1915
1916 ast_str_append(featurecode, 1, "%c", code);
1917
1918 res = ast_get_builtin_feature(chan, "disconnect", disconnect_code, sizeof(disconnect_code));
1919 if (res) {
1920 ast_str_reset(*featurecode);
1921 return 0;
1922 }
1923
1924 if (strlen(disconnect_code) > ast_str_strlen(*featurecode)) {
1925 /* Could be a partial match, anyway */
1926 if (strncmp(disconnect_code, ast_str_buffer(*featurecode), ast_str_strlen(*featurecode))) {
1927 ast_str_reset(*featurecode);
1928 }
1929 return 0;
1930 }
1931
1932 if (strcmp(disconnect_code, ast_str_buffer(*featurecode))) {
1933 ast_str_reset(*featurecode);
1934 return 0;
1935 }
1936
1937 return 1;
1938}
#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:1136
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:758
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:693
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730

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

3394{
3395 struct ast_flags64 peerflags;
3396
3397 memset(&peerflags, 0, sizeof(peerflags));
3398
3399 return dial_exec_full(chan, data, &peerflags, NULL);
3400}
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
Definition: app_dial.c:2265
#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.

Referenced by load_module().

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

2266{
2267 int res = -1; /* default: error */
2268 char *rest, *cur; /* scan the list of destinations */
2269 struct dial_head out_chans = AST_LIST_HEAD_NOLOCK_INIT_VALUE; /* list of destinations */
2270 struct chanlist *outgoing;
2271 struct chanlist *tmp;
2272 struct ast_channel *peer = NULL;
2273 int to; /* timeout */
2274 struct cause_args num = { chan, 0, 0, 0 };
2275 int cause, hanguptreecause = -1;
2276
2277 struct ast_bridge_config config = { { 0, } };
2278 struct timeval calldurationlimit = { 0, };
2279 char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress = NULL;
2280 char *mf_progress = NULL, *mf_wink = NULL;
2281 char *sf_progress = NULL, *sf_wink = NULL;
2282 struct privacy_args pa = {
2283 .sentringing = 0,
2284 .privdb_val = 0,
2285 .status = "INVALIDARGS",
2286 .canceled = 0,
2287 };
2288 int sentringing = 0, moh = 0;
2289 const char *outbound_group = NULL;
2290 int result = 0;
2291 char *parse;
2292 int opermode = 0;
2293 int delprivintro = 0;
2296 AST_APP_ARG(timeout);
2299 );
2300 struct ast_flags64 opts = { 0, };
2301 char *opt_args[OPT_ARG_ARRAY_SIZE];
2302 int fulldial = 0, num_dialed = 0;
2303 int ignore_cc = 0;
2304 char device_name[AST_CHANNEL_NAME];
2305 char forced_clid_name[AST_MAX_EXTENSION];
2306 char stored_clid_name[AST_MAX_EXTENSION];
2307 int force_forwards_only; /*!< TRUE if force CallerID on call forward only. Legacy behaviour.*/
2308 /*!
2309 * \brief Forced CallerID party information to send.
2310 * \note This will not have any malloced strings so do not free it.
2311 */
2312 struct ast_party_id forced_clid;
2313 /*!
2314 * \brief Stored CallerID information if needed.
2315 *
2316 * \note If OPT_ORIGINAL_CLID set then this is the o option
2317 * CallerID. Otherwise it is the dialplan extension and hint
2318 * name.
2319 *
2320 * \note This will not have any malloced strings so do not free it.
2321 */
2322 struct ast_party_id stored_clid;
2323 /*!
2324 * \brief CallerID party information to store.
2325 * \note This will not have any malloced strings so do not free it.
2326 */
2327 struct ast_party_caller caller;
2328 int max_forwards;
2329 SCOPE_ENTER(1, "%s: Data: %s\n", ast_channel_name(chan), data);
2330
2331 /* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
2332 ast_channel_lock(chan);
2334 pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
2335 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
2336 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
2337 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
2338 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME_MS", "");
2339 pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
2340 pbx_builtin_setvar_helper(chan, "DIALEDTIME_MS", "");
2341 pbx_builtin_setvar_helper(chan, "RINGTIME", "");
2342 pbx_builtin_setvar_helper(chan, "RINGTIME_MS", "");
2343 pbx_builtin_setvar_helper(chan, "PROGRESSTIME", "");
2344 pbx_builtin_setvar_helper(chan, "PROGRESSTIME_MS", "");
2347 ast_channel_unlock(chan);
2348
2349 if (max_forwards <= 0) {
2350 ast_log(LOG_WARNING, "Cannot place outbound call from channel '%s'. Max forwards exceeded\n",
2351 ast_channel_name(chan));
2352 pbx_builtin_setvar_helper(chan, "DIALSTATUS", "BUSY");
2353 SCOPE_EXIT_RTN_VALUE(-1, "%s: Max forwards exceeded\n", ast_channel_name(chan));
2354 }
2355
2356 if (ast_check_hangup_locked(chan)) {
2357 /*
2358 * Caller hung up before we could dial. If dial is executed
2359 * within an AGI then the AGI has likely eaten all queued
2360 * frames before executing the dial in DeadAGI mode. With
2361 * the caller hung up and no pending frames from the caller's
2362 * read queue, dial would not know that the call has hung up
2363 * until a called channel answers. It is rather annoying to
2364 * whoever just answered the non-existent call.
2365 *
2366 * Dial should not continue execution in DeadAGI mode, hangup
2367 * handlers, or the h exten.
2368 */
2369 ast_verb(3, "Caller hung up before dial.\n");
2370 pbx_builtin_setvar_helper(chan, "DIALSTATUS", "CANCEL");
2371 SCOPE_EXIT_RTN_VALUE(-1, "%s: Caller hung up before dial\n", ast_channel_name(chan));
2372 }
2373
2374 parse = ast_strdupa(data ?: "");
2375
2377
2378 if (!ast_strlen_zero(args.options) &&
2379 ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
2380 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2381 goto done;
2382 }
2383
2384 if (ast_cc_call_init(chan, &ignore_cc)) {
2385 goto done;
2386 }
2387
2389 delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
2390
2391 if (delprivintro < 0 || delprivintro > 1) {
2392 ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
2393 delprivintro = 0;
2394 }
2395 }
2396
2397 if (!ast_test_flag64(&opts, OPT_RINGBACK)) {
2398 opt_args[OPT_ARG_RINGBACK] = NULL;
2399 }
2400
2401 if (ast_test_flag64(&opts, OPT_OPERMODE)) {
2402 opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
2403 ast_verb(3, "Setting operator services mode to %d.\n", opermode);
2404 }
2405
2407 calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
2408 if (!calldurationlimit.tv_sec) {
2409 ast_log(LOG_WARNING, "Dial does not accept S(%s)\n", opt_args[OPT_ARG_DURATION_STOP]);
2410 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2411 goto done;
2412 }
2413 ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
2414 }
2415
2416 if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
2417 sf_wink = opt_args[OPT_ARG_SENDDTMF];
2418 dtmfcalled = strsep(&sf_wink, ":");
2419 dtmfcalling = strsep(&sf_wink, ":");
2420 dtmf_progress = strsep(&sf_wink, ":");
2421 mf_progress = strsep(&sf_wink, ":");
2422 mf_wink = strsep(&sf_wink, ":");
2423 sf_progress = strsep(&sf_wink, ":");
2424 }
2425
2427 if (ast_bridge_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
2428 goto done;
2429 }
2430
2431 /* Setup the forced CallerID information to send if used. */
2432 ast_party_id_init(&forced_clid);
2433 force_forwards_only = 0;
2434 if (ast_test_flag64(&opts, OPT_FORCECLID)) {
2435 if (ast_strlen_zero(opt_args[OPT_ARG_FORCECLID])) {
2436 ast_channel_lock(chan);
2437 forced_clid.number.str = ast_strdupa(ast_channel_exten(chan));
2438 ast_channel_unlock(chan);
2439 forced_clid_name[0] = '\0';
2440 forced_clid.name.str = (char *) get_cid_name(forced_clid_name,
2441 sizeof(forced_clid_name), chan);
2442 force_forwards_only = 1;
2443 } else {
2444 /* Note: The opt_args[OPT_ARG_FORCECLID] string value is altered here. */
2445 ast_callerid_parse(opt_args[OPT_ARG_FORCECLID], &forced_clid.name.str,
2446 &forced_clid.number.str);
2447 }
2448 if (!ast_strlen_zero(forced_clid.name.str)) {
2449 forced_clid.name.valid = 1;
2450 }
2451 if (!ast_strlen_zero(forced_clid.number.str)) {
2452 forced_clid.number.valid = 1;
2453 }
2454 }
2456 && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_TAG])) {
2457 forced_clid.tag = opt_args[OPT_ARG_FORCE_CID_TAG];
2458 }
2459 forced_clid.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
2461 && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_PRES])) {
2462 int pres;
2463
2465 if (0 <= pres) {
2466 forced_clid.number.presentation = pres;
2467 }
2468 }
2469
2470 /* Setup the stored CallerID information if needed. */
2471 ast_party_id_init(&stored_clid);
2472 if (ast_test_flag64(&opts, OPT_ORIGINAL_CLID)) {
2473 if (ast_strlen_zero(opt_args[OPT_ARG_ORIGINAL_CLID])) {
2474 ast_channel_lock(chan);
2475 ast_party_id_set_init(&stored_clid, &ast_channel_caller(chan)->id);
2476 if (!ast_strlen_zero(ast_channel_caller(chan)->id.name.str)) {
2477 stored_clid.name.str = ast_strdupa(ast_channel_caller(chan)->id.name.str);
2478 }
2479 if (!ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
2480 stored_clid.number.str = ast_strdupa(ast_channel_caller(chan)->id.number.str);
2481 }
2482 if (!ast_strlen_zero(ast_channel_caller(chan)->id.subaddress.str)) {
2483 stored_clid.subaddress.str = ast_strdupa(ast_channel_caller(chan)->id.subaddress.str);
2484 }
2485 if (!ast_strlen_zero(ast_channel_caller(chan)->id.tag)) {
2486 stored_clid.tag = ast_strdupa(ast_channel_caller(chan)->id.tag);
2487 }
2488 ast_channel_unlock(chan);
2489 } else {
2490 /* Note: The opt_args[OPT_ARG_ORIGINAL_CLID] string value is altered here. */
2491 ast_callerid_parse(opt_args[OPT_ARG_ORIGINAL_CLID], &stored_clid.name.str,
2492 &stored_clid.number.str);
2493 if (!ast_strlen_zero(stored_clid.name.str)) {
2494 stored_clid.name.valid = 1;
2495 }
2496 if (!ast_strlen_zero(stored_clid.number.str)) {
2497 stored_clid.number.valid = 1;
2498 }
2499 }
2500 } else {
2501 /*
2502 * In case the new channel has no preset CallerID number by the
2503 * channel driver, setup the dialplan extension and hint name.
2504 */
2505 stored_clid_name[0] = '\0';
2506 stored_clid.name.str = (char *) get_cid_name(stored_clid_name,
2507 sizeof(stored_clid_name), chan);
2508 if (ast_strlen_zero(stored_clid.name.str)) {
2509 stored_clid.name.str = NULL;
2510 } else {
2511 stored_clid.name.valid = 1;
2512 }
2513 ast_channel_lock(chan);
2514 stored_clid.number.str = ast_strdupa(ast_channel_exten(chan));
2515 stored_clid.number.valid = 1;
2516 ast_channel_unlock(chan);
2517 }
2518
2519 if (ast_test_flag64(&opts, OPT_RESETCDR)) {
2521 }
2524
2526 res = setup_privacy_args(&pa, &opts, opt_args, chan);
2527 if (res <= 0)
2528 goto out;
2529 res = -1; /* reset default */
2530 }
2531
2532 if (continue_exec)
2533 *continue_exec = 0;
2534
2535 /* If a channel group has been specified, get it for use when we create peer channels */
2536
2537 ast_channel_lock(chan);
2538 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
2539 outbound_group = ast_strdupa(outbound_group);
2540 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
2541 } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
2542 outbound_group = ast_strdupa(outbound_group);
2543 }
2544 ast_channel_unlock(chan);
2545
2546 /* Set per dial instance flags. These flags are also passed back to RetryDial. */
2550
2551 /* PREDIAL: Run gosub on the caller's channel */
2553 && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {
2555 ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER], 0);
2556 }
2557
2558 /* loop through the list of dial destinations */
2559 rest = args.peers;
2560 while ((cur = strsep(&rest, "&"))) {
2561 struct ast_channel *tc; /* channel for this destination */
2562 char *number;
2563 char *tech;
2564 int i;
2565 size_t tech_len;
2566 size_t number_len;
2567 struct ast_stream_topology *topology;
2568 struct ast_stream *stream;
2569
2570 cur = ast_strip(cur);
2571 if (ast_strlen_zero(cur)) {
2572 /* No tech/resource in this position. */
2573 continue;
2574 }
2575
2576 /* Get a technology/resource pair */
2577 number = cur;
2578 tech = strsep(&number, "/");
2579
2580 num_dialed++;
2581 if (ast_strlen_zero(number)) {
2582 ast_log(LOG_WARNING, "Dial argument takes format (technology/resource)\n");
2583 goto out;
2584 }
2585
2586 tech_len = strlen(tech) + 1;
2587 number_len = strlen(number) + 1;
2588 tmp = ast_calloc(1, sizeof(*tmp) + (2 * tech_len) + number_len);
2589 if (!tmp) {
2590 goto out;
2591 }
2592
2593 /* Save tech, number, and interface. */
2594 cur = tmp->stuff;
2595 strcpy(cur, tech);
2596 tmp->tech = cur;
2597 cur += tech_len;
2598 strcpy(cur, tech);
2599 cur[tech_len - 1] = '/';
2600 tmp->interface = cur;
2601 cur += tech_len;
2602 strcpy(cur, number);
2603 tmp->number = cur;
2604
2605 if (opts.flags) {
2606 /* Set per outgoing call leg options. */
2607 ast_copy_flags64(tmp, &opts,
2617 }
2618
2619 /* Request the peer */
2620
2621 ast_channel_lock(chan);
2622 /*
2623 * Seed the chanlist's connected line information with previously
2624 * acquired connected line info from the incoming channel. The
2625 * previously acquired connected line info could have been set
2626 * through the CONNECTED_LINE dialplan function.
2627 */
2629
2631
2632 ast_channel_unlock(chan);
2633
2634 for (i = 0; i < ast_stream_topology_get_count(topology); ++i) {
2635 stream = ast_stream_topology_get_stream(topology, i);
2636 /* For both recvonly and sendonly the stream state reflects our state, that is we
2637 * are receiving only and we are sending only. Since we are requesting a
2638 * channel for the peer, we need to swap this to reflect what we will be doing.
2639 * That is, if we are receiving from Alice then we want to be sending to Bob,
2640 * so swap recvonly to sendonly and vice versa.
2641 */
2644 } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_SENDONLY) {
2646 }
2647 }
2648
2649 tc = ast_request_with_stream_topology(tmp->tech, topology, NULL, chan, tmp->number, &cause);
2650
2651 ast_stream_topology_free(topology);
2652
2653 if (!tc) {
2654 /* If we can't, just go on to the next call */
2655 /* Failure doesn't necessarily mean user error. DAHDI channels could be busy. */
2656 ast_log(LOG_NOTICE, "Unable to create channel of type '%s' (cause %d - %s)\n",
2657 tmp->tech, cause, ast_cause2str(cause));
2658 handle_cause(cause, &num);
2659 if (!rest) {
2660 /* we are on the last destination */
2661 ast_channel_hangupcause_set(chan, cause);
2662 }
2663 if (!ignore_cc && (cause == AST_CAUSE_BUSY || cause == AST_CAUSE_CONGESTION)) {
2664 if (!ast_cc_callback(chan, tmp->tech, tmp->number, ast_cc_busy_interface)) {
2665 ast_cc_extension_monitor_add_dialstring(chan, tmp->interface, "");
2666 }
2667 }
2669 continue;
2670 }
2671
2672 ast_channel_get_device_name(tc, device_name, sizeof(device_name));
2673 if (!ignore_cc) {
2674 ast_cc_extension_monitor_add_dialstring(chan, tmp->interface, device_name);
2675 }
2676
2677 ast_channel_lock_both(tc, chan);
2679
2680 pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", tmp->number);
2681
2682 /* Setup outgoing SDP to match incoming one */
2683 if (!AST_LIST_FIRST(&out_chans) && !rest && CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
2684 /* We are on the only destination. */
2686 }
2687
2688 /* Inherit specially named variables from parent channel */
2692
2693 ast_channel_appl_set(tc, "AppDial");
2694 ast_channel_data_set(tc, "(Outgoing Line)");
2695
2696 memset(ast_channel_whentohangup(tc), 0, sizeof(*ast_channel_whentohangup(tc)));
2697
2698 /* Determine CallerID to store in outgoing channel. */
2700 if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
2701 caller.id = stored_clid;
2702 ast_channel_set_caller_event(tc, &caller, NULL);
2704 } else if (ast_strlen_zero(S_COR(ast_channel_caller(tc)->id.number.valid,
2705 ast_channel_caller(tc)->id.number.str, NULL))) {
2706 /*
2707 * The new channel has no preset CallerID number by the channel
2708 * driver. Use the dialplan extension and hint name.
2709 */
2710 caller.id = stored_clid;
2711 if (!caller.id.name.valid
2712 && !ast_strlen_zero(S_COR(ast_channel_connected(chan)->id.name.valid,
2713 ast_channel_connected(chan)->id.name.str, NULL))) {
2714 /*
2715 * No hint name available. We have a connected name supplied by
2716 * the dialplan we can use instead.
2717 */
2718 caller.id.name.valid = 1;
2719 caller.id.name = ast_channel_connected(chan)->id.name;
2720 }
2721 ast_channel_set_caller_event(tc, &caller, NULL);
2723 } else if (ast_strlen_zero(S_COR(ast_channel_caller(tc)->id.name.valid, ast_channel_caller(tc)->id.name.str,
2724 NULL))) {
2725 /* The new channel has no preset CallerID name by the channel driver. */
2726 if (!ast_strlen_zero(S_COR(ast_channel_connected(chan)->id.name.valid,
2727 ast_channel_connected(chan)->id.name.str, NULL))) {
2728 /*
2729 * We have a connected name supplied by the dialplan we can
2730 * use instead.
2731 */
2732 caller.id.name.valid = 1;
2733 caller.id.name = ast_channel_connected(chan)->id.name;
2734 ast_channel_set_caller_event(tc, &caller, NULL);
2735 }
2736 }
2737
2738 /* Determine CallerID for outgoing channel to send. */
2739 if (ast_test_flag64(peerflags, OPT_FORCECLID) && !force_forwards_only) {
2741
2743 connected.id = forced_clid;
2745 } else {
2747 }
2748
2750
2752
2755 ast_channel_musicclass_set(tc, ast_channel_musicclass(chan));
2756 }
2757
2758 /* Pass ADSI CPE and transfer capability */
2761
2762 /* If we have an outbound group, set this peer channel to it */
2763 if (outbound_group)
2764 ast_app_group_set_channel(tc, outbound_group);
2765 /* If the calling channel has the ANSWERED_ELSEWHERE flag set, inherit it. This is to support local channels */
2768
2769 /* Check if we're forced by configuration */
2772
2773
2774 /* Inherit context and extension */
2775 ast_channel_dialcontext_set(tc, ast_channel_context(chan));
2777
2779
2780 /* Save the original channel name to detect call pickup masquerading in. */
2781 tmp->orig_chan_name = ast_strdup(ast_channel_name(tc));
2782
2784 ast_channel_unlock(chan);
2785
2786 /* Put channel in the list of outgoing thingies. */
2787 tmp->chan = tc;
2788 AST_LIST_INSERT_TAIL(&out_chans, tmp, node);
2789 }
2790
2791 /* As long as we attempted to dial valid peers, don't throw a warning. */
2792 /* If a DAHDI peer is busy, out_chans will be empty so checking list size is misleading. */
2793 if (!num_dialed) {
2794 ast_verb(3, "No devices or endpoints to dial (technology/resource)\n");
2795 if (continue_exec) {
2796 /* There is no point in having RetryDial try again */
2797 *continue_exec = 1;
2798 }
2799 strcpy(pa.status, "CHANUNAVAIL");
2800 res = 0;
2801 goto out;
2802 }
2803
2804 /*
2805 * PREDIAL: Run gosub on all of the callee channels
2806 *
2807 * We run the callee predial before ast_call() in case the user
2808 * wishes to do something on the newly created channels before
2809 * the channel does anything important.
2810 *
2811 * Inside the target gosub we will be able to do something with
2812 * the newly created channel name ie: now the calling channel
2813 * can know what channel will be used to call the destination
2814 * ex: now we will know that SIP/abc-123 is calling SIP/def-124
2815 */
2818 && !AST_LIST_EMPTY(&out_chans)) {
2819 const char *predial_callee;
2820
2822 predial_callee = ast_app_expand_sub_args(chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
2823 if (predial_callee) {
2825 AST_LIST_TRAVERSE(&out_chans, tmp, node) {
2826 ast_pre_call(tmp->chan, predial_callee);
2827 }
2829 ast_free((char *) predial_callee);
2830 }
2831 }
2832
2833 /* Start all outgoing calls */
2834 AST_LIST_TRAVERSE_SAFE_BEGIN(&out_chans, tmp, node) {
2835 res = ast_call(tmp->chan, tmp->number, 0); /* Place the call, but don't wait on the answer */
2836 ast_channel_lock(chan);
2837
2838 /* check the results of ast_call */
2839 if (res) {
2840 /* Again, keep going even if there's an error */
2841 ast_debug(1, "ast call on peer returned %d\n", res);
2842 ast_verb(3, "Couldn't call %s\n", tmp->interface);
2843 if (ast_channel_hangupcause(tmp->chan)) {
2845 }
2846 ast_channel_unlock(chan);
2847 ast_cc_call_failed(chan, tmp->chan, tmp->interface);
2848 ast_hangup(tmp->chan);
2849 tmp->chan = NULL;
2852 continue;
2853 }
2854
2855 ast_channel_publish_dial(chan, tmp->chan, tmp->number, NULL);
2856 ast_channel_unlock(chan);
2857
2858 ast_verb(3, "Called %s\n", tmp->interface);
2860
2861 /* If this line is up, don't try anybody else */
2862 if (ast_channel_state(tmp->chan) == AST_STATE_UP) {
2863 break;
2864 }
2865 }
2867
2868 if (ast_strlen_zero(args.timeout)) {
2869 to = -1;
2870 } else {
2871 to = atoi(args.timeout);
2872 if (to > 0)
2873 to *= 1000;
2874 else {
2875 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
2876 to = -1;
2877 }
2878 }
2879
2880 outgoing = AST_LIST_FIRST(&out_chans);
2881 if (!outgoing) {
2882 strcpy(pa.status, "CHANUNAVAIL");
2883 if (fulldial == num_dialed) {
2884 res = -1;
2885 goto out;
2886 }
2887 } else {
2888 /* Our status will at least be NOANSWER */
2889 strcpy(pa.status, "NOANSWER");
2891 moh = 1;
2892 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
2893 char *original_moh = ast_strdupa(ast_channel_musicclass(chan));
2894 ast_channel_musicclass_set(chan, opt_args[OPT_ARG_MUSICBACK]);
2895 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
2896 ast_channel_musicclass_set(chan, original_moh);
2897 } else {
2898 ast_moh_start(chan, NULL, NULL);
2899 }
2902 if (!ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
2903 if (dial_handle_playtones(chan, opt_args[OPT_ARG_RINGBACK])){
2905 sentringing++;
2906 } else {
2908 }
2909 } else {
2911 sentringing++;
2912 }
2913 }
2914 }
2915
2916 peer = wait_for_answer(chan, &out_chans, &to, peerflags, opt_args, &pa, &num, &result,
2917 dtmf_progress, mf_progress, mf_wink, sf_progress, sf_wink,
2918 (ast_test_flag64(&opts, OPT_HEARPULSING) ? 1 : 0),
2919 ignore_cc, &forced_clid, &stored_clid, &config);
2920
2921 if (!peer) {
2922 if (result) {
2923 res = result;
2924 } else if (to) { /* Musta gotten hung up */
2925 res = -1;
2926 } else { /* Nobody answered, next please? */
2927 res = 0;
2928 }
2929 } else {
2930 const char *number;
2931 const char *name;
2932 int dial_end_raised = 0;
2933 int cause = -1;
2934
2935 if (ast_test_flag64(&opts, OPT_CALLER_ANSWER)) {
2936 ast_answer(chan);
2937 }
2938
2939 /* Ah ha! Someone answered within the desired timeframe. Of course after this
2940 we will always return with -1 so that it is hung up properly after the
2941 conversation. */
2942
2944 && !ast_strlen_zero(opt_args[OPT_ARG_HANGUPCAUSE])) {
2945 cause = ast_str2cause(opt_args[OPT_ARG_HANGUPCAUSE]);
2946 if (cause <= 0) {
2947 if (!strcasecmp(opt_args[OPT_ARG_HANGUPCAUSE], "NONE")) {
2948 cause = 0;
2949 } else if (sscanf(opt_args[OPT_ARG_HANGUPCAUSE], "%30d", &cause) != 1
2950 || cause < 0) {
2951 ast_log(LOG_WARNING, "Invalid cause given to Dial(...Q(<cause>)): \"%s\"\n",
2952 opt_args[OPT_ARG_HANGUPCAUSE]);
2953 cause = -1;
2954 }
2955 }
2956 }
2957 hanguptree(&out_chans, peer, cause >= 0 ? cause : AST_CAUSE_ANSWERED_ELSEWHERE);
2958
2959 /* If appropriate, log that we have a destination channel and set the answer time */
2960
2961 ast_channel_lock(peer);
2963
2964 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
2965 if (ast_strlen_zero(number)) {
2966 number = NULL;
2967 } else {
2969 }
2970 ast_channel_unlock(peer);
2971
2972 ast_channel_lock(chan);
2974
2975 strcpy(pa.status, "ANSWER");
2976 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2977
2978 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", name);
2979 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
2980
2982 ast_channel_unlock(chan);
2983
2984 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
2985 ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
2986 ast_channel_sendurl( peer, args.url );
2987 }
2989 if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
2990 ast_channel_publish_dial(chan, peer, NULL, pa.status);
2991 /* hang up on the callee -- he didn't want to talk anyway! */
2993 res = 0;
2994 goto out;
2995 }
2996 }
2997 if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
2998 res = 0;
2999 } else {
3000 int digit = 0;
3001 struct ast_channel *chans[2];
3002 struct ast_channel *active_chan;
3003 char *calledfile = NULL, *callerfile = NULL;
3004 int calledstream = 0, callerstream = 0;
3005
3006 chans[0] = chan;
3007 chans[1] = peer;
3008
3009 /* we need to stream the announcement(s) when the OPT_ARG_ANNOUNCE (-A) is set */
3010 callerfile = opt_args[OPT_ARG_ANNOUNCE];
3011 calledfile = strsep(&callerfile, ":");
3012
3013 /* stream the file(s) */
3014 if (!ast_strlen_zero(calledfile)) {
3015 res = ast_streamfile(peer, calledfile, ast_channel_language(peer));
3016 if (res) {
3017 res = 0;
3018 ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", calledfile);
3019 } else {
3020 calledstream = 1;
3021 }
3022 }
3023 if (!ast_strlen_zero(callerfile)) {
3024 res = ast_streamfile(chan, callerfile, ast_channel_language(chan));
3025 if (res) {
3026 res = 0;
3027 ast_log(LOG_ERROR, "error streaming file '%s' to caller\n", callerfile);
3028 } else {
3029 callerstream = 1;
3030 }
3031 }
3032
3033 /* can't use ast_waitstream, because we're streaming two files at once, and can't block
3034 We'll need to handle both channels at once. */
3035
3037 while (ast_channel_stream(peer) || ast_channel_stream(chan)) {
3038 int mspeer, mschan;
3039
3040 mspeer = ast_sched_wait(ast_channel_sched(peer));
3041 mschan = ast_sched_wait(ast_channel_sched(chan));
3042
3043 if (calledstream) {
3044 if (mspeer < 0 && !ast_channel_timingfunc(peer)) {
3045 ast_stopstream(peer);
3046 calledstream = 0;
3047 }
3048 }
3049 if (callerstream) {
3050 if (mschan < 0 && !ast_channel_timingfunc(chan)) {
3051 ast_stopstream(chan);
3052 callerstream = 0;
3053 }
3054 }
3055
3056 if (!calledstream && !callerstream) {
3057 break;
3058 }
3059
3060 if (mspeer < 0)
3061 mspeer = 1000;
3062
3063 if (mschan < 0)
3064 mschan = 1000;
3065
3066 /* wait for the lowest maximum of the two */
3067 active_chan = ast_waitfor_n(chans, 2, (mspeer > mschan ? &mschan : &mspeer));
3068 if (active_chan) {
3069 struct ast_channel *other_chan;
3070 struct ast_frame *fr = ast_read(active_chan);
3071
3072 if (!fr) {
3074 res = -1;
3075 goto done;
3076 }
3077 switch (fr->frametype) {
3078 case AST_FRAME_DTMF_END:
3079 digit = fr->subclass.integer;
3080 if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
3081 ast_stopstream(peer);
3082 res = ast_senddigit(chan, digit, 0);
3083 }
3084 break;
3085 case AST_FRAME_CONTROL:
3086 switch (fr->subclass.integer) {
3087 case AST_CONTROL_HANGUP:
3088 ast_frfree(fr);
3090 res = -1;
3091 goto done;
3093 /* Pass COLP update to the other channel. */
3094 if (active_chan == chan) {
3095 other_chan = peer;
3096 } else {
3097 other_chan = chan;
3098 }
3099 if (ast_channel_connected_line_sub(active_chan, other_chan, fr, 1)) {
3100 ast_indicate_data(other_chan, fr->subclass.integer,
3101 fr->data.ptr, fr->datalen);
3102 }
3103 break;
3104 default:
3105 break;
3106 }
3107 break;
3108 default:
3109 /* Ignore all others */
3110 break;
3111 }
3112 ast_frfree(fr);
3113 }
3116 }
3118 }
3119
3120 if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
3121 /* chan and peer are going into the PBX; as such neither are considered
3122 * outgoing channels any longer */
3124
3126 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
3127 /* peer goes to the same context and extension as chan, so just copy info from chan*/
3128 ast_channel_lock(peer);
3135 ast_channel_unlock(peer);
3136 if (ast_pbx_start(peer)) {
3138 }
3139 if (continue_exec)
3140 *continue_exec = 1;
3141 res = 0;
3142 ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
3143 goto done;
3144 }
3145
3147 const char *gosub_result_peer;
3148 char *gosub_argstart;
3149 char *gosub_args = NULL;
3150 int gosub_res = -1;
3151
3153 gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
3154 if (gosub_argstart) {
3155 const char *what_is_s = "s";
3156 *gosub_argstart = 0;
3157 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)) &&
3158 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))) {
3159 what_is_s = "~~s~~";
3160 }
3161 if (ast_asprintf(&gosub_args, "%s,%s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s, gosub_argstart + 1) < 0) {
3162 gosub_args = NULL;
3163 }
3164 *gosub_argstart = ',';
3165 } else {
3166 const char *what_is_s = "s";
3167 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)) &&
3168 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))) {
3169 what_is_s = "~~s~~";
3170 }
3171 if (ast_asprintf(&gosub_args, "%s,%s,1", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s) < 0) {
3172 gosub_args = NULL;
3173 }
3174 }
3175 if (gosub_args) {
3176 gosub_res = ast_app_exec_sub(chan, peer, gosub_args, 0);
3177 ast_free(gosub_args);
3178 } else {
3179 ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
3180 }
3181
3182 ast_channel_lock_both(chan, peer);
3183
3184 if (!gosub_res && (gosub_result_peer = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
3185 char *gosub_transfer_dest;
3186 char *gosub_result = ast_strdupa(gosub_result_peer);
3187 const char *gosub_retval = pbx_builtin_getvar_helper(peer, "GOSUB_RETVAL");
3188
3189 /* Inherit return value from the peer, so it can be used in the master */
3190 if (gosub_retval) {
3191 pbx_builtin_setvar_helper(chan, "GOSUB_RETVAL", gosub_retval);
3192 }
3193
3194 ast_channel_unlock(peer);
3195 ast_channel_unlock(chan);
3196
3197 if (!strcasecmp(gosub_result, "BUSY")) {
3198 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
3199 ast_set_flag64(peerflags, OPT_GO_ON);
3200 gosub_res = -1;
3201 } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
3202 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
3203 ast_set_flag64(peerflags, OPT_GO_ON);
3204 gosub_res = -1;
3205 } else if (!strcasecmp(gosub_result, "CONTINUE")) {
3206 /* Hangup peer and continue with the next extension priority. */
3207 ast_set_flag64(peerflags, OPT_GO_ON);
3208 gosub_res = -1;
3209 } else if (!strcasecmp(gosub_result, "ABORT")) {
3210 /* Hangup both ends unless the caller has the g flag */
3211 gosub_res = -1;
3212 } else if (!strncasecmp(gosub_result, "GOTO:", 5)) {
3213 gosub_transfer_dest = gosub_result + 5;
3214 gosub_res = -1;
3215 /* perform a transfer to a new extension */
3216 if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
3217 ast_replace_subargument_delimiter(gosub_transfer_dest);
3218 }
3219 if (!ast_parseable_goto(chan, gosub_transfer_dest)) {
3220 ast_set_flag64(peerflags, OPT_GO_ON);
3221 }
3222 }
3223 if (gosub_res) {
3224 res = gosub_res;
3225 if (!dial_end_raised) {
3226 ast_channel_publish_dial(chan, peer, NULL, gosub_result);
3227 dial_end_raised = 1;
3228 }
3229 }
3230 } else {
3231 ast_channel_unlock(peer);
3232 ast_channel_unlock(chan);
3233 }
3234 }
3235
3236 if (!res) {
3237
3238 /* None of the Dial options changed our status; inform
3239 * everyone that this channel answered
3240 */
3241 if (!dial_end_raised) {
3242 ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
3243 dial_end_raised = 1;
3244 }
3245
3246 if (!ast_tvzero(calldurationlimit)) {
3247 struct timeval whentohangup = ast_tvadd(ast_tvnow(), calldurationlimit);
3248 ast_channel_lock(peer);
3249 ast_channel_whentohangup_set(peer, &whentohangup);
3250 ast_channel_unlock(peer);
3251 }
3252 if (!ast_strlen_zero(dtmfcalled)) {
3253 ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
3254 res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
3255 }
3256 if (!ast_strlen_zero(dtmfcalling)) {
3257 ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
3258 res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
3259 }
3260 }
3261
3262 if (res) { /* some error */
3263 if (!ast_check_hangup(chan) && ast_check_hangup(peer)) {
3265 }
3266 setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3268 || ast_pbx_start(peer)) {
3270 }
3271 res = -1;
3272 } else {
3273 if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
3274 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
3275 if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
3276 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
3277 if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
3278 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
3279 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
3280 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
3281 if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
3282 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
3283 if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
3284 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
3285 if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
3286 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
3287 if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
3288 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
3289 if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
3290 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
3291 if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
3292 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
3293
3294 config.end_bridge_callback = end_bridge_callback;
3295 config.end_bridge_callback_data = chan;
3296 config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup;
3297
3298 if (moh) {
3299 moh = 0;
3300 ast_moh_stop(chan);
3301 } else if (sentringing) {
3302 sentringing = 0;
3303 ast_indicate(chan, -1);
3304 }
3305 /* Be sure no generators are left on it and reset the visible indication */
3308 /* Make sure channels are compatible */
3309 res = ast_channel_make_compatible(chan, peer);
3310 if (res < 0) {
3311 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));
3313 res = -1;
3314 goto done;
3315 }
3316 if (opermode) {
3317 struct oprmode oprmode;
3318
3319 oprmode.peer = peer;
3320 oprmode.mode = opermode;
3321
3323 }
3324 setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3325
3326 res = ast_bridge_call(chan, peer, &config);
3327 }
3328 }
3329out:
3330 if (moh) {
3331 moh = 0;
3332 ast_moh_stop(chan);
3333 } else if (sentringing) {
3334 sentringing = 0;
3335 ast_indicate(chan, -1);
3336 }
3337
3338 if (delprivintro && ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3340 if (ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3341 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
3342 } else {
3343 ast_verb(3, "Successfully deleted %s intro file\n", pa.privintro);
3344 }
3345 }
3346
3348 /* forward 'answered elsewhere' if we received it */
3350 hanguptreecause = AST_CAUSE_ANSWERED_ELSEWHERE;
3351 } else if (pa.canceled) { /* Caller canceled */
3352 if (ast_channel_hangupcause(chan))
3353 hanguptreecause = ast_channel_hangupcause(chan);
3354 else
3355 hanguptreecause = AST_CAUSE_NORMAL_CLEARING;
3356 }
3357 hanguptree(&out_chans, NULL, hanguptreecause);
3358 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
3359 ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
3360
3361 if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
3362 if (!ast_tvzero(calldurationlimit))
3363 memset(ast_channel_whentohangup(chan), 0, sizeof(*ast_channel_whentohangup(chan)));
3364 res = 0;
3365 }
3366
3367done:
3368 if (config.answer_topology) {
3369 ast_trace(2, "%s Cleaning up topology: %p %s\n",
3370 peer ? ast_channel_name(peer) : "<no channel>", &config.answer_topology,
3371 ast_str_tmp(256, ast_stream_topology_to_str(config.answer_topology, &STR_TMP)));
3372
3373 /*
3374 * At this point, the channel driver that answered should have bumped the
3375 * topology refcount for itself. Here we're cleaning up the reference we added
3376 * in wait_for_answer().
3377 */
3378 ast_stream_topology_free(config.answer_topology);
3379 }
3380 if (config.warning_sound) {
3381 ast_free((char *)config.warning_sound);
3382 }
3383 if (config.end_sound) {
3384 ast_free((char *)config.end_sound);
3385 }
3386 if (config.start_sound) {
3387 ast_free((char *)config.start_sound);
3388 }
3389 ast_ignore_cc(chan);
3390 SCOPE_EXIT_RTN_VALUE(res, "%s: Done\n", ast_channel_name(chan));
3391}
char digit
#define DIAL_STILLGOING
Definition: app_dial.c:693
#define OPT_PREDIAL_CALLER
Definition: app_dial.c:704
#define OPT_CANCEL_ELSEWHERE
Definition: app_dial.c:696
static const char * get_cid_name(char *name, int namelen, struct ast_channel *chan)
Definition: app_dial.c:888
static const struct ast_app_option dial_exec_options[128]
Definition: app_dial.c:776
#define OPT_PREDIAL_CALLEE
Definition: app_dial.c:703
#define DIAL_CALLERID_ABSENT
Definition: app_dial.c:695
#define OPT_FORCE_CID_PRES
Definition: app_dial.c:701
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:2243
#define CAN_EARLY_BRIDGE(flags, chan, peer)
Definition: app_dial.c:778
#define OPT_RING_WITH_EARLY_MEDIA
Definition: app_dial.c:705
#define OPT_FORCE_CID_TAG
Definition: app_dial.c:700
#define OPT_HEARPULSING
Definition: app_dial.c:707
#define DIAL_NOFORWARDHTML
Definition: app_dial.c:694
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:1183
#define OPT_CANCEL_TIMEOUT
Definition: app_dial.c:699
static void chanlist_free(struct chanlist *outgoing)
Definition: app_dial.c:813
static void handle_cause(int cause, struct cause_args *num)
Definition: app_dial.c:851
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:2088
#define OPT_HANGUPCAUSE
Definition: app_dial.c:706
static void hanguptree(struct dial_head *out_chans, struct ast_channel *exception, int hangupcause)
Definition: app_dial.c:821
static int dial_handle_playtones(struct ast_channel *chan, const char *data)
Definition: app_dial.c:2203
static void end_bridge_callback(void *data)
Definition: app_dial.c:2187
#define OPT_CALLER_ANSWER
Definition: app_dial.c:702
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
Definition: app_dial.c:2199
#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:426
int ast_parse_caller_presentation(const char *data)
Convert caller ID text code to value (used in config file parsing)
Definition: callerid.c:1244
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1063
#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:4164
void ast_ignore_cc(struct ast_channel *chan)
Mark the channel to ignore further CC activity.
Definition: ccss.c:3685
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:4197
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:1983
int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
Start the CC process on a call.
Definition: ccss.c:2386
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:4209
int ast_cdr_reset(const char *channel_name, int keep_variables)
Reset the detail record.
Definition: cdr.c:3660
static PGresult * result
Definition: cel_pgsql.c:84
static const char config[]
Definition: chan_ooh323.c:111
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int ast_str2cause(const char *name) attribute_pure
Convert the string form of a cause code to a number.
Definition: channel.c:625
const char * ast_channel_name(const struct ast_channel *chan)
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
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:10489
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6454
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11018
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:10331
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2535
@ 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:8301
const char * ast_channel_musicclass(const struct ast_channel *chan)
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:7365
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:3151
int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
Send a DTMF digit to a channel.
Definition: channel.c:4967
#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:6713
void ast_channel_data_set(struct ast_channel *chan, const char *value)
@ 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
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
unsigned short ast_channel_transfercapability(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_flags * ast_channel_flags(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
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2362
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:6427
const char * ast_channel_context(const struct ast_channel *chan)
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:2887
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
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4250
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
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:6764
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:6352
int ast_channel_supports_html(struct ast_channel *channel)
Checks for HTML support on a channel.
Definition: channel.c:6616
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
int ast_channel_hangupcause(const struct ast_channel *chan)
struct ast_party_dialed * ast_channel_dialed(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:4646
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
Definition: channel.c:11011
ast_timing_func_t ast_channel_timingfunc(const struct ast_channel *chan)
#define AST_CHANNEL_NAME
Definition: channel.h:171
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
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:6628
const char * ast_channel_language(const struct ast_channel *chan)
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
void ast_channel_context_set(struct ast_channel *chan, const char *value)
struct ast_sched_context * ast_channel_sched(const struct ast_channel *chan)
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:8286
@ AST_FLAG_OUTGOING
Definition: channel.h:999
@ AST_FLAG_END_DTMF_ONLY
Definition: channel.h:1007
struct ast_filestream * ast_channel_stream(const 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:6437
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:7415
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
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
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
void ast_channel_priority_set(struct ast_channel *chan, int value)
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:2799
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:7405
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4270
const char * ast_channel_exten(const struct ast_channel *chan)
#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:685
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:857
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:1293
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1129
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1141
#define AST_DIGIT_ANY
Definition: file.h:48
static const char name[]
Definition: format_mp3.c:68
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_ENTER(level,...)
#define ast_trace(level,...)
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.
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:278
#define AST_APP_ARG(name)
Define an application argument.
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:2183
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#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:297
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:1127
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:3061
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 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:7759
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7769
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
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:4175
#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.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4708
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8866
#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:2264
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
@ 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
void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
Set the state of a stream.
Definition: stream.c:380
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
struct ast_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
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_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
#define 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:1186
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
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::@226 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:845
List of channel drivers.
Definition: app_dial.c:788
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:1126
int privdb_val
Definition: app_dial.c:1123
int sentringing
Definition: app_dial.c:1122
char privintro[1024]
Definition: app_dial.c:1125
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:117
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:159
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: utils.c:2341

References args, ast_answer(), AST_APP_ARG, 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_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_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_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_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, 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, 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 2203 of file app_dial.c.

2204{
2205 struct ast_tone_zone_sound *ts = NULL;
2206 int res;
2207 const char *str = data;
2208
2209 if (ast_strlen_zero(str)) {
2210 ast_debug(1,"Nothing to play\n");
2211 return -1;
2212 }
2213
2215
2216 if (ts && ts->data[0]) {
2217 res = ast_playtones_start(chan, 0, ts->data, 0);
2218 } else {
2219 res = -1;
2220 }
2221
2222 if (ts) {
2224 }
2225
2226 if (res) {
2227 ast_log(LOG_WARNING, "Unable to start playtone \'%s\'\n", str);
2228 }
2229
2230 return res;
2231}
const char * str
Definition: app_jack.c:147
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
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
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
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:461
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 918 of file app_dial.c.

921{
922 char tmpchan[256];
923 char forwarder[AST_CHANNEL_NAME];
924 struct ast_channel *original = o->chan;
925 struct ast_channel *c = o->chan; /* the winner */
926 struct ast_channel *in = num->chan; /* the input channel */
927 char *stuff;
928 char *tech;
929 int cause;
930 struct ast_party_caller caller;
931
932 ast_copy_string(forwarder, ast_channel_name(c), sizeof(forwarder));
933 ast_copy_string(tmpchan, ast_channel_call_forward(c), sizeof(tmpchan));
934 if ((stuff = strchr(tmpchan, '/'))) {
935 *stuff++ = '\0';
936 tech = tmpchan;
937 } else {
938 const char *forward_context;
940 forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
941 if (ast_strlen_zero(forward_context)) {
942 forward_context = NULL;
943 }
944 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", ast_channel_call_forward(c), forward_context ? forward_context : ast_channel_context(c));
946 stuff = tmpchan;
947 tech = "Local";
948 }
949 if (!strcasecmp(tech, "Local")) {
950 /*
951 * Drop the connected line update block for local channels since
952 * this is going to run dialplan and the user can change his
953 * mind about what connected line information he wants to send.
954 */
956 }
957
958 /* Before processing channel, go ahead and check for forwarding */
959 ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", ast_channel_name(in), tech, stuff, ast_channel_name(c));
960 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
961 if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
962 ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", ast_channel_name(in), tech, stuff);
963 ast_channel_publish_dial_forward(in, original, NULL, NULL, "CANCEL",
964 ast_channel_call_forward(original));
965 c = o->chan = NULL;
966 cause = AST_CAUSE_BUSY;
967 } else {
968 struct ast_stream_topology *topology;
969
973
974 /* Setup parameters */
975 c = o->chan = ast_request_with_stream_topology(tech, topology, NULL, in, stuff, &cause);
976
977 ast_stream_topology_free(topology);
978
979 if (c) {
980 if (single && !caller_entertained) {
982 }
986 pbx_builtin_setvar_helper(o->chan, "FORWARDERNAME", forwarder);
990 /* When a call is forwarded, we don't want to track new interfaces
991 * dialed for CC purposes. Setting the done flag will ensure that
992 * any Dial operations that happen later won't record CC interfaces.
993 */
995 ast_verb(3, "Not accepting call completion offers from call-forward recipient %s\n",
997 } else
999 "Forwarding failed to create channel to dial '%s/%s' (cause = %d)\n",
1000 tech, stuff, cause);
1001 }
1002 if (!c) {
1003 ast_channel_publish_dial(in, original, stuff, "BUSY");
1005 handle_cause(cause, num);
1006 ast_hangup(original);
1007 } else {
1008 ast_channel_lock_both(c, original);
1010 ast_channel_redirecting(original));
1012 ast_channel_unlock(original);
1013
1015
1016 if (single && !caller_entertained && CAN_EARLY_BRIDGE(peerflags, c, in)) {
1018 }
1019
1020 if (!ast_channel_redirecting(c)->from.number.valid
1021 || ast_strlen_zero(ast_channel_redirecting(c)->from.number.str)) {
1022 /*
1023 * The call was not previously redirected so it is
1024 * now redirected from this number.
1025 */
1031 }
1032
1034
1035 /* Determine CallerID to store in outgoing channel. */
1037 if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
1038 caller.id = *stored_clid;
1041 } else if (ast_strlen_zero(S_COR(ast_channel_caller(c)->id.number.valid,
1042 ast_channel_caller(c)->id.number.str, NULL))) {
1043 /*
1044 * The new channel has no preset CallerID number by the channel
1045 * driver. Use the dialplan extension and hint name.
1046 */
1047 caller.id = *stored_clid;
1050 } else {
1052 }
1053
1054 /* Determine CallerID for outgoing channel to send. */
1057
1059 connected.id = *forced_clid;
1061 } else {
1063 }
1064
1066
1067 ast_channel_appl_set(c, "AppDial");
1068 ast_channel_data_set(c, "(Outgoing Line)");
1070
1072 if (single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1073 struct ast_party_redirecting redirecting;
1074
1075 /*
1076 * Redirecting updates to the caller make sense only on single
1077 * calls.
1078 *
1079 * Need to re-evalute if unlocking is still required here as macro is gone
1080 */
1081 ast_party_redirecting_init(&redirecting);
1084 if (ast_channel_redirecting_sub(c, in, &redirecting, 0)) {
1085 ast_channel_update_redirecting(in, &redirecting, NULL);
1086 }
1087 ast_party_redirecting_free(&redirecting);
1088 } else {
1090 }
1091
1092 if (ast_test_flag64(peerflags, OPT_CANCEL_TIMEOUT)) {
1093 *to = -1;
1094 }
1095
1096 if (ast_call(c, stuff, 0)) {
1097 ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n",
1098 tech, stuff);
1099 ast_channel_publish_dial(in, original, stuff, "CONGESTION");
1101 ast_hangup(original);
1102 ast_hangup(c);
1103 c = o->chan = NULL;
1104 num->nochan++;
1105 } else {
1106 ast_channel_publish_dial_forward(in, original, c, NULL, "CANCEL",
1107 ast_channel_call_forward(original));
1108
1110
1111 /* Hangup the original channel now, in case we needed it */
1112 ast_hangup(original);
1113 }
1114 if (single && !caller_entertained) {
1115 ast_indicate(in, -1);
1116 }
1117 }
1118}
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_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:10376
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:10277
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:848
struct ast_channel * chan
Definition: app_dial.c:790
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_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_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, 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 2187 of file app_dial.c.

2188{
2189 struct ast_channel *chan = data;
2190
2191 ast_channel_lock(chan);
2193 set_duration_var(chan, "ANSWEREDTIME", ast_channel_get_up_time_ms(chan));
2194 set_duration_var(chan, "DIALEDTIME", ast_channel_get_duration_ms(chan));
2196 ast_channel_unlock(chan);
2197}
static void set_duration_var(struct ast_channel *chan, const char *var_base, int64_t duration)
Definition: app_dial.c:1170
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:2829
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:2814
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 2199 of file app_dial.c.

2199 {
2200 bconfig->end_bridge_callback_data = originator;
2201}
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 888 of file app_dial.c.

889{
890 const char *context;
891 const char *exten;
892
893 ast_channel_lock(chan);
895 exten = ast_strdupa(ast_channel_exten(chan));
896 ast_channel_unlock(chan);
897
898 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
899}
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:4137

References ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_unlock, ast_get_hint(), ast_strdupa, voicemailpwcheck::context, ast_channel::exten, name, and NULL.

Referenced by dial_exec_full().

◆ handle_cause()

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

Definition at line 851 of file app_dial.c.

852{
853 switch(cause) {
854 case AST_CAUSE_BUSY:
855 num->busy++;
856 break;
858 num->congestion++;
859 break;
862 num->nochan++;
863 break;
866 break;
867 default:
868 num->nochan++;
869 break;
870 }
871}
#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:847
int busy
Definition: app_dial.c:846

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

822{
823 /* Hang up a tree of stuff */
824 struct chanlist *outgoing;
825
826 while ((outgoing = AST_LIST_REMOVE_HEAD(out_chans, node))) {
827 /* Hangup any existing lines we have open */
828 if (outgoing->chan && (outgoing->chan != exception)) {
829 if (hangupcause >= 0) {
830 /* This is for the channel drivers */
831 ast_channel_hangupcause_set(outgoing->chan, hangupcause);
832 }
833 ast_hangup(outgoing->chan);
834 }
836 }
837}
#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 3520 of file app_dial.c.

3521{
3522 int res;
3523
3526
3527 return res;
3528}
static const char app[]
Definition: app_dial.c:656
static int dial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3393
static const char rapp[]
Definition: app_dial.c:657
static int retrydial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3402
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

References app, ast_register_application_xml, dial_exec(), rapp, and retrydial_exec().

◆ onedigit_goto()

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

Definition at line 873 of file app_dial.c.

874{
875 char rexten[2] = { exten, '\0' };
876
877 if (context) {
878 if (!ast_goto_if_exists(chan, context, rexten, pri))
879 return 1;
880 } else {
881 if (!ast_goto_if_exists(chan, ast_channel_context(chan), rexten, pri))
882 return 1;
883 }
884 return 0;
885}
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:8781

References ast_channel_context(), ast_goto_if_exists(), voicemailpwcheck::context, and ast_channel::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 1130 of file app_dial.c.

1131{
1132 struct chanlist *outgoing;
1133 AST_LIST_TRAVERSE(out_chans, outgoing, node) {
1134 if (!outgoing->chan || outgoing->chan == exception) {
1135 continue;
1136 }
1138 }
1139}
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 3402 of file app_dial.c.

3403{
3404 char *parse;
3405 const char *context = NULL;
3406 int sleepms = 0, loops = 0, res = -1;
3407 struct ast_flags64 peerflags = { 0, };
3409 AST_APP_ARG(announce);
3410 AST_APP_ARG(sleep);
3411 AST_APP_ARG(retries);
3412 AST_APP_ARG(dialdata);
3413 );
3414
3415 if (ast_strlen_zero(data)) {
3416 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
3417 return -1;
3418 }
3419
3420 parse = ast_strdupa(data);
3422
3423 if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
3424 sleepms *= 1000;
3425
3426 if (!ast_strlen_zero(args.retries)) {
3427 loops = atoi(args.retries);
3428 }
3429
3430 if (!args.dialdata) {
3431 ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
3432 goto done;
3433 }
3434
3435 if (sleepms < 1000)
3436 sleepms = 10000;
3437
3438 if (!loops)
3439 loops = -1; /* run forever */
3440
3441 ast_channel_lock(chan);
3442 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
3444 ast_channel_unlock(chan);
3445
3446 res = 0;
3447 while (loops) {
3448 int continue_exec;
3449
3450 ast_channel_data_set(chan, "Retrying");
3452 ast_moh_stop(chan);
3453
3454 res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
3455 if (continue_exec)
3456 break;
3457
3458 if (res == 0) {
3459 if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
3460 if (!ast_strlen_zero(args.announce)) {
3461 if (ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3462 if (!(res = ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3464 } else
3465 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3466 }
3467 if (!res && sleepms) {
3469 ast_moh_start(chan, NULL, NULL);
3470 res = ast_waitfordigit(chan, sleepms);
3471 }
3472 } else {
3473 if (!ast_strlen_zero(args.announce)) {
3474 if (ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3475 if (!(res = ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3476 res = ast_waitstream(chan, "");
3477 } else
3478 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3479 }
3480 if (sleepms) {
3482 ast_moh_start(chan, NULL, NULL);
3483 if (!res)
3484 res = ast_waitfordigit(chan, sleepms);
3485 }
3486 }
3487 }
3488
3489 if (res < 0 || res == AST_PBX_INCOMPLETE) {
3490 break;
3491 } else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
3492 if (onedigit_goto(chan, context, (char) res, 1)) {
3493 res = 0;
3494 break;
3495 }
3496 }
3497 loops--;
3498 }
3499 if (loops == 0)
3500 res = 0;
3501 else if (res == 1)
3502 res = 0;
3503
3505 ast_moh_stop(chan);
3506 done:
3507 return res;
3508}
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
Definition: app_dial.c:873
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3169
@ 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:1839
#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(), voicemailpwcheck::context, dial_exec_full(), done, LOG_ERROR, LOG_WARNING, NULL, onedigit_goto(), OPT_DTMF_EXIT, pbx_builtin_getvar_helper(), and rapp.

Referenced by load_module().

◆ set_duration_var()

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

Definition at line 1170 of file app_dial.c.

1171{
1172 char buf[32];
1173 char full_var_name[128];
1174
1175 snprintf(buf, sizeof(buf), "%" PRId64, duration / 1000);
1176 pbx_builtin_setvar_helper(chan, var_base, buf);
1177
1178 snprintf(full_var_name, sizeof(full_var_name), "%s_MS", var_base);
1179 snprintf(buf, sizeof(buf), "%" PRId64, duration);
1180 pbx_builtin_setvar_helper(chan, full_var_name, buf);
1181}
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 2243 of file app_dial.c.

2244{
2245 const char *context;
2246 const char *extension;
2247 int priority;
2248
2249 if (ast_test_flag64(opts, OPT_PEER_H)) {
2250 ast_channel_lock(chan);
2252 ast_channel_unlock(chan);
2254 } else if (ast_test_flag64(opts, OPT_CALLEE_GO_ON)) {
2255 ast_channel_lock(chan);
2259 ast_channel_unlock(chan);
2261 opt_args[OPT_ARG_CALLEE_GO_ON]);
2262 }
2263}
#define OPT_PEER_H
Definition: app_dial.c:697
#define OPT_CALLEE_GO_ON
Definition: app_dial.c:698
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, voicemailpwcheck::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 2088 of file app_dial.c.

2090{
2091 char callerid[60];
2092 int res;
2093 char *l;
2094
2095 if (ast_channel_caller(chan)->id.number.valid
2096 && !ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
2097 l = ast_strdupa(ast_channel_caller(chan)->id.number.str);
2099 if (ast_test_flag64(opts, OPT_PRIVACY) ) {
2100 ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
2101 pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
2102 } else {
2103 ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
2105 }
2106 } else {
2107 char *tnam, *tn2;
2108
2109 tnam = ast_strdupa(ast_channel_name(chan));
2110 /* clean the channel name so slashes don't try to end up in disk file name */
2111 for (tn2 = tnam; *tn2; tn2++) {
2112 if (*tn2 == '/') /* any other chars to be afraid of? */
2113 *tn2 = '=';
2114 }
2115 ast_verb(3, "Privacy-- callerid is empty\n");
2116
2117 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", ast_channel_exten(chan), tnam);
2118 l = callerid;
2120 }
2121
2122 ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
2123
2124 if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
2125 /* if callerid is set and OPT_SCREEN_NOCALLERID is set also */
2126 ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
2128 } else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
2129 ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
2130 }
2131
2132 if (pa->privdb_val == AST_PRIVACY_DENY) {
2133 ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
2134 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
2135 return 0;
2136 } else if (pa->privdb_val == AST_PRIVACY_KILL) {
2137 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
2138 return 0; /* Is this right? */
2139 } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
2140 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
2141 return 0; /* is this right??? */
2142 } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
2143 /* Get the user's intro, store it in priv-callerintros/$CID,
2144 unless it is already there-- this should be done before the
2145 call is actually dialed */
2146
2147 /* make sure the priv-callerintros dir actually exists */
2148 snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
2149 if ((res = ast_mkdir(pa->privintro, 0755))) {
2150 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
2151 return -1;
2152 }
2153
2154 snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
2155 if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
2156 /* the DELUX version of this code would allow this caller the
2157 option to hear and retape their previously recorded intro.
2158 */
2159 } else {
2160 int duration; /* for feedback from play_and_wait */
2161 /* the file doesn't exist yet. Let the caller submit his
2162 vocal intro for posterity */
2163 /* priv-recordintro script:
2164 "At the tone, please say your name:"
2165 */
2167 ast_answer(chan);
2168 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 */
2169 /* don't think we'll need a lock removed, we took care of
2170 conflicts by naming the pa.privintro file */
2171 if (res == -1) {
2172 /* Delete the file regardless since they hung up during recording */
2174 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
2175 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
2176 else
2177 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
2178 return -1;
2179 }
2180 if (!ast_streamfile(chan, "vm-dialout", ast_channel_language(chan)) )
2181 ast_waitstream(chan, "");
2182 }
2183 }
2184 return 1; /* success */
2185}
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:1002
@ 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:2144
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:1124
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2477

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

3511{
3512 int res;
3513
3516
3517 return res;
3518}
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 1150 of file app_dial.c.

1151{
1152 struct ast_party_connected_line connected_caller;
1153
1154 ast_party_connected_line_init(&connected_caller);
1155
1156 ast_channel_lock(peer);
1158 ast_channel_unlock(peer);
1159 connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1160 if (ast_channel_connected_line_sub(peer, chan, &connected_caller, 0)) {
1161 ast_channel_update_connected_line(chan, &connected_caller, NULL);
1162 }
1163 ast_party_connected_line_free(&connected_caller);
1164}
@ AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER
Definition: callerid.h:540
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:9086

References ast_channel_caller(), 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 1941 of file app_dial.c.

1942{
1943 if (res < '1')
1944 return 0;
1945 if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
1946 return 1;
1947 if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
1948 return 1;
1949 return 0;
1950}

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

1194{
1195 struct cause_args num = *num_in;
1196 int prestart = num.busy + num.congestion + num.nochan;
1197 int orig = *to;
1198 struct ast_channel *peer = NULL;
1199 struct chanlist *outgoing = AST_LIST_FIRST(out_chans);
1200 /* single is set if only one destination is enabled */
1201 int single = outgoing && !AST_LIST_NEXT(outgoing, node);
1202 int caller_entertained = outgoing
1204 struct ast_str *featurecode = ast_str_alloca(AST_FEATURE_MAX_LEN + 1);
1205 int cc_recall_core_id;
1206 int is_cc_recall;
1207 int cc_frame_received = 0;
1208 int num_ringing = 0;
1209 int sent_ring = 0;
1210 int sent_progress = 0, sent_wink = 0;
1211 struct timeval start = ast_tvnow();
1212 SCOPE_ENTER(3, "%s\n", ast_channel_name(in));
1213
1214 if (single) {
1215 /* Turn off hold music, etc */
1216 if (!caller_entertained) {
1218 /* If we are calling a single channel, and not providing ringback or music, */
1219 /* then, make them compatible for in-band tone purpose */
1220 if (ast_channel_make_compatible(in, outgoing->chan) < 0) {
1221 /* If these channels can not be made compatible,
1222 * there is no point in continuing. The bridge
1223 * will just fail if it gets that far.
1224 */
1225 *to = -1;
1226 strcpy(pa->status, "CONGESTION");
1228 SCOPE_EXIT_RTN_VALUE(NULL, "%s: can't be made compat with %s\n",
1230 }
1231 }
1232
1236 }
1237 }
1238
1239 is_cc_recall = ast_cc_is_recall(in, &cc_recall_core_id, NULL);
1240
1241 while ((*to = ast_remaining_ms(start, orig)) && !peer) {
1242 struct chanlist *o;
1243 int pos = 0; /* how many channels do we handle */
1244 int numlines = prestart;
1245 struct ast_channel *winner;
1246 struct ast_channel *watchers[AST_MAX_WATCHERS];
1247
1248 watchers[pos++] = in;
1249 AST_LIST_TRAVERSE(out_chans, o, node) {
1250 /* Keep track of important channels */
1251 if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
1252 watchers[pos++] = o->chan;
1253 numlines++;
1254 }
1255 if (pos == 1) { /* only the input channel is available */
1256 if (numlines == (num.busy + num.congestion + num.nochan)) {
1257 ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1258 if (num.busy)
1259 strcpy(pa->status, "BUSY");
1260 else if (num.congestion)
1261 strcpy(pa->status, "CONGESTION");
1262 else if (num.nochan)
1263 strcpy(pa->status, "CHANUNAVAIL");
1264 } else {
1265 ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1266 }
1267 *to = 0;
1268 if (is_cc_recall) {
1269 ast_cc_failed(cc_recall_core_id, "Everyone is busy/congested for the recall. How sad");
1270 }
1271 SCOPE_EXIT_RTN_VALUE(NULL, "%s: No outgoing channels available\n", ast_channel_name(in));
1272 }
1273 winner = ast_waitfor_n(watchers, pos, to);
1274 AST_LIST_TRAVERSE(out_chans, o, node) {
1275 int res = 0;
1276 struct ast_frame *f;
1277 struct ast_channel *c = o->chan;
1278
1279 if (c == NULL)
1280 continue;
1282 if (!peer) {
1283 ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1284 if (o->orig_chan_name
1285 && strcmp(o->orig_chan_name, ast_channel_name(c))) {
1286 /*
1287 * The channel name changed so we must generate COLP update.
1288 * Likely because a call pickup channel masqueraded in.
1289 */
1291 } else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1292 if (o->pending_connected_update) {
1295 }
1296 } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1298 }
1299 }
1300 if (o->aoc_s_rate_list) {
1301 size_t encoded_size;
1302 struct ast_aoc_encoded *encoded;
1303 if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1304 ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1305 ast_aoc_destroy_encoded(encoded);
1306 }
1307 }
1308 peer = c;
1309 publish_dial_end_event(in, out_chans, peer, "CANCEL");
1310 ast_copy_flags64(peerflags, o,
1317 ast_channel_dialcontext_set(c, "");
1319 }
1320 continue;
1321 }
1322 if (c != winner)
1323 continue;
1324 /* here, o->chan == c == winner */
1326 pa->sentringing = 0;
1327 if (!ignore_cc && (f = ast_read(c))) {
1329 /* This channel is forwarding the call, and is capable of CC, so
1330 * be sure to add the new device interface to the list
1331 */
1333 }
1334 ast_frfree(f);
1335 }
1336
1337 if (o->pending_connected_update) {
1338 /*
1339 * Re-seed the chanlist's connected line information with
1340 * previously acquired connected line info from the incoming
1341 * channel. The previously acquired connected line info could
1342 * have been set through the CONNECTED_LINE dialplan function.
1343 */
1348 }
1349
1350 do_forward(o, &num, peerflags, single, caller_entertained, &orig,
1351 forced_clid, stored_clid);
1352
1353 if (o->chan) {
1356 if (single
1360 }
1361 }
1362 continue;
1363 }
1364 f = ast_read(winner);
1365 if (!f) {
1368 ast_hangup(c);
1369 c = o->chan = NULL;
1372 continue;
1373 }
1374 switch (f->frametype) {
1375 case AST_FRAME_CONTROL:
1376 switch (f->subclass.integer) {
1377 case AST_CONTROL_ANSWER:
1378 /* This is our guy if someone answered. */
1379 if (!peer) {
1380 ast_trace(-1, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1381 ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1382 if (o->orig_chan_name
1383 && strcmp(o->orig_chan_name, ast_channel_name(c))) {
1384 /*
1385 * The channel name changed so we must generate COLP update.
1386 * Likely because a call pickup channel masqueraded in.
1387 */
1389 } else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1390 if (o->pending_connected_update) {
1393 }
1394 } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1396 }
1397 }
1398 if (o->aoc_s_rate_list) {
1399 size_t encoded_size;
1400 struct ast_aoc_encoded *encoded;
1401 if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1402 ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1403 ast_aoc_destroy_encoded(encoded);
1404 }
1405 }
1406 peer = c;
1407 /* Answer can optionally include a topology */
1408 if (f->subclass.topology) {
1409 /*
1410 * We need to bump the refcount on the topology to prevent it
1411 * from being cleaned up when the frame is cleaned up.
1412 */
1413 config->answer_topology = ao2_bump(f->subclass.topology);
1414 ast_trace(-1, "%s Found topology in frame: %p %p %s\n",
1415 ast_channel_name(peer), f, config->answer_topology,
1416 ast_str_tmp(256, ast_stream_topology_to_str(config->answer_topology, &STR_TMP)));
1417 }
1418
1419 /* Inform everyone else that they've been canceled.
1420 * The dial end event for the peer will be sent out after
1421 * other Dial options have been handled.
1422 */
1423 publish_dial_end_event(in, out_chans, peer, "CANCEL");
1424 ast_copy_flags64(peerflags, o,
1431 ast_channel_dialcontext_set(c, "");
1433 if (CAN_EARLY_BRIDGE(peerflags, in, peer)) {
1434 /* Setup early bridge if appropriate */
1436 }
1437 }
1438 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
1441 break;
1442 case AST_CONTROL_BUSY:
1443 ast_verb(3, "%s is busy\n", ast_channel_name(c));
1445 ast_channel_publish_dial(in, c, NULL, "BUSY");
1446 ast_hangup(c);
1447 c = o->chan = NULL;
1450 break;
1452 ast_verb(3, "%s is circuit-busy\n", ast_channel_name(c));
1454 ast_channel_publish_dial(in, c, NULL, "CONGESTION");
1455 ast_hangup(c);
1456 c = o->chan = NULL;
1459 break;
1461 /* This is a tricky area to get right when using a native
1462 * CC agent. The reason is that we do the best we can to send only a
1463 * single ringing notification to the caller.
1464 *
1465 * Call completion complicates the logic used here. CCNR is typically
1466 * offered during a ringing message. Let's say that party A calls
1467 * parties B, C, and D. B and C do not support CC requests, but D
1468 * does. If we were to receive a ringing notification from B before
1469 * the others, then we would end up sending a ringing message to
1470 * A with no CCNR offer present.
1471 *
1472 * The approach that we have taken is that if we receive a ringing
1473 * response from a party and no CCNR offer is present, we need to
1474 * wait. Specifically, we need to wait until either a) a called party
1475 * offers CCNR in its ringing response or b) all called parties have
1476 * responded in some way to our call and none offers CCNR.
1477 *
1478 * The drawback to this is that if one of the parties has a delayed
1479 * response or, god forbid, one just plain doesn't respond to our
1480 * outgoing call, then this will result in a significant delay between
1481 * when the caller places the call and hears ringback.
1482 *
1483 * Note also that if CC is disabled for this call, then it is perfectly
1484 * fine for ringing frames to get sent through.
1485 */
1486 ++num_ringing;
1487 if (ignore_cc || cc_frame_received || num_ringing == numlines) {
1488 ast_verb(3, "%s is ringing\n", ast_channel_name(c));
1489 /* Setup early media if appropriate */
1490 if (single && !caller_entertained
1491 && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1493 }
1496 pa->sentringing++;
1497 }
1498 if (!sent_ring) {
1499 struct timeval now, then;
1500 int64_t diff;
1501
1502 now = ast_tvnow();
1503
1506
1508 diff = ast_tvzero(then) ? 0 : ast_tvdiff_ms(now, then);
1509 set_duration_var(in, "RINGTIME", diff);
1510
1513 sent_ring = 1;
1514 }
1515 }
1516 ast_channel_publish_dial(in, c, NULL, "RINGING");
1517 break;
1519 ast_verb(3, "%s is making progress passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1520 /* Setup early media if appropriate */
1521 if (single && !caller_entertained
1522 && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1524 }
1526 if (single || (!single && !pa->sentringing)) {
1528 }
1529 }
1530 if (!sent_progress) {
1531 struct timeval now, then;
1532 int64_t diff;
1533
1534 now = ast_tvnow();
1535
1538
1540 diff = ast_tvzero(then) ? 0 : ast_tvdiff_ms(now, then);
1541 set_duration_var(in, "PROGRESSTIME", diff);
1542
1545 sent_progress = 1;
1546
1547 if (!ast_strlen_zero(mf_progress)) {
1548 ast_verb(3,
1549 "Sending MF '%s' to %s as result of "
1550 "receiving a PROGRESS message.\n",
1551 mf_progress, hearpulsing ? "parties" : "called party");
1552 res |= ast_mf_stream(c, (hearpulsing ? NULL : in),
1553 (hearpulsing ? in : NULL), mf_progress, 50, 55, 120, 65, 0);
1554 }
1555 if (!ast_strlen_zero(sf_progress)) {
1556 ast_verb(3,
1557 "Sending SF '%s' to %s as result of "
1558 "receiving a PROGRESS message.\n",
1559 sf_progress, (hearpulsing ? "parties" : "called party"));
1560 res |= ast_sf_stream(c, (hearpulsing ? NULL : in),
1561 (hearpulsing ? in : NULL), sf_progress, 0, 0);
1562 }
1563 if (!ast_strlen_zero(dtmf_progress)) {
1564 ast_verb(3,
1565 "Sending DTMF '%s' to the called party as result of "
1566 "receiving a PROGRESS message.\n",
1567 dtmf_progress);
1568 res |= ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
1569 }
1570 if (res) {
1571 ast_log(LOG_WARNING, "Called channel %s hung up post-progress before all digits could be sent\n", ast_channel_name(c));
1572 goto wait_over;
1573 }
1574 }
1575 ast_channel_publish_dial(in, c, NULL, "PROGRESS");
1576 break;
1577 case AST_CONTROL_WINK:
1578 ast_verb(3, "%s winked, passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1579 if (!sent_wink) {
1580 sent_wink = 1;
1581 if (!ast_strlen_zero(mf_wink)) {
1582 ast_verb(3,
1583 "Sending MF '%s' to %s as result of "
1584 "receiving a WINK message.\n",
1585 mf_wink, (hearpulsing ? "parties" : "called party"));
1586 res |= ast_mf_stream(c, (hearpulsing ? NULL : in),
1587 (hearpulsing ? in : NULL), mf_wink, 50, 55, 120, 65, 0);
1588 }
1589 if (!ast_strlen_zero(sf_wink)) {
1590 ast_verb(3,
1591 "Sending SF '%s' to %s as result of "
1592 "receiving a WINK message.\n",
1593 sf_wink, (hearpulsing ? "parties" : "called party"));
1594 res |= ast_sf_stream(c, (hearpulsing ? NULL : in),
1595 (hearpulsing ? in : NULL), sf_wink, 0, 0);
1596 }
1597 if (res) {
1598 ast_log(LOG_WARNING, "Called channel %s hung up post-wink before all digits could be sent\n", ast_channel_name(c));
1599 goto wait_over;
1600 }
1601 }
1603 break;
1607 if (!single || caller_entertained) {
1608 break;
1609 }
1610 ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1613 break;
1616 ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(in));
1617 break;
1618 }
1619 if (!single) {
1621
1622 ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n",
1629 break;
1630 }
1631 if (ast_channel_connected_line_sub(c, in, f, 1)) {
1633 }
1634 break;
1635 case AST_CONTROL_AOC:
1636 {
1637 struct ast_aoc_decoded *decoded = ast_aoc_decode(f->data.ptr, f->datalen, o->chan);
1638 if (decoded && (ast_aoc_get_msg_type(decoded) == AST_AOC_S)) {
1640 o->aoc_s_rate_list = decoded;
1641 } else {
1642 ast_aoc_destroy_decoded(decoded);
1643 }
1644 }
1645 break;
1647 if (!single) {
1648 /*
1649 * Redirecting updates to the caller make sense only on single
1650 * calls.
1651 */
1652 break;
1653 }
1655 ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(in));
1656 break;
1657 }
1658 ast_verb(3, "%s redirecting info has changed, passing it to %s\n",
1660 if (ast_channel_redirecting_sub(c, in, f, 1)) {
1662 }
1663 pa->sentringing = 0;
1664 break;
1666 ast_verb(3, "%s is proceeding passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1667 if (single && !caller_entertained
1668 && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1670 }
1673 ast_channel_publish_dial(in, c, NULL, "PROCEEDING");
1674 break;
1675 case AST_CONTROL_HOLD:
1676 /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1677 ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(c));
1679 break;
1680 case AST_CONTROL_UNHOLD:
1681 /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1682 ast_verb(3, "Call on %s left from hold\n", ast_channel_name(c));
1684 break;
1686 case AST_CONTROL_FLASH:
1687 /* Ignore going off hook and flash */
1688 break;
1689 case AST_CONTROL_CC:
1690 if (!ignore_cc) {
1692 cc_frame_received = 1;
1693 }
1694 break;
1697 break;
1698 case -1:
1699 if (single && !caller_entertained) {
1700 ast_verb(3, "%s stopped sounds\n", ast_channel_name(c));
1701 ast_indicate(in, -1);
1702 pa->sentringing = 0;
1703 }
1704 break;
1705 default:
1706 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass.integer);
1707 break;
1708 }
1709 break;
1710 case AST_FRAME_VIDEO:
1711 case AST_FRAME_VOICE:
1712 case AST_FRAME_IMAGE:
1714 case AST_FRAME_DTMF_END:
1715 if (caller_entertained) {
1716 break;
1717 }
1718 /* Fall through */
1719 case AST_FRAME_TEXT:
1720 if (single && ast_write(in, f)) {
1721 ast_log(LOG_WARNING, "Unable to write frametype: %u\n",
1722 f->frametype);
1723 }
1724 break;
1725 case AST_FRAME_HTML:
1727 && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1728 ast_log(LOG_WARNING, "Unable to send URL\n");
1729 }
1730 break;
1731 default:
1732 break;
1733 }
1734 ast_frfree(f);
1735 } /* end for */
1736 if (winner == in) {
1737 struct ast_frame *f = ast_read(in);
1738#if 0
1739 if (f && (f->frametype != AST_FRAME_VOICE))
1740 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
1741 else if (!f || (f->frametype != AST_FRAME_VOICE))
1742 printf("Hangup received on %s\n", in->name);
1743#endif
1744 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP))) {
1745 /* Got hung up */
1746 *to = -1;
1747 strcpy(pa->status, "CANCEL");
1748 pa->canceled = 1;
1749 publish_dial_end_event(in, out_chans, NULL, pa->status);
1750 if (f) {
1751 if (f->data.uint32) {
1753 }
1754 ast_frfree(f);
1755 }
1756 if (is_cc_recall) {
1757 ast_cc_completed(in, "CC completed, although the caller hung up (cancelled)");
1758 }
1759 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller hung up\n", ast_channel_name(in));
1760 }
1761
1762 /* now f is guaranteed non-NULL */
1763 if (f->frametype == AST_FRAME_DTMF) {
1764 if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
1765 const char *context;
1767 context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
1768 if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
1769 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
1770 *to = 0;
1771 *result = f->subclass.integer;
1772 strcpy(pa->status, "CANCEL");
1773 pa->canceled = 1;
1774 publish_dial_end_event(in, out_chans, NULL, pa->status);
1775 ast_frfree(f);
1777 if (is_cc_recall) {
1778 ast_cc_completed(in, "CC completed, but the caller used DTMF to exit");
1779 }
1780 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller pressed %c to end call\n",
1782 }
1784 }
1785
1786 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
1787 detect_disconnect(in, f->subclass.integer, &featurecode)) {
1788 ast_verb(3, "User requested call disconnect.\n");
1789 *to = 0;
1790 strcpy(pa->status, "CANCEL");
1791 pa->canceled = 1;
1792 publish_dial_end_event(in, out_chans, NULL, pa->status);
1793 ast_frfree(f);
1794 if (is_cc_recall) {
1795 ast_cc_completed(in, "CC completed, but the caller hung up with DTMF");
1796 }
1797 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller requested disconnect\n",
1799 }
1800 }
1801
1802 /* Send the frame from the in channel to all outgoing channels. */
1803 AST_LIST_TRAVERSE(out_chans, o, node) {
1804 if (!o->chan || !ast_test_flag64(o, DIAL_STILLGOING)) {
1805 /* This outgoing channel has died so don't send the frame to it. */
1806 continue;
1807 }
1808 switch (f->frametype) {
1809 case AST_FRAME_HTML:
1810 /* Forward HTML stuff */
1812 && ast_channel_sendhtml(o->chan, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1813 ast_log(LOG_WARNING, "Unable to send URL\n");
1814 }
1815 break;
1816 case AST_FRAME_VIDEO:
1817 case AST_FRAME_VOICE:
1818 case AST_FRAME_IMAGE:
1819 if (!single || caller_entertained) {
1820 /*
1821 * We are calling multiple parties or caller is being
1822 * entertained and has thus not been made compatible.
1823 * No need to check any other called parties.
1824 */
1825 goto skip_frame;
1826 }
1827 /* Fall through */
1828 case AST_FRAME_TEXT:
1830 case AST_FRAME_DTMF_END:
1831 if (ast_write(o->chan, f)) {
1832 ast_log(LOG_WARNING, "Unable to forward frametype: %u\n",
1833 f->frametype);
1834 }
1835 break;
1836 case AST_FRAME_CONTROL:
1837 switch (f->subclass.integer) {
1838 case AST_CONTROL_HOLD:
1839 ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(o->chan));
1841 break;
1842 case AST_CONTROL_UNHOLD:
1843 ast_verb(3, "Call on %s left from hold\n", ast_channel_name(o->chan));
1845 break;
1846 case AST_CONTROL_FLASH:
1847 ast_verb(3, "Hook flash on %s\n", ast_channel_name(o->chan));
1849 break;
1853 if (!single || caller_entertained) {
1854 /*
1855 * We are calling multiple parties or caller is being
1856 * entertained and has thus not been made compatible.
1857 * No need to check any other called parties.
1858 */
1859 goto skip_frame;
1860 }
1861 ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1864 break;
1867 ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(o->chan));
1868 break;
1869 }
1870 if (ast_channel_connected_line_sub(in, o->chan, f, 1)) {
1872 }
1873 break;
1876 ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(o->chan));
1877 break;
1878 }
1879 if (ast_channel_redirecting_sub(in, o->chan, f, 1)) {
1881 }
1882 break;
1883 default:
1884 /* We are not going to do anything with this frame. */
1885 goto skip_frame;
1886 }
1887 break;
1888 default:
1889 /* We are not going to do anything with this frame. */
1890 goto skip_frame;
1891 }
1892 }
1893skip_frame:;
1894 ast_frfree(f);
1895 }
1896 }
1897
1898wait_over:
1899 if (!*to || ast_check_hangup(in)) {
1900 ast_verb(3, "Nobody picked up in %d ms\n", orig);
1901 publish_dial_end_event(in, out_chans, NULL, "NOANSWER");
1902 }
1903
1904 if (is_cc_recall) {
1905 ast_cc_completed(in, "Recall completed!");
1906 }
1907 SCOPE_EXIT_RTN_VALUE(peer, "%s: %s%s\n", ast_channel_name(in),
1908 peer ? "Answered by " : "No answer", peer ? ast_channel_name(peer) : "");
1909}
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:313
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
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
@ AST_AOC_S
Definition: aoc.h:64
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:918
#define AST_MAX_WATCHERS
Definition: app_dial.c:839
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:1130
static void update_connected_line_from_peer(struct ast_channel *chan, struct ast_channel *peer, int is_caller)
Definition: app_dial.c:1150
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode)
Definition: app_dial.c:1911
#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:3405
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:2293
int ast_cc_completed(struct ast_channel *chan, const char *const debug,...)
Indicate recall has been acknowledged.
Definition: ccss.c:3807
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
Definition: ccss.c:3844
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:6621
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:5137
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:8778
const char * ast_hangup_cause_to_dial_status(int hangup_cause)
Convert a hangup cause to a publishable dial status.
Definition: dial.c:749
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:1097
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:1113
#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:845
struct ast_stream_topology * topology
Support for dynamic strings.
Definition: strings.h:623
struct ast_aoc_decoded * aoc_s_rate_list
Definition: app_dial.c:804
struct ast_party_connected_line connected
Definition: app_dial.c:801
char * orig_chan_name
Definition: app_dial.c:798
unsigned int pending_connected_update
Definition: app_dial.c:803
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:2279
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107

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_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_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, voicemailpwcheck::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 3535 of file app_dial.c.

◆ app

const char app[] = "Dial"
static

Definition at line 656 of file app_dial.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 3535 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' ] = { .flag = OPT_MUSICBACK , .arg_index = OPT_ARG_MUSICBACK + 1 }, [ 'n' ] = { .flag = OPT_SCREEN_NOINTRO , .arg_index = OPT_ARG_SCREEN_NOINTRO + 1 }, [ 'N' ] = { .flag = OPT_SCREEN_NOCALLERID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID , .arg_index = OPT_ARG_ORIGINAL_CLID + 1 }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'Q' ] = { .flag = (1LLU << 44) , .arg_index = OPT_ARG_HANGUPCAUSE + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK , .arg_index = OPT_ARG_RINGBACK + 1 }, [ 'R' ] = { .flag = (1LLU << 43) }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 's' ] = { .flag = (1LLU << 38) , .arg_index = OPT_ARG_FORCE_CID_TAG + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'u' ] = { .flag = (1LLU << 39) , .arg_index = OPT_ARG_FORCE_CID_PRES + 1 }, [ 'U' ] = { .flag = OPT_CALLEE_GOSUB , .arg_index = OPT_ARG_CALLEE_GOSUB + 1 }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR }, [ 'x' ] = { .flag = OPT_CALLEE_MIXMONITOR }, [ 'X' ] = { .flag = OPT_CALLER_MIXMONITOR }, [ 'z' ] = { .flag = (1LLU << 37) }, }
static

Definition at line 776 of file app_dial.c.

Referenced by dial_exec_full().

◆ rapp

const char rapp[] = "RetryDial"
static

Definition at line 657 of file app_dial.c.

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