Wed Jan 8 2020 09:49:53

Asterisk developer's documentation


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 <sys/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/cdr.h"
#include "asterisk/manager.h"
#include "asterisk/privacy.h"
#include "asterisk/stringfields.h"
#include "asterisk/global_datastores.h"
#include "asterisk/dsp.h"
#include "asterisk/cel.h"
#include "asterisk/aoc.h"
#include "asterisk/ccss.h"
#include "asterisk/indications.h"
#include "asterisk/framehook.h"

Go to the source code of this file.

Data Structures

struct  cause_args
 
struct  chanlist
 List of channel drivers. More...
 
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_PEER_H   (1LLU << 35)
 

Enumerations

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

Functions

static void __reg_module (void)
 
static void __unreg_module (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 chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
 
static int load_module (void)
 
static int onedigit_goto (struct ast_channel *chan, const char *context, char exten, int pri)
 
static void replace_macro_delimiter (char *s)
 
static int retrydial_exec (struct ast_channel *chan, const char *data)
 
static void senddialendevent (struct ast_channel *src, const char *dialstatus)
 
static void senddialevent (struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
 
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 int valid_priv_reply (struct ast_flags64 *opts, int res)
 
static struct ast_channelwait_for_answer (struct ast_channel *in, struct chanlist *outgoing, int *to, struct ast_flags64 *peerflags, char *opt_args[], struct privacy_args *pa, const struct cause_args *num_in, int *result, char *dtmf_progress, const int ignore_cc, struct ast_party_id *forced_clid, struct ast_party_id *stored_clid)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
 
static const char app [] = "Dial"
 
static struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_app_option dial_exec_options [128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'a' ] = { .flag = (1LLU << 40) }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'c' ] = { .flag = (1LLU << 34) }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'e' ] = { .flag = (1LLU << 35) }, [ 'f' ] = { .flag = OPT_FORCECLID , .arg_index = OPT_ARG_FORCECLID + 1 }, [ 'F' ] = { .flag = (1LLU << 36) , .arg_index = OPT_ARG_CALLEE_GO_ON + 1 }, [ 'g' ] = { .flag = OPT_GO_ON }, [ 'G' ] = { .flag = OPT_GOTO , .arg_index = OPT_ARG_GOTO + 1 }, [ 'h' ] = { .flag = OPT_CALLEE_HANGUP }, [ 'H' ] = { .flag = OPT_CALLER_HANGUP }, [ 'i' ] = { .flag = OPT_IGNORE_FORWARDING }, [ 'I' ] = { .flag = OPT_IGNORE_CONNECTEDLINE }, [ 'k' ] = { .flag = OPT_CALLEE_PARK }, [ 'K' ] = { .flag = OPT_CALLER_PARK }, [ 'L' ] = { .flag = OPT_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, [ 'm' ] = { .flag = OPT_MUSICBACK , .arg_index = OPT_ARG_MUSICBACK + 1 }, [ 'M' ] = { .flag = OPT_CALLEE_MACRO , .arg_index = OPT_ARG_CALLEE_MACRO + 1 }, [ 'n' ] = { .flag = OPT_SCREEN_NOINTRO , .arg_index = OPT_ARG_SCREEN_NOINTRO + 1 }, [ 'N' ] = { .flag = OPT_SCREEN_NOCALLERID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID , .arg_index = OPT_ARG_ORIGINAL_CLID + 1 }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK , .arg_index = OPT_ARG_RINGBACK + 1 }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 's' ] = { .flag = (1LLU << 38) , .arg_index = OPT_ARG_FORCE_CID_TAG + 1 }, [ 'u' ] = { .flag = (1LLU << 39) , .arg_index = OPT_ARG_FORCE_CID_PRES + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ '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

#define AST_MAX_WATCHERS   256

Definition at line 705 of file app_dial.c.

Referenced by wait_for_answer().

#define CAN_EARLY_BRIDGE (   flags,
  chan,
  peer 
)

Definition at line 654 of file app_dial.c.

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

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

Definition at line 582 of file app_dial.c.

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

#define DIAL_NOFORWARDHTML   (1LLU << 32)

Definition at line 581 of file app_dial.c.

Referenced by dial_exec_full(), and wait_for_answer().

#define DIAL_STILLGOING   (1LLU << 31)

Definition at line 580 of file app_dial.c.

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

#define OPT_CALLEE_GO_ON   (1LLU << 36)

Definition at line 585 of file app_dial.c.

Referenced by dial_exec_full().

#define OPT_CALLER_ANSWER   (1LLU << 40)

Definition at line 589 of file app_dial.c.

Referenced by dial_exec_full().

#define OPT_CANCEL_ELSEWHERE   (1LLU << 34)

Definition at line 583 of file app_dial.c.

Referenced by dial_exec_full().

#define OPT_CANCEL_TIMEOUT   (1LLU << 37)

Definition at line 586 of file app_dial.c.

Referenced by dial_exec_full(), and do_forward().

#define OPT_FORCE_CID_PRES   (1LLU << 39)

Definition at line 588 of file app_dial.c.

Referenced by dial_exec_full().

#define OPT_FORCE_CID_TAG   (1LLU << 38)

Definition at line 587 of file app_dial.c.

Referenced by dial_exec_full().

#define OPT_PEER_H   (1LLU << 35)

Definition at line 584 of file app_dial.c.

Referenced by dial_exec_full().

Enumeration Type Documentation

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

Definition at line 591 of file app_dial.c.

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

Definition at line 545 of file app_dial.c.

545  {
546  OPT_ANNOUNCE = (1 << 0),
547  OPT_RESETCDR = (1 << 1),
548  OPT_DTMF_EXIT = (1 << 2),
549  OPT_SENDDTMF = (1 << 3),
550  OPT_FORCECLID = (1 << 4),
551  OPT_GO_ON = (1 << 5),
552  OPT_CALLEE_HANGUP = (1 << 6),
553  OPT_CALLER_HANGUP = (1 << 7),
554  OPT_ORIGINAL_CLID = (1 << 8),
555  OPT_DURATION_LIMIT = (1 << 9),
556  OPT_MUSICBACK = (1 << 10),
557  OPT_CALLEE_MACRO = (1 << 11),
558  OPT_SCREEN_NOINTRO = (1 << 12),
559  OPT_SCREEN_NOCALLERID = (1 << 13),
560  OPT_IGNORE_CONNECTEDLINE = (1 << 14),
561  OPT_SCREENING = (1 << 15),
562  OPT_PRIVACY = (1 << 16),
563  OPT_RINGBACK = (1 << 17),
564  OPT_DURATION_STOP = (1 << 18),
565  OPT_CALLEE_TRANSFER = (1 << 19),
566  OPT_CALLER_TRANSFER = (1 << 20),
567  OPT_CALLEE_MONITOR = (1 << 21),
568  OPT_CALLER_MONITOR = (1 << 22),
569  OPT_GOTO = (1 << 23),
570  OPT_OPERMODE = (1 << 24),
571  OPT_CALLEE_PARK = (1 << 25),
572  OPT_CALLER_PARK = (1 << 26),
573  OPT_IGNORE_FORWARDING = (1 << 27),
574  OPT_CALLEE_GOSUB = (1 << 28),
575  OPT_CALLEE_MIXMONITOR = (1 << 29),
576  OPT_CALLER_MIXMONITOR = (1 << 30),
577 };

Function Documentation

static void __reg_module ( void  )
static

Definition at line 3205 of file app_dial.c.

static void __unreg_module ( void  )
static

Definition at line 3205 of file app_dial.c.

static void chanlist_free ( struct chanlist outgoing)
static

Definition at line 677 of file app_dial.c.

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

Referenced by dial_exec_full(), and hanguptree().

678 {
681  ast_free(outgoing);
682 }
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:176
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2353
struct ast_party_connected_line connected
Definition: app_dial.c:669
#define ast_free(a)
Definition: astmm.h:97
struct ast_aoc_decoded * aoc_s_rate_list
Definition: app_dial.c:672
static int detect_disconnect ( struct ast_channel chan,
char  code,
struct ast_str **  featurecode 
)
static

Definition at line 1652 of file app_dial.c.

References ast_feature_detect(), AST_FEATURE_DISCONNECT, AST_FEATURE_RETURN_STOREDIGITS, ast_str_append(), ast_str_buffer(), ast_str_reset(), and ast_call_feature::feature_mask.

Referenced by wait_for_answer().

1653 {
1654  struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
1655  struct ast_call_feature feature = { 0, };
1656  int res;
1657 
1658  ast_str_append(featurecode, 1, "%c", code);
1659 
1660  res = ast_feature_detect(chan, &features, ast_str_buffer(*featurecode), &feature);
1661 
1662  if (res != AST_FEATURE_RETURN_STOREDIGITS) {
1663  ast_str_reset(*featurecode);
1664  }
1665  if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
1666  return 1;
1667  }
1668 
1669  return 0;
1670 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
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:900
#define AST_FEATURE_RETURN_STOREDIGITS
Definition: features.h:44
Structure used to handle boolean flags.
Definition: utils.h:200
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:436
int ast_feature_detect(struct ast_channel *chan, struct ast_flags *features, const char *code, struct ast_call_feature *feature)
detect a feature before bridging
Definition: features.c:3434
static int dial_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 3055 of file app_dial.c.

References dial_exec_full().

Referenced by load_module().

3056 {
3057  struct ast_flags64 peerflags;
3058 
3059  memset(&peerflags, 0, sizeof(peerflags));
3060 
3061  return dial_exec_full(chan, data, &peerflags, NULL);
3062 }
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:206
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
Definition: app_dial.c:1987
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 1987 of file app_dial.c.

References ast_channel::_state, accountcode, ast_channel::accountcode, ast_channel::adsicpe, ast_cdr::answer, ast_channel::appl, args, ast_answer(), AST_APP_ARG, ast_app_group_set_channel(), ast_app_parse_options64(), ast_asprintf, ast_autoservice_start(), ast_autoservice_stop(), ast_bridge_call(), ast_bridge_timelimit(), ast_call(), ast_callerid_parse(), ast_calloc, ast_cause2str(), AST_CAUSE_ANSWERED_ELSEWHERE, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_cc_busy_interface(), ast_cc_call_failed(), ast_cc_call_init(), ast_cc_callback(), ast_cc_extension_monitor_add_dialstring(), AST_CDR_FLAG_DIALED, ast_cdr_reset(), ast_cdr_setanswer(), ast_cdr_setdestchan(), ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_datastore_inherit(), ast_channel_datastore_remove(), ast_channel_early_bridge(), ast_channel_get_device_name(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_make_compatible(), AST_CHANNEL_NAME, ast_channel_sendurl(), ast_channel_set_caller_event(), ast_channel_set_connected_line(), ast_channel_setoption(), ast_channel_supports_html(), ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, ast_connected_line_copy_from_caller(), AST_CONTROL_HANGUP, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_copy_flags64, ast_copy_string(), ast_datastore_alloc(), ast_datastore_free(), 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_NO_H_EXTEN, AST_FEATURE_PARKCALL, AST_FEATURE_REDIRECT, ast_filedelete(), ast_fileexists(), AST_FLAG_ANSWERED_ELSEWHERE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_IN_AUTOLOOP, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, ast_free, ast_frfree, ast_goto_if_exists(), ast_hangup(), ast_ignore_cc(), ast_indicate(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), AST_MAX_EXTENSION, 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_run_args(), ast_pbx_start(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRIVACY_UNKNOWN, ast_read(), ast_request(), ast_rtp_instance_early_bridge_make_compatible(), ast_sched_runq(), ast_sched_wait(), ast_senddigit(), ast_set2_flag, ast_set2_flag64, ast_set_flag, ast_set_flag64, ast_spawn_extension(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_tvadd(), ast_tvnow(), ast_tvzero(), ast_verb, ast_waitfor_n(), ast_channel::caller, CAN_EARLY_BRIDGE, ast_channel::cdr, chanlist::chan, cause_args::chan, chanlist_free(), CHANNEL_DEADLOCK_AVOIDANCE, chanlist::connected, ast_channel::connected, ast_channel::context, ast_datastore::data, ast_channel::data, DATASTORE_INHERIT_FOREVER, di, DIAL_CALLERID_ABSENT, dial_exec_options, dial_handle_playtones(), DIAL_NOFORWARDHTML, DIAL_STILLGOING, dialcontext, ast_channel::dialed, dialed_interface_info, ast_bridge_config::end_bridge_callback, end_bridge_callback(), ast_bridge_config::end_bridge_callback_data, ast_bridge_config::end_bridge_callback_data_fixup, end_bridge_callback_data_fixup(), ast_bridge_config::end_sound, ast_channel::exten, ast_bridge_config::features_callee, ast_bridge_config::features_caller, ast_flags64::flags, ast_frame::frametype, get_cid_name(), handle_cause(), ast_channel::hangupcause, hanguptree(), ast_party_caller::id, ast_party_connected_line::id, ast_datastore::inheritance, ast_frame_subclass::integer, ast_dialed_interface::interface, ast_channel::language, ast_dialed_interface::list, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, ast_channel::macroexten, oprmode::mode, moh, musicclass, ast_channel::musicclass, ast_party_id::name, ast_channel::name, ast_channel::nativeformats, chanlist::next, ast_pbx_args::no_hangup_chan, ast_party_id::number, OPT_ANNOUNCE, OPT_ARG_ANNOUNCE, OPT_ARG_ARRAY_SIZE, OPT_ARG_CALLEE_GO_ON, OPT_ARG_CALLEE_GOSUB, OPT_ARG_CALLEE_MACRO, OPT_ARG_DURATION_LIMIT, OPT_ARG_DURATION_STOP, OPT_ARG_FORCE_CID_PRES, OPT_ARG_FORCE_CID_TAG, OPT_ARG_FORCECLID, OPT_ARG_GOTO, OPT_ARG_OPERMODE, OPT_ARG_ORIGINAL_CLID, OPT_ARG_PRIVACY, OPT_ARG_RINGBACK, OPT_ARG_SCREEN_NOINTRO, OPT_ARG_SENDDTMF, OPT_CALLEE_GO_ON, OPT_CALLEE_GOSUB, OPT_CALLEE_HANGUP, OPT_CALLEE_MACRO, OPT_CALLEE_MIXMONITOR, OPT_CALLEE_MONITOR, OPT_CALLEE_PARK, OPT_CALLEE_TRANSFER, OPT_CALLER_ANSWER, OPT_CALLER_HANGUP, OPT_CALLER_MIXMONITOR, OPT_CALLER_MONITOR, OPT_CALLER_PARK, OPT_CALLER_TRANSFER, OPT_CANCEL_ELSEWHERE, OPT_CANCEL_TIMEOUT, OPT_DTMF_EXIT, OPT_DURATION_LIMIT, OPT_DURATION_STOP, OPT_FORCE_CID_PRES, OPT_FORCE_CID_TAG, OPT_FORCECLID, OPT_GO_ON, OPT_GOTO, OPT_IGNORE_CONNECTEDLINE, OPT_IGNORE_FORWARDING, OPT_MUSICBACK, OPT_OPERMODE, OPT_ORIGINAL_CLID, OPT_PEER_H, OPT_PRIVACY, OPT_RESETCDR, OPT_RINGBACK, OPT_SCREEN_NOINTRO, OPT_SCREENING, OPT_SENDDTMF, parse(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_exec(), pbx_findapp(), oprmode::peer, ast_party_number::presentation, ast_channel::priority, privacy_args::privdb_val, privacy_args::privintro, ast_channel::redirecting, replace_macro_delimiter(), S_COR, S_OR, ast_channel::sched, senddialendevent(), senddialevent(), privacy_args::sentringing, setup_privacy_args(), ast_bridge_config::start_sound, privacy_args::status, ast_party_name::str, ast_party_number::str, ast_party_subaddress::str, ast_channel::stream, strsep(), ast_party_id::subaddress, ast_frame::subclass, ast_party_id::tag, ast_channel::timingfunc, ast_channel::transfercapability, ast_party_dialed::transit_network_select, url, ast_party_name::valid, ast_party_number::valid, ast_channel::visible_indication, wait_for_answer(), ast_bridge_config::warning_sound, and ast_channel::whentohangup.

Referenced by dial_exec(), and retrydial_exec().

1988 {
1989  int res = -1; /* default: error */
1990  char *rest, *cur; /* scan the list of destinations */
1991  struct chanlist *outgoing = NULL; /* list of destinations */
1992  struct ast_channel *peer;
1993  int to; /* timeout */
1994  struct cause_args num = { chan, 0, 0, 0 };
1995  int cause;
1996  char numsubst[256];
1997 
1998  struct ast_bridge_config config = { { 0, } };
1999  struct timeval calldurationlimit = { 0, };
2000  char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress=NULL;
2001  struct privacy_args pa = {
2002  .sentringing = 0,
2003  .privdb_val = 0,
2004  .status = "INVALIDARGS",
2005  };
2006  int sentringing = 0, moh = 0;
2007  const char *outbound_group = NULL;
2008  int result = 0;
2009  char *parse;
2010  int opermode = 0;
2011  int delprivintro = 0;
2013  AST_APP_ARG(peers);
2014  AST_APP_ARG(timeout);
2015  AST_APP_ARG(options);
2016  AST_APP_ARG(url);
2017  );
2018  struct ast_flags64 opts = { 0, };
2019  char *opt_args[OPT_ARG_ARRAY_SIZE];
2020  struct ast_datastore *datastore = NULL;
2021  int fulldial = 0, num_dialed = 0;
2022  int ignore_cc = 0;
2023  char device_name[AST_CHANNEL_NAME];
2024  char forced_clid_name[AST_MAX_EXTENSION];
2025  char stored_clid_name[AST_MAX_EXTENSION];
2026  int force_forwards_only; /*!< TRUE if force CallerID on call forward only. Legacy behaviour.*/
2027  /*!
2028  * \brief Forced CallerID party information to send.
2029  * \note This will not have any malloced strings so do not free it.
2030  */
2031  struct ast_party_id forced_clid;
2032  /*!
2033  * \brief Stored CallerID information if needed.
2034  *
2035  * \note If OPT_ORIGINAL_CLID set then this is the o option
2036  * CallerID. Otherwise it is the dialplan extension and hint
2037  * name.
2038  *
2039  * \note This will not have any malloced strings so do not free it.
2040  */
2041  struct ast_party_id stored_clid;
2042  /*!
2043  * \brief CallerID party information to store.
2044  * \note This will not have any malloced strings so do not free it.
2045  */
2046  struct ast_party_caller caller;
2047 
2048  /* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
2049  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
2050  pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
2051  pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
2052  pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
2053  pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
2054 
2055  if (ast_strlen_zero(data)) {
2056  ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
2057  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2058  return -1;
2059  }
2060 
2061  parse = ast_strdupa(data);
2062 
2063  AST_STANDARD_APP_ARGS(args, parse);
2064 
2065  if (!ast_strlen_zero(args.options) &&
2066  ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
2067  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2068  goto done;
2069  }
2070 
2071  if (ast_strlen_zero(args.peers)) {
2072  ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
2073  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2074  goto done;
2075  }
2076 
2077  if (ast_cc_call_init(chan, &ignore_cc)) {
2078  goto done;
2079  }
2080 
2082  delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
2083 
2084  if (delprivintro < 0 || delprivintro > 1) {
2085  ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
2086  delprivintro = 0;
2087  }
2088  }
2089 
2090  if (!ast_test_flag64(&opts, OPT_RINGBACK)) {
2091  opt_args[OPT_ARG_RINGBACK] = NULL;
2092  }
2093 
2094  if (ast_test_flag64(&opts, OPT_OPERMODE)) {
2095  opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
2096  ast_verb(3, "Setting operator services mode to %d.\n", opermode);
2097  }
2098 
2100  calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
2101  if (!calldurationlimit.tv_sec) {
2102  ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
2103  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2104  goto done;
2105  }
2106  ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
2107  }
2108 
2109  if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
2110  dtmf_progress = opt_args[OPT_ARG_SENDDTMF];
2111  dtmfcalled = strsep(&dtmf_progress, ":");
2112  dtmfcalling = strsep(&dtmf_progress, ":");
2113  }
2114 
2116  if (ast_bridge_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
2117  goto done;
2118  }
2119 
2120  /* Setup the forced CallerID information to send if used. */
2121  ast_party_id_init(&forced_clid);
2122  force_forwards_only = 0;
2123  if (ast_test_flag64(&opts, OPT_FORCECLID)) {
2124  if (ast_strlen_zero(opt_args[OPT_ARG_FORCECLID])) {
2125  ast_channel_lock(chan);
2126  forced_clid.number.str = ast_strdupa(S_OR(chan->macroexten, chan->exten));
2127  ast_channel_unlock(chan);
2128  forced_clid_name[0] = '\0';
2129  forced_clid.name.str = (char *) get_cid_name(forced_clid_name,
2130  sizeof(forced_clid_name), chan);
2131  force_forwards_only = 1;
2132  } else {
2133  /* Note: The opt_args[OPT_ARG_FORCECLID] string value is altered here. */
2134  ast_callerid_parse(opt_args[OPT_ARG_FORCECLID], &forced_clid.name.str,
2135  &forced_clid.number.str);
2136  }
2137  if (!ast_strlen_zero(forced_clid.name.str)) {
2138  forced_clid.name.valid = 1;
2139  }
2140  if (!ast_strlen_zero(forced_clid.number.str)) {
2141  forced_clid.number.valid = 1;
2142  }
2143  }
2145  && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_TAG])) {
2146  forced_clid.tag = opt_args[OPT_ARG_FORCE_CID_TAG];
2147  }
2148  forced_clid.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
2150  && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_PRES])) {
2151  int pres;
2152 
2153  pres = ast_parse_caller_presentation(opt_args[OPT_ARG_FORCE_CID_PRES]);
2154  if (0 <= pres) {
2155  forced_clid.number.presentation = pres;
2156  }
2157  }
2158 
2159  /* Setup the stored CallerID information if needed. */
2160  ast_party_id_init(&stored_clid);
2161  if (ast_test_flag64(&opts, OPT_ORIGINAL_CLID)) {
2162  if (ast_strlen_zero(opt_args[OPT_ARG_ORIGINAL_CLID])) {
2163  ast_channel_lock(chan);
2164  ast_party_id_set_init(&stored_clid, &chan->caller.id);
2165  if (!ast_strlen_zero(chan->caller.id.name.str)) {
2166  stored_clid.name.str = ast_strdupa(chan->caller.id.name.str);
2167  }
2168  if (!ast_strlen_zero(chan->caller.id.number.str)) {
2169  stored_clid.number.str = ast_strdupa(chan->caller.id.number.str);
2170  }
2171  if (!ast_strlen_zero(chan->caller.id.subaddress.str)) {
2172  stored_clid.subaddress.str = ast_strdupa(chan->caller.id.subaddress.str);
2173  }
2174  if (!ast_strlen_zero(chan->caller.id.tag)) {
2175  stored_clid.tag = ast_strdupa(chan->caller.id.tag);
2176  }
2177  ast_channel_unlock(chan);
2178  } else {
2179  /* Note: The opt_args[OPT_ARG_ORIGINAL_CLID] string value is altered here. */
2180  ast_callerid_parse(opt_args[OPT_ARG_ORIGINAL_CLID], &stored_clid.name.str,
2181  &stored_clid.number.str);
2182  if (!ast_strlen_zero(stored_clid.name.str)) {
2183  stored_clid.name.valid = 1;
2184  }
2185  if (!ast_strlen_zero(stored_clid.number.str)) {
2186  stored_clid.number.valid = 1;
2187  }
2188  }
2189  } else {
2190  /*
2191  * In case the new channel has no preset CallerID number by the
2192  * channel driver, setup the dialplan extension and hint name.
2193  */
2194  stored_clid_name[0] = '\0';
2195  stored_clid.name.str = (char *) get_cid_name(stored_clid_name,
2196  sizeof(stored_clid_name), chan);
2197  if (ast_strlen_zero(stored_clid.name.str)) {
2198  stored_clid.name.str = NULL;
2199  } else {
2200  stored_clid.name.valid = 1;
2201  }
2202  ast_channel_lock(chan);
2203  stored_clid.number.str = ast_strdupa(S_OR(chan->macroexten, chan->exten));
2204  stored_clid.number.valid = 1;
2205  ast_channel_unlock(chan);
2206  }
2207 
2208  if (ast_test_flag64(&opts, OPT_RESETCDR) && chan->cdr)
2209  ast_cdr_reset(chan->cdr, NULL);
2210  if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
2211  opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
2212 
2213  if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
2214  res = setup_privacy_args(&pa, &opts, opt_args, chan);
2215  if (res <= 0)
2216  goto out;
2217  res = -1; /* reset default */
2218  }
2219 
2220  if (continue_exec)
2221  *continue_exec = 0;
2222 
2223  /* If a channel group has been specified, get it for use when we create peer channels */
2224 
2225  ast_channel_lock(chan);
2226  if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
2227  outbound_group = ast_strdupa(outbound_group);
2228  pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
2229  } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
2230  outbound_group = ast_strdupa(outbound_group);
2231  }
2232  ast_channel_unlock(chan);
2233 
2234  /* Set per dial instance flags. These flags are also passed back to RetryDial. */
2238 
2239  /* loop through the list of dial destinations */
2240  rest = args.peers;
2241  while ((cur = strsep(&rest, "&")) ) {
2242  struct chanlist *tmp;
2243  struct ast_channel *tc; /* channel for this destination */
2244  /* Get a technology/[device:]number pair */
2245  char *number = cur;
2246  char *interface = ast_strdupa(number);
2247  char *tech = strsep(&number, "/");
2248  /* find if we already dialed this interface */
2249  struct ast_dialed_interface *di;
2250  AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
2251  num_dialed++;
2252  if (ast_strlen_zero(number)) {
2253  ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
2254  goto out;
2255  }
2256  if (!(tmp = ast_calloc(1, sizeof(*tmp))))
2257  goto out;
2258  if (opts.flags) {
2259  /* Set per outgoing call leg options. */
2260  ast_copy_flags64(tmp, &opts,
2269  }
2270  ast_copy_string(numsubst, number, sizeof(numsubst));
2271  /* Request the peer */
2272 
2273  ast_channel_lock(chan);
2274  datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
2275  /*
2276  * Seed the chanlist's connected line information with previously
2277  * acquired connected line info from the incoming channel. The
2278  * previously acquired connected line info could have been set
2279  * through the CONNECTED_LINE dialplan function.
2280  */
2282  ast_channel_unlock(chan);
2283 
2284  if (datastore)
2285  dialed_interfaces = datastore->data;
2286  else {
2287  if (!(datastore = ast_datastore_alloc(&dialed_interface_info, NULL))) {
2288  ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
2289  chanlist_free(tmp);
2290  goto out;
2291  }
2292 
2294 
2295  if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
2296  ast_datastore_free(datastore);
2297  chanlist_free(tmp);
2298  goto out;
2299  }
2300 
2301  datastore->data = dialed_interfaces;
2302  AST_LIST_HEAD_INIT(dialed_interfaces);
2303 
2304  ast_channel_lock(chan);
2305  ast_channel_datastore_add(chan, datastore);
2306  ast_channel_unlock(chan);
2307  }
2308 
2309  AST_LIST_LOCK(dialed_interfaces);
2310  AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
2311  if (!strcasecmp(di->interface, interface)) {
2312  ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
2313  di->interface);
2314  break;
2315  }
2316  }
2317  AST_LIST_UNLOCK(dialed_interfaces);
2318 
2319  if (di) {
2320  fulldial++;
2321  chanlist_free(tmp);
2322  continue;
2323  }
2324 
2325  /* It is always ok to dial a Local interface. We only keep track of
2326  * which "real" interfaces have been dialed. The Local channel will
2327  * inherit this list so that if it ends up dialing a real interface,
2328  * it won't call one that has already been called. */
2329  if (strcasecmp(tech, "Local")) {
2330  if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
2331  AST_LIST_UNLOCK(dialed_interfaces);
2332  chanlist_free(tmp);
2333  goto out;
2334  }
2335  strcpy(di->interface, interface);
2336 
2337  AST_LIST_LOCK(dialed_interfaces);
2338  AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
2339  AST_LIST_UNLOCK(dialed_interfaces);
2340  }
2341 
2342  tc = ast_request(tech, chan->nativeformats, chan, numsubst, &cause);
2343  if (!tc) {
2344  /* If we can't, just go on to the next call */
2345  ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
2346  tech, cause, ast_cause2str(cause));
2347  handle_cause(cause, &num);
2348  if (!rest) /* we are on the last destination */
2349  chan->hangupcause = cause;
2350  chanlist_free(tmp);
2351  if (!ignore_cc && (cause == AST_CAUSE_BUSY || cause == AST_CAUSE_CONGESTION)) {
2352  if (!ast_cc_callback(chan, tech, numsubst, ast_cc_busy_interface)) {
2354  }
2355  }
2356  continue;
2357  }
2358  ast_channel_get_device_name(tc, device_name, sizeof(device_name));
2359  if (!ignore_cc) {
2361  }
2362  pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
2363 
2364  ast_channel_lock(tc);
2365  while (ast_channel_trylock(chan)) {
2367  }
2368  /* Setup outgoing SDP to match incoming one */
2369  if (!outgoing && !rest && CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
2371  }
2372 
2373  /* Inherit specially named variables from parent channel */
2376 
2377  tc->appl = "AppDial";
2378  tc->data = "(Outgoing Line)";
2379  memset(&tc->whentohangup, 0, sizeof(tc->whentohangup));
2380 
2381  /* Determine CallerID to store in outgoing channel. */
2382  ast_party_caller_set_init(&caller, &tc->caller);
2383  if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
2384  caller.id = stored_clid;
2385  ast_channel_set_caller_event(tc, &caller, NULL);
2387  } else if (ast_strlen_zero(S_COR(tc->caller.id.number.valid,
2388  tc->caller.id.number.str, NULL))) {
2389  /*
2390  * The new channel has no preset CallerID number by the channel
2391  * driver. Use the dialplan extension and hint name.
2392  */
2393  caller.id = stored_clid;
2394  if (!caller.id.name.valid
2396  chan->connected.id.name.str, NULL))) {
2397  /*
2398  * No hint name available. We have a connected name supplied by
2399  * the dialplan we can use instead.
2400  */
2401  caller.id.name.valid = 1;
2402  caller.id.name = chan->connected.id.name;
2403  }
2404  ast_channel_set_caller_event(tc, &caller, NULL);
2406  } else if (ast_strlen_zero(S_COR(tc->caller.id.name.valid, tc->caller.id.name.str,
2407  NULL))) {
2408  /* The new channel has no preset CallerID name by the channel driver. */
2410  chan->connected.id.name.str, NULL))) {
2411  /*
2412  * We have a connected name supplied by the dialplan we can
2413  * use instead.
2414  */
2415  caller.id.name.valid = 1;
2416  caller.id.name = chan->connected.id.name;
2417  ast_channel_set_caller_event(tc, &caller, NULL);
2418  }
2419  }
2420 
2421  /* Determine CallerID for outgoing channel to send. */
2422  if (ast_test_flag64(peerflags, OPT_FORCECLID) && !force_forwards_only) {
2424 
2426  connected.id = forced_clid;
2428  } else {
2430  }
2431 
2433 
2435 
2436  if (!ast_strlen_zero(chan->accountcode)) {
2438  }
2439  if (ast_strlen_zero(tc->musicclass))
2441 
2442  /* Pass ADSI CPE and transfer capability */
2443  tc->adsicpe = chan->adsicpe;
2445 
2446  /* If we have an outbound group, set this peer channel to it */
2447  if (outbound_group)
2448  ast_app_group_set_channel(tc, outbound_group);
2449  /* If the calling channel has the ANSWERED_ELSEWHERE flag set, inherit it. This is to support local channels */
2452 
2453  /* Check if we're forced by configuration */
2456 
2457 
2458  /* Inherit context and extension */
2460  if (!ast_strlen_zero(chan->macroexten))
2461  ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
2462  else
2463  ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
2464 
2465  ast_channel_unlock(tc);
2466  ast_channel_unlock(chan);
2467  res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */
2468  ast_channel_lock(chan);
2469 
2470  /* Save the info in cdr's that we called them */
2471  if (chan->cdr)
2472  ast_cdr_setdestchan(chan->cdr, tc->name);
2473 
2474  /* check the results of ast_call */
2475  if (res) {
2476  /* Again, keep going even if there's an error */
2477  ast_debug(1, "ast call on peer returned %d\n", res);
2478  ast_verb(3, "Couldn't call %s/%s\n", tech, numsubst);
2479  if (tc->hangupcause) {
2480  chan->hangupcause = tc->hangupcause;
2481  }
2482  ast_channel_unlock(chan);
2483  ast_cc_call_failed(chan, tc, interface);
2484  ast_hangup(tc);
2485  tc = NULL;
2486  chanlist_free(tmp);
2487  continue;
2488  } else {
2489  senddialevent(chan, tc, numsubst);
2490  ast_verb(3, "Called %s/%s\n", tech, numsubst);
2491  ast_channel_unlock(chan);
2492  }
2493  /* Put them in the list of outgoing thingies... We're ready now.
2494  XXX If we're forcibly removed, these outgoing calls won't get
2495  hung up XXX */
2497  tmp->chan = tc;
2498  tmp->next = outgoing;
2499  outgoing = tmp;
2500  /* If this line is up, don't try anybody else */
2501  if (outgoing->chan->_state == AST_STATE_UP)
2502  break;
2503  }
2504 
2505  if (ast_strlen_zero(args.timeout)) {
2506  to = -1;
2507  } else {
2508  to = atoi(args.timeout);
2509  if (to > 0)
2510  to *= 1000;
2511  else {
2512  ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
2513  to = -1;
2514  }
2515  }
2516 
2517  if (!outgoing) {
2518  strcpy(pa.status, "CHANUNAVAIL");
2519  if (fulldial == num_dialed) {
2520  res = -1;
2521  goto out;
2522  }
2523  } else {
2524  /* Our status will at least be NOANSWER */
2525  strcpy(pa.status, "NOANSWER");
2526  if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
2527  moh = 1;
2528  if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
2529  char *original_moh = ast_strdupa(chan->musicclass);
2530  ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
2531  ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
2532  ast_string_field_set(chan, musicclass, original_moh);
2533  } else {
2534  ast_moh_start(chan, NULL, NULL);
2535  }
2537  } else if (ast_test_flag64(outgoing, OPT_RINGBACK)) {
2538  if (!ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
2539  if (dial_handle_playtones(chan, opt_args[OPT_ARG_RINGBACK])){
2541  sentringing++;
2542  } else {
2544  }
2545  } else {
2547  sentringing++;
2548  }
2549  }
2550  }
2551 
2552  peer = wait_for_answer(chan, outgoing, &to, peerflags, opt_args, &pa, &num, &result,
2553  dtmf_progress, ignore_cc, &forced_clid, &stored_clid);
2554 
2555  /* The ast_channel_datastore_remove() function could fail here if the
2556  * datastore was moved to another channel during a masquerade. If this is
2557  * the case, don't free the datastore here because later, when the channel
2558  * to which the datastore was moved hangs up, it will attempt to free this
2559  * datastore again, causing a crash
2560  */
2561  ast_channel_lock(chan);
2562  datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL); /* make sure we weren't cleaned up already */
2563  if (datastore && !ast_channel_datastore_remove(chan, datastore)) {
2564  ast_datastore_free(datastore);
2565  }
2566  ast_channel_unlock(chan);
2567  if (!peer) {
2568  if (result) {
2569  res = result;
2570  } else if (to) { /* Musta gotten hung up */
2571  res = -1;
2572  } else { /* Nobody answered, next please? */
2573  res = 0;
2574  }
2575  } else {
2576  const char *number;
2577 
2578  if (ast_test_flag64(&opts, OPT_CALLER_ANSWER))
2579  ast_answer(chan);
2580 
2581  strcpy(pa.status, "ANSWER");
2582  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2583  /* Ah ha! Someone answered within the desired timeframe. Of course after this
2584  we will always return with -1 so that it is hung up properly after the
2585  conversation. */
2586  hanguptree(outgoing, peer, 1);
2587  outgoing = NULL;
2588  /* If appropriate, log that we have a destination channel and set the answer time */
2589  if (chan->cdr) {
2590  ast_cdr_setdestchan(chan->cdr, peer->name);
2591  ast_cdr_setanswer(chan->cdr, peer->cdr->answer);
2592  }
2593  if (peer->name)
2594  pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
2595 
2596  ast_channel_lock(peer);
2597  number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
2598  if (!number)
2599  number = numsubst;
2600  pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
2601  ast_channel_unlock(peer);
2602 
2603  if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
2604  ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
2605  ast_channel_sendurl( peer, args.url );
2606  }
2608  if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
2609  res = 0;
2610  goto out;
2611  }
2612  }
2613  if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
2614  res = 0;
2615  } else {
2616  int digit = 0;
2617  struct ast_channel *chans[2];
2618  struct ast_channel *active_chan;
2619 
2620  chans[0] = chan;
2621  chans[1] = peer;
2622 
2623  /* we need to stream the announcment while monitoring the caller for a hangup */
2624 
2625  /* stream the file */
2626  res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
2627  if (res) {
2628  res = 0;
2629  ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]);
2630  }
2631 
2633  while (peer->stream) {
2634  int ms;
2635 
2636  ms = ast_sched_wait(peer->sched);
2637 
2638  if (ms < 0 && !peer->timingfunc) {
2639  ast_stopstream(peer);
2640  break;
2641  }
2642  if (ms < 0)
2643  ms = 1000;
2644 
2645  active_chan = ast_waitfor_n(chans, 2, &ms);
2646  if (active_chan) {
2647  struct ast_frame *fr = ast_read(active_chan);
2648  if (!fr) {
2649  ast_hangup(peer);
2650  res = -1;
2651  goto done;
2652  }
2653  switch(fr->frametype) {
2654  case AST_FRAME_DTMF_END:
2655  digit = fr->subclass.integer;
2656  if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
2657  ast_stopstream(peer);
2658  res = ast_senddigit(chan, digit, 0);
2659  }
2660  break;
2661  case AST_FRAME_CONTROL:
2662  switch (fr->subclass.integer) {
2663  case AST_CONTROL_HANGUP:
2664  ast_frfree(fr);
2665  ast_hangup(peer);
2666  res = -1;
2667  goto done;
2668  default:
2669  break;
2670  }
2671  break;
2672  default:
2673  /* Ignore all others */
2674  break;
2675  }
2676  ast_frfree(fr);
2677  }
2678  ast_sched_runq(peer->sched);
2679  }
2681  }
2682 
2683  if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
2684  /* chan and peer are going into the PBX, they both
2685  * should probably get CDR records. */
2688 
2689  replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
2690  ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
2691  /* peer goes to the same context and extension as chan, so just copy info from chan*/
2692  ast_copy_string(peer->context, chan->context, sizeof(peer->context));
2693  ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
2694  peer->priority = chan->priority + 2;
2695  if (ast_pbx_start(peer)) {
2696  ast_hangup(peer);
2697  }
2698  hanguptree(outgoing, NULL, ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0);
2699  if (continue_exec)
2700  *continue_exec = 1;
2701  res = 0;
2702  goto done;
2703  }
2704 
2706  struct ast_app *theapp;
2707  const char *macro_result;
2708 
2709  res = ast_autoservice_start(chan);
2710  if (res) {
2711  ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
2712  res = -1;
2713  }
2714 
2715  theapp = pbx_findapp("Macro");
2716 
2717  if (theapp && !res) { /* XXX why check res here ? */
2718  /* Set peer->exten and peer->context so that MACRO_EXTEN and MACRO_CONTEXT get set */
2719  ast_copy_string(peer->context, chan->context, sizeof(peer->context));
2720  ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
2721 
2722  replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
2723  res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
2724  ast_debug(1, "Macro exited with status %d\n", res);
2725  res = 0;
2726  } else {
2727  ast_log(LOG_ERROR, "Could not find application Macro\n");
2728  res = -1;
2729  }
2730 
2731  if (ast_autoservice_stop(chan) < 0) {
2732  res = -1;
2733  }
2734 
2735  ast_channel_lock(peer);
2736 
2737  if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
2738  char *macro_transfer_dest;
2739 
2740  if (!strcasecmp(macro_result, "BUSY")) {
2741  ast_copy_string(pa.status, macro_result, sizeof(pa.status));
2742  ast_set_flag64(peerflags, OPT_GO_ON);
2743  res = -1;
2744  } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
2745  ast_copy_string(pa.status, macro_result, sizeof(pa.status));
2746  ast_set_flag64(peerflags, OPT_GO_ON);
2747  res = -1;
2748  } else if (!strcasecmp(macro_result, "CONTINUE")) {
2749  /* hangup peer and keep chan alive assuming the macro has changed
2750  the context / exten / priority or perhaps
2751  the next priority in the current exten is desired.
2752  */
2753  ast_set_flag64(peerflags, OPT_GO_ON);
2754  res = -1;
2755  } else if (!strcasecmp(macro_result, "ABORT")) {
2756  /* Hangup both ends unless the caller has the g flag */
2757  res = -1;
2758  } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
2759  res = -1;
2760  /* perform a transfer to a new extension */
2761  if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
2762  replace_macro_delimiter(macro_transfer_dest);
2763  }
2764  if (!ast_parseable_goto(chan, macro_transfer_dest)) {
2765  ast_set_flag64(peerflags, OPT_GO_ON);
2766  }
2767  }
2768  }
2769 
2770  ast_channel_unlock(peer);
2771  }
2772 
2774  struct ast_app *theapp;
2775  const char *gosub_result;
2776  char *gosub_args, *gosub_argstart;
2777  int res9 = -1;
2778 
2779  res9 = ast_autoservice_start(chan);
2780  if (res9) {
2781  ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
2782  res9 = -1;
2783  }
2784 
2785  theapp = pbx_findapp("Gosub");
2786 
2787  if (theapp && !res9) {
2788  replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
2789 
2790  /* Set where we came from */
2791  ast_copy_string(peer->context, "app_dial_gosub_virtual_context", sizeof(peer->context));
2792  ast_copy_string(peer->exten, "s", sizeof(peer->exten));
2793  peer->priority = 0;
2794 
2795  gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
2796  if (gosub_argstart) {
2797  const char *what_is_s = "s";
2798  *gosub_argstart = 0;
2799  if (!ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "s", 1, S_COR(peer->caller.id.number.valid, peer->caller.id.number.str, NULL)) &&
2800  ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "~~s~~", 1, S_COR(peer->caller.id.number.valid, peer->caller.id.number.str, NULL))) {
2801  what_is_s = "~~s~~";
2802  }
2803  if (ast_asprintf(&gosub_args, "%s,%s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s, gosub_argstart + 1) < 0) {
2804  gosub_args = NULL;
2805  }
2806  *gosub_argstart = ',';
2807  } else {
2808  const char *what_is_s = "s";
2809  if (!ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "s", 1, S_COR(peer->caller.id.number.valid, peer->caller.id.number.str, NULL)) &&
2810  ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "~~s~~", 1, S_COR(peer->caller.id.number.valid, peer->caller.id.number.str, NULL))) {
2811  what_is_s = "~~s~~";
2812  }
2813  if (ast_asprintf(&gosub_args, "%s,%s,1", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s) < 0) {
2814  gosub_args = NULL;
2815  }
2816  }
2817 
2818  if (gosub_args) {
2819  res9 = pbx_exec(peer, theapp, gosub_args);
2820  if (!res9) {
2821  struct ast_pbx_args args;
2822  /* A struct initializer fails to compile for this case ... */
2823  memset(&args, 0, sizeof(args));
2824  args.no_hangup_chan = 1;
2825  ast_pbx_run_args(peer, &args);
2826  }
2827  ast_free(gosub_args);
2828  ast_debug(1, "Gosub exited with status %d\n", res9);
2829  } else {
2830  ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
2831  }
2832 
2833  } else if (!res9) {
2834  ast_log(LOG_ERROR, "Could not find application Gosub\n");
2835  res9 = -1;
2836  }
2837 
2838  if (ast_autoservice_stop(chan) < 0) {
2839  res9 = -1;
2840  }
2841 
2842  ast_channel_lock(peer);
2843 
2844  if (!res9 && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
2845  char *gosub_transfer_dest;
2846  const char *gosub_retval = pbx_builtin_getvar_helper(peer, "GOSUB_RETVAL");
2847 
2848  /* Inherit return value from the peer, so it can be used in the master */
2849  if (gosub_retval) {
2850  pbx_builtin_setvar_helper(chan, "GOSUB_RETVAL", gosub_retval);
2851  }
2852 
2853  if (!strcasecmp(gosub_result, "BUSY")) {
2854  ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
2855  ast_set_flag64(peerflags, OPT_GO_ON);
2856  res = -1;
2857  } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
2858  ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
2859  ast_set_flag64(peerflags, OPT_GO_ON);
2860  res = -1;
2861  } else if (!strcasecmp(gosub_result, "CONTINUE")) {
2862  /* hangup peer and keep chan alive assuming the macro has changed
2863  the context / exten / priority or perhaps
2864  the next priority in the current exten is desired.
2865  */
2866  ast_set_flag64(peerflags, OPT_GO_ON);
2867  res = -1;
2868  } else if (!strcasecmp(gosub_result, "ABORT")) {
2869  /* Hangup both ends unless the caller has the g flag */
2870  res = -1;
2871  } else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
2872  res = -1;
2873  /* perform a transfer to a new extension */
2874  if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
2875  replace_macro_delimiter(gosub_transfer_dest);
2876  }
2877  if (!ast_parseable_goto(chan, gosub_transfer_dest)) {
2878  ast_set_flag64(peerflags, OPT_GO_ON);
2879  }
2880  }
2881  }
2882 
2883  ast_channel_unlock(peer);
2884  }
2885 
2886  if (!res) {
2887  if (!ast_tvzero(calldurationlimit)) {
2888  struct timeval whentohangup = calldurationlimit;
2889  peer->whentohangup = ast_tvadd(ast_tvnow(), whentohangup);
2890  }
2891  if (!ast_strlen_zero(dtmfcalled)) {
2892  ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
2893  res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
2894  }
2895  if (!ast_strlen_zero(dtmfcalling)) {
2896  ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
2897  res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
2898  }
2899  }
2900 
2901  if (res) { /* some error */
2902  res = -1;
2903  } else {
2904  if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
2906  if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
2908  if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
2910  if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
2912  if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
2914  if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
2916  if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
2918  if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
2920  if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
2922  if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
2924  if (ast_test_flag64(peerflags, OPT_GO_ON))
2926 
2928  config.end_bridge_callback_data = chan;
2930 
2931  if (moh) {
2932  moh = 0;
2933  ast_moh_stop(chan);
2934  } else if (sentringing) {
2935  sentringing = 0;
2936  ast_indicate(chan, -1);
2937  }
2938  /* Be sure no generators are left on it and reset the visible indication */
2940  chan->visible_indication = 0;
2941  /* Make sure channels are compatible */
2942  res = ast_channel_make_compatible(chan, peer);
2943  if (res < 0) {
2944  ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
2945  ast_hangup(peer);
2946  res = -1;
2947  goto done;
2948  }
2949  if (opermode) {
2950  struct oprmode oprmode;
2951 
2952  oprmode.peer = peer;
2953  oprmode.mode = opermode;
2954 
2956  }
2957  res = ast_bridge_call(chan, peer, &config);
2958  }
2959 
2960  strcpy(peer->context, chan->context);
2961 
2962  if (ast_test_flag64(&opts, OPT_PEER_H)
2963  && ast_exists_extension(peer, peer->context, "h", 1,
2964  S_COR(peer->caller.id.number.valid, peer->caller.id.number.str, NULL))) {
2965  int autoloopflag;
2966  int found;
2967  int res9;
2968 
2969  strcpy(peer->exten, "h");
2970  peer->priority = 1;
2971  autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
2973 
2974  while ((res9 = ast_spawn_extension(peer, peer->context, peer->exten,
2975  peer->priority,
2976  S_COR(peer->caller.id.number.valid, peer->caller.id.number.str, NULL),
2977  &found, 1)) == 0) {
2978  peer->priority++;
2979  }
2980 
2981  if (found && res9) {
2982  /* Something bad happened, or a hangup has been requested. */
2983  ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
2984  ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
2985  }
2986  ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP); /* set it back the way it was */
2987  }
2988  if (!ast_check_hangup(peer)) {
2989  if (ast_test_flag64(&opts, OPT_CALLEE_GO_ON)) {
2990  int goto_res;
2991 
2992  if (!ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {
2993  replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
2994  goto_res = ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
2995  } else { /* F() */
2996  goto_res = ast_goto_if_exists(peer, chan->context,
2997  chan->exten, chan->priority + 1);
2998  }
2999  if (!goto_res && !ast_pbx_start(peer)) {
3000  /* The peer is now running its own PBX. */
3001  goto out;
3002  }
3003  }
3004  } else if (!ast_check_hangup(chan)) {
3005  chan->hangupcause = peer->hangupcause;
3006  }
3007  ast_hangup(peer);
3008  }
3009 out:
3010  if (moh) {
3011  moh = 0;
3012  ast_moh_stop(chan);
3013  } else if (sentringing) {
3014  sentringing = 0;
3015  ast_indicate(chan, -1);
3016  }
3017 
3018  if (delprivintro && ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3019  ast_filedelete(pa.privintro, NULL);
3020  if (ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3021  ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
3022  } else {
3023  ast_verb(3, "Successfully deleted %s intro file\n", pa.privintro);
3024  }
3025  }
3026 
3027  ast_channel_early_bridge(chan, NULL);
3028  /* When dialing local channels, the hangupcause of the parent channel
3029  * tells us whether the call was answered elsewhere. */
3030  hanguptree(outgoing, NULL, chan->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE ? 1 : 0);
3031  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
3032  senddialendevent(chan, pa.status);
3033  ast_debug(1, "Exiting with DIALSTATUS=%s (HANGUPCAUSE=%d).\n", pa.status, chan->hangupcause);
3034 
3035  if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
3036  if (!ast_tvzero(calldurationlimit))
3037  memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
3038  res = 0;
3039  }
3040 
3041 done:
3042  if (config.warning_sound) {
3043  ast_free((char *)config.warning_sound);
3044  }
3045  if (config.end_sound) {
3046  ast_free((char *)config.end_sound);
3047  }
3048  if (config.start_sound) {
3049  ast_free((char *)config.start_sound);
3050  }
3051  ast_ignore_cc(chan);
3052  return res;
3053 }
static char musicclass[MAX_MUSICCLASS]
Definition: chan_mgcp.c:155
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:3534
union ast_frame_subclass subclass
Definition: frame.h:146
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
#define OPT_FORCE_CID_PRES
Definition: app_dial.c:588
int sentringing
Definition: app_dial.c:1026
int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
Bridge two channels together (early)
Definition: channel.c:7406
Information needed to identify an endpoint in a call.
Definition: channel.h:288
Options for ast_pbx_run()
Definition: pbx.h:336
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:383
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
#define OPT_CALLEE_GO_ON
Definition: app_dial.c:585
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char privintro[1024]
Definition: app_dial.c:1029
void(* end_bridge_callback_data_fixup)(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
Definition: channel.h:993
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Definition: linkedlists.h:172
static const char config[]
Definition: cdr_csv.c:57
Definition: frame.h:527
#define ast_copy_flags64(dest, src, flagz)
Definition: utils.h:141
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
Definition: channel.c:7091
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:179
char * strsep(char **str, const char *delims)
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: pbx.c:1537
int priority
Definition: channel.h:841
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx.c:1497
#define OPT_CANCEL_ELSEWHERE
Definition: app_dial.c:583
struct ast_flags features_callee
Definition: channel.h:976
int visible_indication
Definition: channel.h:861
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: app.c:1222
void ast_cdr_reset(struct ast_cdr *cdr, struct ast_flags *flags)
Reset the detail record, optionally posting it first.
Definition: cdr.c:1149
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
#define AST_DIGIT_ANY
Definition: file.h:47
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
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:2329
#define ast_test_flag(p, flag)
Definition: utils.h:63
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: app.c:2106
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
static struct ast_channel * wait_for_answer(struct ast_channel *in, struct chanlist *outgoing, int *to, struct ast_flags64 *peerflags, char *opt_args[], struct privacy_args *pa, const struct cause_args *num_in, int *result, char *dtmf_progress, const int ignore_cc, struct ast_party_id *forced_clid, struct ast_party_id *stored_clid)
Definition: app_dial.c:1033
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
int ast_channel_supports_html(struct ast_channel *channel)
Checks for HTML support on a channel.
Definition: channel.c:5902
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:144
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:5879
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static void end_bridge_callback(void *data)
Definition: app_dial.c:1928
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
#define AST_OPTION_OPRMODE
Definition: frame.h:469
static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
Definition: app_dial.c:684
char * str
Subscriber name (Malloced)
Definition: channel.h:214
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:3960
#define DIAL_STILLGOING
Definition: app_dial.c:580
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_set_flag64(p, flag)
Definition: utils.h:127
static void senddialendevent(struct ast_channel *src, const char *dialstatus)
Definition: app_dial.c:810
static void replace_macro_delimiter(char *s)
Definition: app_dial.c:1672
struct ast_cdr * cdr
Definition: channel.h:766
unsigned short transfercapability
Definition: channel.h:863
format_t nativeformats
Definition: channel.h:852
Structure for a data store object.
Definition: datastore.h:54
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2604
char * str
Malloced subaddress string.
Definition: channel.h:263
const char * data
Definition: channel.h:755
int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
Send a DTMF digit to a channel.
Definition: channel.c:4774
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
#define OPT_CANCEL_TIMEOUT
Definition: app_dial.c:586
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:7795
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:206
enum ast_channel_adsicpe adsicpe
Definition: channel.h:844
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:8051
#define ast_verb(level,...)
Definition: logger.h:243
const char * appl
Definition: channel.h:754
static void handle_cause(int cause, struct cause_args *num)
Definition: app_dial.c:717
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
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:3936
#define CAN_EARLY_BRIDGE(flags, chan, peer)
Definition: app_dial.c:654
const char * start_sound
Definition: channel.h:986
#define DIAL_CALLERID_ABSENT
Definition: app_dial.c:582
struct chanlist * next
Definition: app_dial.c:665
Number structure.
Definition: app_followme.c:109
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2573
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 &lt;0 if the caller should &#39;goto out&#39;
Definition: app_dial.c:1826
#define ast_asprintf(a, b, c...)
Definition: astmm.h:121
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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:1735
static const char * get_cid_name(char *name, int namelen, struct ast_channel *chan)
Definition: app_dial.c:774
static char dialcontext[AST_MAX_CONTEXT]
struct ast_channel * chan
Definition: app_dial.c:666
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_datastore_info dialed_interface_info
#define OPT_FORCE_CID_TAG
Definition: app_dial.c:587
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:113
enum ast_pbx_result ast_pbx_run_args(struct ast_channel *c, struct ast_pbx_args *args)
Execute the PBX in the current thread.
Definition: pbx.c:5906
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:11326
#define AST_MAX_EXTENSION
Definition: channel.h:135
bridge configuration
Definition: channel.h:974
void * end_bridge_callback_data
Definition: channel.h:989
Caller Party information.
Definition: channel.h:368
const char * end_sound
Definition: channel.h:985
static int dial_handle_playtones(struct ast_channel *chan, const char *data)
Definition: app_dial.c:1957
#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:83
void ast_cdr_setanswer(struct ast_cdr *cdr, struct timeval t)
Set the answer time for a call.
Definition: cdr.c:834
List of channel drivers.
Definition: app_dial.c:664
struct sched_context * sched
Definition: channel.h:756
#define DIAL_NOFORWARDHTML
Definition: app_dial.c:581
int(* timingfunc)(const void *data)
Definition: channel.h:759
#define OPT_PEER_H
Definition: app_dial.c:584
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:5400
int ast_parse_caller_presentation(const char *data)
Convert caller ID text code to value (used in config file parsing)
Definition: callerid.c:1144
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:238
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
struct ast_party_connected_line connected
Definition: app_dial.c:669
struct ast_flags features_caller
Definition: channel.h:975
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:3981
uint64_t flags
Definition: utils.h:207
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
Start the CC process on a call.
Definition: ccss.c:2146
static char moh[80]
Definition: chan_agent.c:209
#define AST_PBX_INCOMPLETE
Definition: pbx.h:50
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct timeval answer
Definition: cdr.h:102
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:294
#define OPT_CALLER_ANSWER
Definition: app_dial.c:589
#define LOG_ERROR
Definition: logger.h:155
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
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:2288
static struct @350 args
int privdb_val
Definition: app_dial.c:1027
enum ast_channel_state _state
Definition: channel.h:839
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
Connected Line/Party information.
Definition: channel.h:401
const ast_string_field name
Definition: channel.h:787
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:2110
struct ast_channel * chan
Definition: app_dial.c:711
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:8040
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static float di[4]
Definition: tdd.c:59
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
#define LOG_NOTICE
Definition: logger.h:133
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:11261
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_dialed_interface::@174 list
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:5914
#define ast_channel_unlock(chan)
Definition: channel.h:2467
const char * ast_cause2str(int state) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:980
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
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:6241
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:611
#define ast_free(a)
Definition: astmm.h:97
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
#define AST_CHANNEL_NAME
Definition: channel.h:137
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
Definition: lock.h:480
int ast_call(struct ast_channel *chan, char *addr, int timeout)
Make a call.
Definition: channel.c:5761
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:156
unsigned int inheritance
Definition: datastore.h:58
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
Definition: channel.c:2087
#define ast_set2_flag64(p, value, flag)
Definition: utils.h:151
#define AST_PRIVACY_UNKNOWN
Definition: privacy.h:34
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct ast_channel * peer
Definition: frame.h:528
int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid, int *found, int combined_find_spawn)
Launch a new extension (i.e. new stack)
Definition: pbx.c:5425
int ast_sched_runq(struct sched_context *con)
Runs the queue.
Definition: sched.c:600
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...
Definition: pbx.c:10546
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:3969
char macroexten[AST_MAX_EXTENSION]
Definition: channel.h:871
#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:332
void ast_ignore_cc(struct ast_channel *chan)
Mark the channel to ignore further CC activity.
Definition: ccss.c:3454
char * tag
User-set &quot;tag&quot;.
Definition: channel.h:304
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:3107
void * data
Definition: datastore.h:56
int transit_network_select
Transit Network Select.
Definition: channel.h:347
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:2316
int ast_channel_make_compatible(struct ast_channel *c0, struct ast_channel *c1)
Makes two channel formats compatible.
Definition: channel.c:5970
#define ast_calloc(a, b)
Definition: astmm.h:82
static void chanlist_free(struct chanlist *outgoing)
Definition: app_dial.c:677
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
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:8443
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
ast_app: A registered application
Definition: pbx.c:971
static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
Definition: app_dial.c:787
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
int ast_sched_wait(struct sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place Determine the number of s...
Definition: sched.c:334
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
#define AST_CAUSE_BUSY
Definition: causes.h:148
const ast_string_field musicclass
Definition: channel.h:787
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:9776
const ast_string_field accountcode
Definition: channel.h:787
Data structure associated with a single frame of data.
Definition: frame.h:142
int hangupcause
Definition: channel.h:849
static int connected
Definition: cdr_pgsql.c:57
struct timeval whentohangup
Definition: channel.h:789
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
enum ast_frame_type frametype
Definition: frame.h:144
const char * warning_sound
Definition: channel.h:984
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
Definition: app_dial.c:1953
char status[256]
Definition: app_dial.c:1030
#define ast_channel_trylock(chan)
Definition: channel.h:2468
#define ast_frfree(fr)
Definition: frame.h:583
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send DTMF to a channel.
Definition: app.c:501
void(* end_bridge_callback)(void *)
Definition: channel.h:988
int mode
Definition: frame.h:529
struct ast_filestream * stream
Definition: channel.h:757
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:1423
struct ast_channel * ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *status)
Requests a channel.
Definition: channel.c:5695
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2590
void ast_cdr_setdestchan(struct ast_cdr *cdr, const char *chan)
Set the destination channel, if there was one.
Definition: cdr.c:812
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2599
static struct ast_app_option dial_exec_options[128]
Definition: app_dial.c:652
const ast_string_field language
Definition: channel.h:787
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:8458
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
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:2367
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1009
int ast_bridge_timelimit(struct ast_channel *chan, struct ast_bridge_config *config, char *parse, struct timeval *calldurationlimit)
parse L option and read associated channel variables to set warning, warning frequency, and timelimit
Definition: features.c:7532
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static int dial_handle_playtones ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 1957 of file app_dial.c.

References 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, str, and ast_channel::zone.

Referenced by dial_exec_full().

1958 {
1959  struct ast_tone_zone_sound *ts = NULL;
1960  int res;
1961  const char *str = data;
1962 
1963  if (ast_strlen_zero(str)) {
1964  ast_debug(1,"Nothing to play\n");
1965  return -1;
1966  }
1967 
1968  ts = ast_get_indication_tone(chan->zone, str);
1969 
1970  if (ts && ts->data[0]) {
1971  res = ast_playtones_start(chan, 0, ts->data, 0);
1972  } else {
1973  res = -1;
1974  }
1975 
1976  if (ts) {
1977  ts = ast_tone_zone_sound_unref(ts);
1978  }
1979 
1980  if (res) {
1981  ast_log(LOG_WARNING, "Unable to start playtone \'%s\'\n", str);
1982  }
1983 
1984  return res;
1985 }
struct ast_tone_zone * zone
Definition: channel.h:767
#define LOG_WARNING
Definition: logger.h:144
const char * str
Definition: app_jack.c:144
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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:226
Description of a tone.
Definition: indications.h:36
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:473
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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:319
const char * data
Description of a tone.
Definition: indications.h:53
static void do_forward ( struct chanlist o,
struct cause_args num,
struct ast_flags64 peerflags,
int  single,
int  caller_entertained,
int *  to,
struct ast_party_id forced_clid,
struct ast_party_id stored_clid 
)
static

helper function for wait_for_answer()

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

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

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

Definition at line 837 of file app_dial.c.

References accountcode, ast_channel::accountcode, ast_channel::appl, ast_call(), AST_CAUSE_BUSY, AST_CEL_FORWARD, ast_cel_report_event(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_make_compatible(), ast_channel_redirecting_macro(), 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_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(), ast_rtp_instance_early_bridge_make_compatible(), ast_set_flag64, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_verb, ast_channel::call_forward, ast_channel::caller, CAN_EARLY_BRIDGE, chanlist::chan, cause_args::chan, ast_channel::connected, ast_channel::context, ast_channel::data, DIAL_CALLERID_ABSENT, DIAL_STILLGOING, ast_channel::dialed, ast_channel::exten, ast_party_redirecting::from, handle_cause(), ast_party_caller::id, ast_party_connected_line::id, LOG_NOTICE, ast_channel::macroexten, ast_channel::name, ast_channel::nativeformats, cause_args::nochan, ast_party_id::number, OPT_CANCEL_TIMEOUT, OPT_FORCECLID, OPT_IGNORE_CONNECTEDLINE, OPT_IGNORE_FORWARDING, OPT_ORIGINAL_CLID, pbx_builtin_getvar_helper(), ast_channel::redirecting, S_COR, S_OR, senddialevent(), ast_party_number::str, ast_channel::tech, ast_party_dialed::transit_network_select, and ast_party_number::valid.

Referenced by wait_for_answer().

840 {
841  char tmpchan[256];
842  struct ast_channel *original = o->chan;
843  struct ast_channel *c = o->chan; /* the winner */
844  struct ast_channel *in = num->chan; /* the input channel */
845  char *stuff;
846  char *tech;
847  int cause;
848  struct ast_party_caller caller;
849 
850  ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
851  if ((stuff = strchr(tmpchan, '/'))) {
852  *stuff++ = '\0';
853  tech = tmpchan;
854  } else {
855  const char *forward_context;
856  ast_channel_lock(c);
857  forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
858  if (ast_strlen_zero(forward_context)) {
859  forward_context = NULL;
860  }
861  snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
863  stuff = tmpchan;
864  tech = "Local";
865  }
866  if (!strcasecmp(tech, "Local")) {
867  /*
868  * Drop the connected line update block for local channels since
869  * this is going to run dialplan and the user can change his
870  * mind about what connected line information he wants to send.
871  */
873  }
874 
876 
877  /* Before processing channel, go ahead and check for forwarding */
878  ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
879  /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
880  if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
881  ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
882  c = o->chan = NULL;
883  cause = AST_CAUSE_BUSY;
884  } else {
885  /* Setup parameters */
886  c = o->chan = ast_request(tech, in->nativeformats, in, stuff, &cause);
887  if (c) {
888  if (single && !caller_entertained) {
890  }
891  ast_channel_lock_both(in, o->chan);
894  ast_channel_unlock(in);
896  /* When a call is forwarded, we don't want to track new interfaces
897  * dialed for CC purposes. Setting the done flag will ensure that
898  * any Dial operations that happen later won't record CC interfaces.
899  */
900  ast_ignore_cc(o->chan);
901  ast_log(LOG_NOTICE, "Not accepting call completion offers from call-forward recipient %s\n", o->chan->name);
902  } else
904  "Forwarding failed to create channel to dial '%s/%s' (cause = %d)\n",
905  tech, stuff, cause);
906  }
907  if (!c) {
909  handle_cause(cause, num);
910  ast_hangup(original);
911  } else {
912  ast_channel_lock_both(c, original);
915  ast_channel_unlock(original);
916 
917  ast_channel_lock_both(c, in);
918 
919  if (single && !caller_entertained && CAN_EARLY_BRIDGE(peerflags, c, in)) {
921  }
922 
923  if (!c->redirecting.from.number.valid
925  /*
926  * The call was not previously redirected so it is
927  * now redirected from this number.
928  */
931  c->redirecting.from.number.valid = 1;
933  ast_strdup(S_OR(in->macroexten, in->exten));
934  }
935 
937 
938  /* Determine CallerID to store in outgoing channel. */
939  ast_party_caller_set_init(&caller, &c->caller);
940  if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
941  caller.id = *stored_clid;
942  ast_channel_set_caller_event(c, &caller, NULL);
944  } else if (ast_strlen_zero(S_COR(c->caller.id.number.valid,
945  c->caller.id.number.str, NULL))) {
946  /*
947  * The new channel has no preset CallerID number by the channel
948  * driver. Use the dialplan extension and hint name.
949  */
950  caller.id = *stored_clid;
951  ast_channel_set_caller_event(c, &caller, NULL);
953  } else {
955  }
956 
957  /* Determine CallerID for outgoing channel to send. */
958  if (ast_test_flag64(o, OPT_FORCECLID)) {
960 
962  connected.id = *forced_clid;
964  } else {
966  }
967 
969 
970  c->appl = "AppDial";
971  c->data = "(Outgoing Line)";
972 
973  ast_channel_unlock(in);
974  if (single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
975  struct ast_party_redirecting redirecting;
976 
977  /*
978  * Redirecting updates to the caller make sense only on single
979  * calls.
980  *
981  * We must unlock c before calling
982  * ast_channel_redirecting_macro, because we put c into
983  * autoservice there. That is pretty much a guaranteed
984  * deadlock. This is why the handling of c's lock may seem a
985  * bit unusual here.
986  */
987  ast_party_redirecting_init(&redirecting);
988  ast_party_redirecting_copy(&redirecting, &c->redirecting);
990  if (ast_channel_redirecting_macro(c, in, &redirecting, 1, 0)) {
991  ast_channel_update_redirecting(in, &redirecting, NULL);
992  }
993  ast_party_redirecting_free(&redirecting);
994  } else {
996  }
997 
998  if (ast_test_flag64(peerflags, OPT_CANCEL_TIMEOUT)) {
999  *to = -1;
1000  }
1001 
1002  if (ast_call(c, stuff, 0)) {
1003  ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n",
1004  tech, stuff);
1006  ast_hangup(original);
1007  ast_hangup(c);
1008  c = o->chan = NULL;
1009  num->nochan++;
1010  } else {
1011  ast_channel_lock_both(c, in);
1012  senddialevent(in, c, stuff);
1013  ast_channel_unlock(in);
1014  ast_channel_unlock(c);
1015  /* Hangup the original channel now, in case we needed it */
1016  ast_hangup(original);
1017  }
1018  if (single && !caller_entertained) {
1019  ast_indicate(in, -1);
1020  }
1021  }
1022 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2308
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:383
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
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:7091
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
#define ast_strdup(a)
Definition: astmm.h:109
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:449
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:9592
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event_type, const char *userdefevname, const char *extra, struct ast_channel *peer2)
Report a channel event.
Definition: cel.c:645
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
#define DIAL_STILLGOING
Definition: app_dial.c:580
#define ast_set_flag64(p, flag)
Definition: utils.h:127
format_t nativeformats
Definition: channel.h:852
const char * data
Definition: channel.h:755
#define OPT_CANCEL_TIMEOUT
Definition: app_dial.c:586
#define ast_verb(level,...)
Definition: logger.h:243
const char * appl
Definition: channel.h:754
static void handle_cause(int cause, struct cause_args *num)
Definition: app_dial.c:717
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
#define CAN_EARLY_BRIDGE(flags, chan, peer)
Definition: app_dial.c:654
#define DIAL_CALLERID_ABSENT
Definition: app_dial.c:582
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2573
struct ast_channel * chan
Definition: app_dial.c:666
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
Definition: channel.c:1981
Caller Party information.
Definition: channel.h:368
#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:83
int nochan
Definition: app_dial.c:714
void ast_party_number_free(struct ast_party_number *doomed)
Destroy the party number contents.
Definition: channel.c:2028
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
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:2288
const ast_string_field call_forward
Definition: channel.h:787
Connected Line/Party information.
Definition: channel.h:401
const ast_string_field name
Definition: channel.h:787
struct ast_channel * chan
Definition: app_dial.c:711
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:447
#define LOG_NOTICE
Definition: logger.h:133
#define ast_channel_unlock(chan)
Definition: channel.h:2467
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:6241
int ast_call(struct ast_channel *chan, char *addr, int timeout)
Make a call.
Definition: channel.c:5761
#define ast_clear_flag64(p, flag)
Definition: utils.h:134
char macroexten[AST_MAX_EXTENSION]
Definition: channel.h:871
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2473
void ast_ignore_cc(struct ast_channel *chan)
Mark the channel to ignore further CC activity.
Definition: ccss.c:3454
int transit_network_select
Transit Network Select.
Definition: channel.h:347
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2396
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:2316
int ast_channel_make_compatible(struct ast_channel *c0, struct ast_channel *c1)
Makes two channel formats compatible.
Definition: channel.c:5970
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:452
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
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:8443
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
Definition: channel.c:2359
static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
Definition: app_dial.c:787
#define AST_CAUSE_BUSY
Definition: causes.h:148
const ast_string_field accountcode
Definition: channel.h:787
static int connected
Definition: cdr_pgsql.c:57
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:1423
struct ast_channel * ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *status)
Requests a channel.
Definition: channel.c:5695
struct ast_channel_tech * tech
Definition: channel.h:743
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
this call was forwarded somewhere else
Definition: cel.h:98
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
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:2367
int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
Run a redirecting interception macro and update a channel&#39;s redirecting information.
Definition: channel.c:9663
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static void end_bridge_callback ( void *  data)
static

Definition at line 1928 of file app_dial.c.

References ast_cdr::answer, ast_channel_lock, ast_channel_unlock, ast_channel::cdr, ast_channel::data, pbx_builtin_setvar_helper(), and ast_cdr::start.

Referenced by dial_exec_full().

1929 {
1930  char buf[80];
1931  time_t end;
1932  struct ast_channel *chan = data;
1933 
1934  if (!chan->cdr) {
1935  return;
1936  }
1937 
1938  time(&end);
1939 
1940  ast_channel_lock(chan);
1941  if (chan->cdr->answer.tv_sec) {
1942  snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->answer.tv_sec);
1943  pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
1944  }
1945 
1946  if (chan->cdr->start.tv_sec) {
1947  snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->start.tv_sec);
1948  pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
1949  }
1950  ast_channel_unlock(chan);
1951 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_cdr * cdr
Definition: channel.h:766
const char * data
Definition: channel.h:755
struct timeval answer
Definition: cdr.h:102
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct timeval start
Definition: cdr.h:100
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...
Definition: pbx.c:10546
static void end_bridge_callback_data_fixup ( struct ast_bridge_config bconfig,
struct ast_channel originator,
struct ast_channel terminator 
)
static

Definition at line 1953 of file app_dial.c.

References ast_bridge_config::end_bridge_callback_data.

Referenced by dial_exec_full().

1953  {
1954  bconfig->end_bridge_callback_data = originator;
1955 }
void * end_bridge_callback_data
Definition: channel.h:989
static const char* get_cid_name ( char *  name,
int  namelen,
struct ast_channel chan 
)
static

Definition at line 774 of file app_dial.c.

References ast_channel_lock, ast_channel_unlock, ast_get_hint(), ast_strdupa, context, ast_channel::context, exten, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, and S_OR.

Referenced by dial_exec_full().

775 {
776  const char *context;
777  const char *exten;
778 
779  ast_channel_lock(chan);
780  context = ast_strdupa(S_OR(chan->macrocontext, chan->context));
781  exten = ast_strdupa(S_OR(chan->macroexten, chan->exten));
782  ast_channel_unlock(chan);
783 
784  return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
785 }
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:5362
#define ast_channel_lock(chan)
Definition: channel.h:2466
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static const char name[]
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
char macroexten[AST_MAX_EXTENSION]
Definition: channel.h:871
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static void handle_cause ( int  cause,
struct cause_args num 
)
static

Definition at line 717 of file app_dial.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_UNREGISTERED, ast_cdr_busy(), ast_cdr_failed(), ast_cdr_noanswer(), cause_args::busy, ast_channel::cdr, cause_args::chan, cause_args::congestion, and cause_args::nochan.

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

718 {
719  struct ast_cdr *cdr = num->chan->cdr;
720 
721  switch(cause) {
722  case AST_CAUSE_BUSY:
723  if (cdr)
724  ast_cdr_busy(cdr);
725  num->busy++;
726  break;
727 
729  if (cdr)
730  ast_cdr_failed(cdr);
731  num->congestion++;
732  break;
733 
736  if (cdr)
737  ast_cdr_failed(cdr);
738  num->nochan++;
739  break;
740 
741  case AST_CAUSE_NO_ANSWER:
742  if (cdr) {
743  ast_cdr_noanswer(cdr);
744  }
745  break;
747  break;
748 
749  default:
750  num->nochan++;
751  break;
752  }
753 }
void ast_cdr_failed(struct ast_cdr *cdr)
Fail a call.
Definition: cdr.c:764
int congestion
Definition: app_dial.c:713
struct ast_cdr * cdr
Definition: channel.h:766
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
int nochan
Definition: app_dial.c:714
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
Responsible for call detail data.
Definition: cdr.h:82
struct ast_channel * chan
Definition: app_dial.c:711
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:153
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
int busy
Definition: app_dial.c:712
void ast_cdr_noanswer(struct ast_cdr *cdr)
A call wasn&#39;t answered.
Definition: cdr.c:776
#define AST_CAUSE_BUSY
Definition: causes.h:148
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
void ast_cdr_busy(struct ast_cdr *cdr)
Busy a call.
Definition: cdr.c:753
static void hanguptree ( struct chanlist outgoing,
struct ast_channel exception,
int  answered_elsewhere 
)
static

Definition at line 684 of file app_dial.c.

References AST_CAUSE_ANSWERED_ELSEWHERE, AST_FLAG_ANSWERED_ELSEWHERE, ast_hangup(), ast_set_flag, chanlist::chan, chanlist_free(), ast_channel::hangupcause, and chanlist::next.

Referenced by dial_exec_full().

685 {
686  /* Hang up a tree of stuff */
687  struct chanlist *oo;
688  while (outgoing) {
689  /* Hangup any existing lines we have open */
690  if (outgoing->chan && (outgoing->chan != exception)) {
691  if (answered_elsewhere) {
692  /* The flag is used for local channel inheritance and stuff */
694  /* This is for the channel drivers */
696  }
697  ast_hangup(outgoing->chan);
698  }
699  oo = outgoing;
700  outgoing = outgoing->next;
701  chanlist_free(oo);
702  }
703 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct chanlist * next
Definition: app_dial.c:665
struct ast_channel * chan
Definition: app_dial.c:666
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:113
List of channel drivers.
Definition: app_dial.c:664
static void chanlist_free(struct chanlist *outgoing)
Definition: app_dial.c:677
int hangupcause
Definition: channel.h:849
static int load_module ( void  )
static

Definition at line 3188 of file app_dial.c.

References ast_add_extension2(), ast_context_find_or_create(), ast_free_ptr(), ast_log(), ast_register_application_xml, ast_strdup, dial_exec(), LOG_ERROR, and retrydial_exec().

3189 {
3190  int res;
3191  struct ast_context *con;
3192 
3193  con = ast_context_find_or_create(NULL, NULL, "app_dial_gosub_virtual_context", "app_dial");
3194  if (!con)
3195  ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
3196  else
3197  ast_add_extension2(con, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "app_dial");
3198 
3201 
3202  return res;
3203 }
#define ast_strdup(a)
Definition: astmm.h:109
int ast_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add an extension to an extension context, this time with an ast_context *.
Definition: pbx.c:9052
static int retrydial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3064
void ast_free_ptr(void *ptr)
static int dial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3055
static const char app[]
Definition: app_dial.c:542
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char rapp[]
Definition: app_dial.c:543
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:7726
ast_context: An extension context
Definition: pbx.c:955
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
static int onedigit_goto ( struct ast_channel chan,
const char *  context,
char  exten,
int  pri 
)
static

Definition at line 755 of file app_dial.c.

References ast_goto_if_exists(), ast_strlen_zero(), ast_channel::context, exten, and ast_channel::macrocontext.

Referenced by retrydial_exec(), and wait_for_answer().

756 {
757  char rexten[2] = { exten, '\0' };
758 
759  if (context) {
760  if (!ast_goto_if_exists(chan, context, rexten, pri))
761  return 1;
762  } else {
763  if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
764  return 1;
765  else if (!ast_strlen_zero(chan->macrocontext)) {
766  if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
767  return 1;
768  }
769  }
770  return 0;
771 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:11261
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static void replace_macro_delimiter ( char *  s)
static

Definition at line 1672 of file app_dial.c.

Referenced by dial_exec_full().

1673 {
1674  for (; *s; s++)
1675  if (*s == '^')
1676  *s = ',';
1677 }
static int retrydial_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 3064 of file app_dial.c.

References args, AST_APP_ARG, ast_channel_lock, ast_channel_unlock, AST_DECLARE_APP_ARGS, AST_DIGIT_ANY, ast_fileexists(), AST_FLAG_MOH, ast_log(), ast_moh_start(), ast_moh_stop(), AST_PBX_INCOMPLETE, AST_STANDARD_APP_ARGS, ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_waitfordigit(), ast_waitstream(), context, ast_channel::data, dial_exec_full(), ast_channel::language, LOG_ERROR, LOG_WARNING, onedigit_goto(), OPT_DTMF_EXIT, parse(), and pbx_builtin_getvar_helper().

Referenced by load_module().

3065 {
3066  char *parse;
3067  const char *context = NULL;
3068  int sleepms = 0, loops = 0, res = -1;
3069  struct ast_flags64 peerflags = { 0, };
3071  AST_APP_ARG(announce);
3072  AST_APP_ARG(sleep);
3073  AST_APP_ARG(retries);
3074  AST_APP_ARG(dialdata);
3075  );
3076 
3077  if (ast_strlen_zero(data)) {
3078  ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
3079  return -1;
3080  }
3081 
3082  parse = ast_strdupa(data);
3083  AST_STANDARD_APP_ARGS(args, parse);
3084 
3085  if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
3086  sleepms *= 1000;
3087 
3088  if (!ast_strlen_zero(args.retries)) {
3089  loops = atoi(args.retries);
3090  }
3091 
3092  if (!args.dialdata) {
3093  ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
3094  goto done;
3095  }
3096 
3097  if (sleepms < 1000)
3098  sleepms = 10000;
3099 
3100  if (!loops)
3101  loops = -1; /* run forever */
3102 
3103  ast_channel_lock(chan);
3104  context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
3105  context = !ast_strlen_zero(context) ? ast_strdupa(context) : NULL;
3106  ast_channel_unlock(chan);
3107 
3108  res = 0;
3109  while (loops) {
3110  int continue_exec;
3111 
3112  chan->data = "Retrying";
3113  if (ast_test_flag(chan, AST_FLAG_MOH))
3114  ast_moh_stop(chan);
3115 
3116  res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
3117  if (continue_exec)
3118  break;
3119 
3120  if (res == 0) {
3121  if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
3122  if (!ast_strlen_zero(args.announce)) {
3123  if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
3124  if (!(res = ast_streamfile(chan, args.announce, chan->language)))
3126  } else
3127  ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3128  }
3129  if (!res && sleepms) {
3130  if (!ast_test_flag(chan, AST_FLAG_MOH))
3131  ast_moh_start(chan, NULL, NULL);
3132  res = ast_waitfordigit(chan, sleepms);
3133  }
3134  } else {
3135  if (!ast_strlen_zero(args.announce)) {
3136  if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
3137  if (!(res = ast_streamfile(chan, args.announce, chan->language)))
3138  res = ast_waitstream(chan, "");
3139  } else
3140  ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3141  }
3142  if (sleepms) {
3143  if (!ast_test_flag(chan, AST_FLAG_MOH))
3144  ast_moh_start(chan, NULL, NULL);
3145  if (!res)
3146  res = ast_waitfordigit(chan, sleepms);
3147  }
3148  }
3149  }
3150 
3151  if (res < 0 || res == AST_PBX_INCOMPLETE) {
3152  break;
3153  } else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
3154  if (onedigit_goto(chan, context, (char) res, 1)) {
3155  res = 0;
3156  break;
3157  }
3158  }
3159  loops--;
3160  }
3161  if (loops == 0)
3162  res = 0;
3163  else if (res == 1)
3164  res = 0;
3165 
3166  if (ast_test_flag(chan, AST_FLAG_MOH))
3167  ast_moh_stop(chan);
3168  done:
3169  return res;
3170 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
Definition: app_dial.c:755
#define AST_DIGIT_ANY
Definition: file.h:47
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
const char * data
Definition: channel.h:755
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:206
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:8051
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_PBX_INCOMPLETE
Definition: pbx.h:50
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
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:8040
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
static const char rapp[]
Definition: app_dial.c:543
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
Definition: app_dial.c:1987
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
const ast_string_field language
Definition: channel.h:787
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static void senddialendevent ( struct ast_channel src,
const char *  dialstatus 
)
static

Definition at line 810 of file app_dial.c.

References ast_manager_event, EVENT_FLAG_CALL, ast_channel::name, and ast_channel::uniqueid.

Referenced by dial_exec_full().

811 {
812  ast_manager_event(src, EVENT_FLAG_CALL, "Dial",
813  "SubEvent: End\r\n"
814  "Channel: %s\r\n"
815  "UniqueID: %s\r\n"
816  "DialStatus: %s\r\n",
817  src->name, src->uniqueid, dialstatus);
818 }
const ast_string_field uniqueid
Definition: channel.h:787
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define ast_manager_event(chan, category, event, contents,...)
Definition: manager.h:221
const ast_string_field name
Definition: channel.h:787
static void senddialevent ( struct ast_channel src,
struct ast_channel dst,
const char *  dialstring 
)
static

Definition at line 787 of file app_dial.c.

References ast_manager_event_multichan, ast_channel::caller, ast_channel::connected, EVENT_FLAG_CALL, ast_party_caller::id, ast_party_connected_line::id, ast_party_id::name, ast_channel::name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_channel::uniqueid, ast_party_name::valid, and ast_party_number::valid.

Referenced by dial_exec_full(), and do_forward().

788 {
789  struct ast_channel *chans[] = { src, dst };
791  "SubEvent: Begin\r\n"
792  "Channel: %s\r\n"
793  "Destination: %s\r\n"
794  "CallerIDNum: %s\r\n"
795  "CallerIDName: %s\r\n"
796  "ConnectedLineNum: %s\r\n"
797  "ConnectedLineName: %s\r\n"
798  "UniqueID: %s\r\n"
799  "DestUniqueID: %s\r\n"
800  "Dialstring: %s\r\n",
801  src->name, dst->name,
802  S_COR(src->caller.id.number.valid, src->caller.id.number.str, "<unknown>"),
803  S_COR(src->caller.id.name.valid, src->caller.id.name.str, "<unknown>"),
804  S_COR(src->connected.id.number.valid, src->connected.id.number.str, "<unknown>"),
805  S_COR(src->connected.id.name.valid, src->connected.id.name.str, "<unknown>"),
806  src->uniqueid, dst->uniqueid,
807  dialstring ? dialstring : "");
808 }
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
const ast_string_field uniqueid
Definition: channel.h:787
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
#define EVENT_FLAG_CALL
Definition: manager.h:72
char * str
Subscriber name (Malloced)
Definition: channel.h:214
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#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:83
const ast_string_field name
Definition: channel.h:787
#define ast_manager_event_multichan(category, event, nchans, chans, contents,...)
Definition: manager.h:226
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
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 1826 of file app_dial.c.

References ast_answer(), 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(), ast_channel::caller, ast_channel::exten, ast_party_caller::id, ast_channel::language, LOG_NOTICE, LOG_WARNING, ast_channel::name, ast_party_id::number, OPT_ARG_PRIVACY, OPT_PRIVACY, OPT_SCREEN_NOCALLERID, privacy_args::privcid, privacy_args::privdb_val, privacy_args::privintro, silencethreshold, privacy_args::status, ast_party_number::str, THRESHOLD_SILENCE, and ast_party_number::valid.

Referenced by dial_exec_full().

1828 {
1829  char callerid[60];
1830  int res;
1831  char *l;
1832  int silencethreshold;
1833 
1834  if (chan->caller.id.number.valid
1835  && !ast_strlen_zero(chan->caller.id.number.str)) {
1836  l = ast_strdupa(chan->caller.id.number.str);
1838  if (ast_test_flag64(opts, OPT_PRIVACY) ) {
1839  ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
1840  pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
1841  } else {
1842  ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
1844  }
1845  } else {
1846  char *tnam, *tn2;
1847 
1848  tnam = ast_strdupa(chan->name);
1849  /* clean the channel name so slashes don't try to end up in disk file name */
1850  for (tn2 = tnam; *tn2; tn2++) {
1851  if (*tn2 == '/') /* any other chars to be afraid of? */
1852  *tn2 = '=';
1853  }
1854  ast_verb(3, "Privacy-- callerid is empty\n");
1855 
1856  snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
1857  l = callerid;
1859  }
1860 
1861  ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
1862 
1863  if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
1864  /* if callerid is set and OPT_SCREEN_NOCALLERID is set also */
1865  ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
1867  } else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
1868  ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
1869  }
1870 
1871  if (pa->privdb_val == AST_PRIVACY_DENY) {
1872  ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1873  ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1874  return 0;
1875  } else if (pa->privdb_val == AST_PRIVACY_KILL) {
1876  ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1877  return 0; /* Is this right? */
1878  } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
1879  ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1880  return 0; /* is this right??? */
1881  } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
1882  /* Get the user's intro, store it in priv-callerintros/$CID,
1883  unless it is already there-- this should be done before the
1884  call is actually dialed */
1885 
1886  /* make sure the priv-callerintros dir actually exists */
1887  snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1888  if ((res = ast_mkdir(pa->privintro, 0755))) {
1889  ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
1890  return -1;
1891  }
1892 
1893  snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
1894  if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
1895  /* the DELUX version of this code would allow this caller the
1896  option to hear and retape their previously recorded intro.
1897  */
1898  } else {
1899  int duration; /* for feedback from play_and_wait */
1900  /* the file doesn't exist yet. Let the caller submit his
1901  vocal intro for posterity */
1902  /* priv-recordintro script:
1903 
1904  "At the tone, please say your name:"
1905 
1906  */
1908  ast_answer(chan);
1909  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 */
1910  /* don't think we'll need a lock removed, we took care of
1911  conflicts by naming the pa.privintro file */
1912  if (res == -1) {
1913  /* Delete the file regardless since they hung up during recording */
1914  ast_filedelete(pa->privintro, NULL);
1915  if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
1916  ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1917  else
1918  ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1919  return -1;
1920  }
1921  if (!ast_streamfile(chan, "vm-dialout", chan->language) )
1922  ast_waitstream(chan, "");
1923  }
1924  }
1925  return 1; /* success */
1926 }
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: app.c:1183
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
#define AST_PRIVACY_ALLOW
Definition: privacy.h:31
char privintro[1024]
Definition: app_dial.c:1029
char privcid[256]
Definition: app_dial.c:1028
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int ast_privacy_check(char *dest, char *cid)
Definition: privacy.c:48
#define LOG_WARNING
Definition: logger.h:144
#define AST_PRIVACY_TORTURE
Definition: privacy.h:33
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
#define ast_verb(level,...)
Definition: logger.h:243
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define AST_PRIVACY_KILL
Definition: privacy.h:32
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int silencethreshold
const char * ast_config_AST_DATA_DIR
Definition: asterisk.c:262
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int privdb_val
Definition: app_dial.c:1027
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_PRIVACY_UNKNOWN
Definition: privacy.h:34
#define AST_PRIVACY_DENY
Definition: privacy.h:30
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
char status[256]
Definition: app_dial.c:1030
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:948
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1880
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2151
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static int unload_module ( void  )
static

Definition at line 3172 of file app_dial.c.

References ast_context_destroy(), ast_context_find(), ast_context_remove_extension2(), and ast_unregister_application().

3173 {
3174  int res;
3175  struct ast_context *con;
3176 
3179 
3180  if ((con = ast_context_find("app_dial_gosub_virtual_context"))) {
3181  ast_context_remove_extension2(con, "s", 1, NULL, 0);
3182  ast_context_destroy(con, "app_dial"); /* leave nothing behind */
3183  }
3184 
3185  return res;
3186 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static const char app[]
Definition: app_dial.c:542
static const char rapp[]
Definition: app_dial.c:543
int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked)
This functionc locks given context, search for the right extension and fires out all peer in this ext...
Definition: pbx.c:6144
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context (or ANY context if NULL)
Definition: pbx.c:9875
ast_context: An extension context
Definition: pbx.c:955
struct ast_context * ast_context_find(const char *name)
Find a context.
Definition: pbx.c:2971
static int valid_priv_reply ( struct ast_flags64 opts,
int  res 
)
static

Definition at line 1680 of file app_dial.c.

References ast_test_flag64, OPT_PRIVACY, and OPT_SCREENING.

1681 {
1682  if (res < '1')
1683  return 0;
1684  if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
1685  return 1;
1686  if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
1687  return 1;
1688  return 0;
1689 }
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static struct ast_channel* wait_for_answer ( struct ast_channel in,
struct chanlist outgoing,
int *  to,
struct ast_flags64 peerflags,
char *  opt_args[],
struct privacy_args pa,
const struct cause_args num_in,
int *  result,
char *  dtmf_progress,
const int  ignore_cc,
struct ast_party_id forced_clid,
struct ast_party_id stored_clid 
)
static

Definition at line 1033 of file app_dial.c.

References ast_channel::_state, ast_cdr::answer, 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_CDR_ANSWERED, ast_cdr_failed(), ast_cdr_noanswer(), ast_channel_connected_line_macro(), ast_channel_early_bridge(), ast_channel_lock, ast_channel_make_compatible(), ast_channel_redirecting_macro(), ast_channel_sendhtml(), ast_channel_unlock, ast_channel_update_connected_line(), ast_check_hangup(), ast_clear_flag64, ast_connected_line_copy_from_caller(), ast_connected_line_parse_data(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, 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_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_flags64, ast_copy_string(), ast_deactivate_generator(), ast_debug, ast_dtmf_stream(), 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_VOICE, ast_frfree, ast_handle_cc_control_frame(), ast_hangup(), ast_indicate(), ast_indicate_data(), ast_log(), AST_MAX_WATCHERS, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_connected_line_set(), ast_party_connected_line_set_init(), ast_poll_channel_add(), ast_poll_channel_del(), ast_read(), ast_remaining_ms(), AST_STATE_UP, ast_str_alloca, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_tvnow(), ast_verb, ast_waitfor_n(), ast_write(), cause_args::busy, ast_channel::call_forward, ast_channel::caller, CAN_EARLY_BRIDGE, ast_channel::cdr, chanlist::chan, cause_args::congestion, chanlist::connected, ast_channel::connected, context, ast_frame::data, ast_frame::datalen, detect_disconnect(), DIAL_CALLERID_ABSENT, DIAL_NOFORWARDHTML, DIAL_STILLGOING, dialcontext, ast_cdr::disposition, do_forward(), ast_channel::exten, f, FEATURE_MAX_LEN, ast_frame::frametype, handle_cause(), ast_channel::hangupcause, ast_frame_subclass::integer, LOG_WARNING, ast_channel::name, chanlist::next, cause_args::nochan, 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, pbx_builtin_getvar_helper(), chanlist::pending_connected_update, ast_frame::ptr, privacy_args::sentringing, ast_party_connected_line::source, privacy_args::status, ast_frame::subclass, and ast_frame::uint32.

Referenced by dial_exec_full().

1040 {
1041  struct cause_args num = *num_in;
1042  int prestart = num.busy + num.congestion + num.nochan;
1043  int orig = *to;
1044  struct ast_channel *peer = NULL;
1045  /* single is set if only one destination is enabled */
1046  int single = outgoing && !outgoing->next;
1047  int caller_entertained = outgoing
1048  && ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
1049 #ifdef HAVE_EPOLL
1050  struct chanlist *epollo;
1051 #endif
1052  struct ast_party_connected_line connected_caller;
1053  struct ast_str *featurecode = ast_str_alloca(FEATURE_MAX_LEN + 1);
1054  int cc_recall_core_id;
1055  int is_cc_recall;
1056  int cc_frame_received = 0;
1057  int num_ringing = 0;
1058  struct timeval start = ast_tvnow();
1059 
1060  ast_party_connected_line_init(&connected_caller);
1061  if (single) {
1062  /* Turn off hold music, etc */
1063  if (!caller_entertained) {
1065  /* If we are calling a single channel, and not providing ringback or music, */
1066  /* then, make them compatible for in-band tone purpose */
1067  if (ast_channel_make_compatible(outgoing->chan, in) < 0) {
1068  /* If these channels can not be made compatible,
1069  * there is no point in continuing. The bridge
1070  * will just fail if it gets that far.
1071  */
1072  *to = -1;
1073  strcpy(pa->status, "CONGESTION");
1074  ast_cdr_failed(in->cdr);
1075  return NULL;
1076  }
1077  }
1078 
1080  && !ast_test_flag64(outgoing, DIAL_CALLERID_ABSENT)) {
1081  ast_channel_lock(outgoing->chan);
1082  ast_connected_line_copy_from_caller(&connected_caller, &outgoing->chan->caller);
1083  ast_channel_unlock(outgoing->chan);
1084  connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1085  if (ast_channel_connected_line_macro(outgoing->chan, in, &connected_caller, 1, 0)) {
1086  ast_channel_update_connected_line(in, &connected_caller, NULL);
1087  }
1088  ast_party_connected_line_free(&connected_caller);
1089  }
1090  }
1091 
1092  is_cc_recall = ast_cc_is_recall(in, &cc_recall_core_id, NULL);
1093 
1094 #ifdef HAVE_EPOLL
1095  for (epollo = outgoing; epollo; epollo = epollo->next)
1096  ast_poll_channel_add(in, epollo->chan);
1097 #endif
1098 
1099  while ((*to = ast_remaining_ms(start, orig)) && !peer) {
1100  struct chanlist *o;
1101  int pos = 0; /* how many channels do we handle */
1102  int numlines = prestart;
1103  struct ast_channel *winner;
1104  struct ast_channel *watchers[AST_MAX_WATCHERS];
1105 
1106  watchers[pos++] = in;
1107  for (o = outgoing; o; o = o->next) {
1108  /* Keep track of important channels */
1109  if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
1110  watchers[pos++] = o->chan;
1111  numlines++;
1112  }
1113  if (pos == 1) { /* only the input channel is available */
1114  if (numlines == (num.busy + num.congestion + num.nochan)) {
1115  ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1116  if (num.busy)
1117  strcpy(pa->status, "BUSY");
1118  else if (num.congestion)
1119  strcpy(pa->status, "CONGESTION");
1120  else if (num.nochan)
1121  strcpy(pa->status, "CHANUNAVAIL");
1122  } else {
1123  ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1124  }
1125  *to = 0;
1126  if (is_cc_recall) {
1127  ast_cc_failed(cc_recall_core_id, "Everyone is busy/congested for the recall. How sad");
1128  }
1129  return NULL;
1130  }
1131  winner = ast_waitfor_n(watchers, pos, to);
1132  for (o = outgoing; o; o = o->next) {
1133  struct ast_frame *f;
1134  struct ast_channel *c = o->chan;
1135 
1136  if (c == NULL)
1137  continue;
1139  if (!peer) {
1140  ast_verb(3, "%s answered %s\n", c->name, in->name);
1141  if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1142  if (o->pending_connected_update) {
1143  if (ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
1145  }
1146  } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1147  ast_channel_lock(c);
1148  ast_connected_line_copy_from_caller(&connected_caller, &c->caller);
1149  ast_channel_unlock(c);
1150  connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1151  if (ast_channel_connected_line_macro(c, in, &connected_caller, 1, 0)) {
1152  ast_channel_update_connected_line(in, &connected_caller, NULL);
1153  }
1154  ast_party_connected_line_free(&connected_caller);
1155  }
1156  }
1157  if (o->aoc_s_rate_list) {
1158  size_t encoded_size;
1159  struct ast_aoc_encoded *encoded;
1160  if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1161  ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1162  ast_aoc_destroy_encoded(encoded);
1163  }
1164  }
1165  peer = c;
1166  ast_copy_flags64(peerflags, o,
1174  ast_copy_string(c->exten, "", sizeof(c->exten));
1175  }
1176  continue;
1177  }
1178  if (c != winner)
1179  continue;
1180  /* here, o->chan == c == winner */
1181  if (!ast_strlen_zero(c->call_forward)) {
1182  pa->sentringing = 0;
1183  if (!ignore_cc && (f = ast_read(c))) {
1185  /* This channel is forwarding the call, and is capable of CC, so
1186  * be sure to add the new device interface to the list
1187  */
1189  }
1190  ast_frfree(f);
1191  }
1192 
1193  if (o->pending_connected_update) {
1194  /*
1195  * Re-seed the chanlist's connected line information with
1196  * previously acquired connected line info from the incoming
1197  * channel. The previously acquired connected line info could
1198  * have been set through the CONNECTED_LINE dialplan function.
1199  */
1200  o->pending_connected_update = 0;
1201  ast_channel_lock(in);
1203  ast_channel_unlock(in);
1204  }
1205 
1206  do_forward(o, &num, peerflags, single, caller_entertained, &orig,
1207  forced_clid, stored_clid);
1208 
1209  if (single && o->chan
1212  ast_channel_lock(o->chan);
1213  ast_connected_line_copy_from_caller(&connected_caller, &o->chan->caller);
1215  connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1216  if (ast_channel_connected_line_macro(o->chan, in, &connected_caller, 1, 0)) {
1217  ast_channel_update_connected_line(in, &connected_caller, NULL);
1218  }
1219  ast_party_connected_line_free(&connected_caller);
1220  }
1221  continue;
1222  }
1223  f = ast_read(winner);
1224  if (!f) {
1225  in->hangupcause = c->hangupcause;
1226 #ifdef HAVE_EPOLL
1227  ast_poll_channel_del(in, c);
1228 #endif
1229  ast_hangup(c);
1230  c = o->chan = NULL;
1232  handle_cause(in->hangupcause, &num);
1233  continue;
1234  }
1235  switch (f->frametype) {
1236  case AST_FRAME_CONTROL:
1237  switch (f->subclass.integer) {
1238  case AST_CONTROL_ANSWER:
1239  /* This is our guy if someone answered. */
1240  if (!peer) {
1241  ast_verb(3, "%s answered %s\n", c->name, in->name);
1242  if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1243  if (o->pending_connected_update) {
1244  if (ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
1246  }
1247  } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1248  ast_channel_lock(c);
1249  ast_connected_line_copy_from_caller(&connected_caller, &c->caller);
1250  ast_channel_unlock(c);
1251  connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1252  if (ast_channel_connected_line_macro(c, in, &connected_caller, 1, 0)) {
1253  ast_channel_update_connected_line(in, &connected_caller, NULL);
1254  }
1255  ast_party_connected_line_free(&connected_caller);
1256  }
1257  }
1258  if (o->aoc_s_rate_list) {
1259  size_t encoded_size;
1260  struct ast_aoc_encoded *encoded;
1261  if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1262  ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1263  ast_aoc_destroy_encoded(encoded);
1264  }
1265  }
1266  peer = c;
1267  if (peer->cdr) {
1268  peer->cdr->answer = ast_tvnow();
1269  peer->cdr->disposition = AST_CDR_ANSWERED;
1270  }
1271  ast_copy_flags64(peerflags, o,
1279  ast_copy_string(c->exten, "", sizeof(c->exten));
1280  if (CAN_EARLY_BRIDGE(peerflags, in, peer))
1281  /* Setup early bridge if appropriate */
1282  ast_channel_early_bridge(in, peer);
1283  }
1284  /* If call has been answered, then the eventual hangup is likely to be normal hangup */
1287  break;
1288  case AST_CONTROL_BUSY:
1289  ast_verb(3, "%s is busy\n", c->name);
1290  in->hangupcause = c->hangupcause;
1291  ast_hangup(c);
1292  c = o->chan = NULL;
1295  break;
1297  ast_verb(3, "%s is circuit-busy\n", c->name);
1298  in->hangupcause = c->hangupcause;
1299  ast_hangup(c);
1300  c = o->chan = NULL;
1303  break;
1304  case AST_CONTROL_RINGING:
1305  /* This is a tricky area to get right when using a native
1306  * CC agent. The reason is that we do the best we can to send only a
1307  * single ringing notification to the caller.
1308  *
1309  * Call completion complicates the logic used here. CCNR is typically
1310  * offered during a ringing message. Let's say that party A calls
1311  * parties B, C, and D. B and C do not support CC requests, but D
1312  * does. If we were to receive a ringing notification from B before
1313  * the others, then we would end up sending a ringing message to
1314  * A with no CCNR offer present.
1315  *
1316  * The approach that we have taken is that if we receive a ringing
1317  * response from a party and no CCNR offer is present, we need to
1318  * wait. Specifically, we need to wait until either a) a called party
1319  * offers CCNR in its ringing response or b) all called parties have
1320  * responded in some way to our call and none offers CCNR.
1321  *
1322  * The drawback to this is that if one of the parties has a delayed
1323  * response or, god forbid, one just plain doesn't respond to our
1324  * outgoing call, then this will result in a significant delay between
1325  * when the caller places the call and hears ringback.
1326  *
1327  * Note also that if CC is disabled for this call, then it is perfectly
1328  * fine for ringing frames to get sent through.
1329  */
1330  ++num_ringing;
1331  if (ignore_cc || cc_frame_received || num_ringing == numlines) {
1332  ast_verb(3, "%s is ringing\n", c->name);
1333  /* Setup early media if appropriate */
1334  if (single && !caller_entertained
1335  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1336  ast_channel_early_bridge(in, c);
1337  }
1338  if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK) && ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
1340  pa->sentringing++;
1341  }
1342  }
1343  break;
1344  case AST_CONTROL_PROGRESS:
1345  ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
1346  /* Setup early media if appropriate */
1347  if (single && !caller_entertained
1348  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1349  ast_channel_early_bridge(in, c);
1350  }
1351  if (!ast_test_flag64(outgoing, OPT_RINGBACK)) {
1352  if (single || (!single && !pa->sentringing)) {
1354  }
1355  }
1356  if (!ast_strlen_zero(dtmf_progress)) {
1357  ast_verb(3,
1358  "Sending DTMF '%s' to the called party as result of receiving a PROGRESS message.\n",
1359  dtmf_progress);
1360  ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
1361  }
1362  break;
1363  case AST_CONTROL_VIDUPDATE:
1364  case AST_CONTROL_SRCUPDATE:
1365  case AST_CONTROL_SRCCHANGE:
1366  if (!single || caller_entertained) {
1367  break;
1368  }
1369  ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1370  c->name, f->subclass.integer, in->name);
1371  ast_indicate(in, f->subclass.integer);
1372  break;
1375  ast_verb(3, "Connected line update to %s prevented.\n", in->name);
1376  break;
1377  }
1378  if (!single) {
1380 
1381  ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n",
1382  c->name, in->name);
1387  o->pending_connected_update = 1;
1388  break;
1389  }
1390  if (ast_channel_connected_line_macro(c, in, f, 1, 1)) {
1392  }
1393  break;
1394  case AST_CONTROL_AOC:
1395  {
1396  struct ast_aoc_decoded *decoded = ast_aoc_decode(f->data.ptr, f->datalen, o->chan);
1397  if (decoded && (ast_aoc_get_msg_type(decoded) == AST_AOC_S)) {
1399  o->aoc_s_rate_list = decoded;
1400  } else {
1401  ast_aoc_destroy_decoded(decoded);
1402  }
1403  }
1404  break;
1406  if (!single) {
1407  /*
1408  * Redirecting updates to the caller make sense only on single
1409  * calls.
1410  */
1411  break;
1412  }
1414  ast_verb(3, "Redirecting update to %s prevented.\n", in->name);
1415  break;
1416  }
1417  ast_verb(3, "%s redirecting info has changed, passing it to %s\n",
1418  c->name, in->name);
1419  if (ast_channel_redirecting_macro(c, in, f, 1, 1)) {
1421  }
1422  pa->sentringing = 0;
1423  break;
1425  ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
1426  if (single && !caller_entertained
1427  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1428  ast_channel_early_bridge(in, c);
1429  }
1430  if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1432  break;
1433  case AST_CONTROL_HOLD:
1434  /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1435  ast_verb(3, "Call on %s placed on hold\n", c->name);
1437  break;
1438  case AST_CONTROL_UNHOLD:
1439  /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1440  ast_verb(3, "Call on %s left from hold\n", c->name);
1442  break;
1443  case AST_CONTROL_OFFHOOK:
1444  case AST_CONTROL_FLASH:
1445  /* Ignore going off hook and flash */
1446  break;
1447  case AST_CONTROL_CC:
1448  if (!ignore_cc) {
1450  cc_frame_received = 1;
1451  }
1452  break;
1453  case -1:
1454  if (single && !caller_entertained) {
1455  ast_verb(3, "%s stopped sounds\n", c->name);
1456  ast_indicate(in, -1);
1457  pa->sentringing = 0;
1458  }
1459  break;
1460  default:
1461  ast_debug(1, "Dunno what to do with control type %d\n", f->subclass.integer);
1462  break;
1463  }
1464  break;
1465  case AST_FRAME_VOICE:
1466  case AST_FRAME_IMAGE:
1467  if (caller_entertained) {
1468  break;
1469  }
1470  /* Fall through */
1471  case AST_FRAME_TEXT:
1472  if (single && ast_write(in, f)) {
1473  ast_log(LOG_WARNING, "Unable to write frametype: %u\n",
1474  f->frametype);
1475  }
1476  break;
1477  case AST_FRAME_HTML:
1478  if (single && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML)
1479  && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1480  ast_log(LOG_WARNING, "Unable to send URL\n");
1481  }
1482  break;
1483  default:
1484  break;
1485  }
1486  ast_frfree(f);
1487  } /* end for */
1488  if (winner == in) {
1489  struct ast_frame *f = ast_read(in);
1490 #if 0
1491  if (f && (f->frametype != AST_FRAME_VOICE))
1492  printf("Frame type: %d, %d\n", f->frametype, f->subclass);
1493  else if (!f || (f->frametype != AST_FRAME_VOICE))
1494  printf("Hangup received on %s\n", in->name);
1495 #endif
1496  if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP))) {
1497  /* Got hung up */
1498  *to = -1;
1499  strcpy(pa->status, "CANCEL");
1500  ast_cdr_noanswer(in->cdr);
1501  if (f) {
1502  if (f->data.uint32) {
1503  in->hangupcause = f->data.uint32;
1504  }
1505  ast_frfree(f);
1506  }
1507  if (is_cc_recall) {
1508  ast_cc_completed(in, "CC completed, although the caller hung up (cancelled)");
1509  }
1510  return NULL;
1511  }
1512 
1513  /* now f is guaranteed non-NULL */
1514  if (f->frametype == AST_FRAME_DTMF) {
1515  if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
1516  const char *context;
1517  ast_channel_lock(in);
1518  context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
1519  if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
1520  ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
1521  *to = 0;
1522  ast_cdr_noanswer(in->cdr);
1523  *result = f->subclass.integer;
1524  strcpy(pa->status, "CANCEL");
1525  ast_frfree(f);
1526  ast_channel_unlock(in);
1527  if (is_cc_recall) {
1528  ast_cc_completed(in, "CC completed, but the caller used DTMF to exit");
1529  }
1530  return NULL;
1531  }
1532  ast_channel_unlock(in);
1533  }
1534 
1535  if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
1536  detect_disconnect(in, f->subclass.integer, &featurecode)) {
1537  ast_verb(3, "User requested call disconnect.\n");
1538  *to = 0;
1539  strcpy(pa->status, "CANCEL");
1540  ast_cdr_noanswer(in->cdr);
1541  ast_frfree(f);
1542  if (is_cc_recall) {
1543  ast_cc_completed(in, "CC completed, but the caller hung up with DTMF");
1544  }
1545  return NULL;
1546  }
1547  }
1548 
1549  /* Send the frame from the in channel to all outgoing channels. */
1550  for (o = outgoing; o; o = o->next) {
1551  if (!o->chan || !ast_test_flag64(o, DIAL_STILLGOING)) {
1552  /* This outgoing channel has died so don't send the frame to it. */
1553  continue;
1554  }
1555  switch (f->frametype) {
1556  case AST_FRAME_HTML:
1557  /* Forward HTML stuff */
1559  && ast_channel_sendhtml(o->chan, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1560  ast_log(LOG_WARNING, "Unable to send URL\n");
1561  }
1562  break;
1563  case AST_FRAME_VOICE:
1564  case AST_FRAME_IMAGE:
1565  if (!single || caller_entertained) {
1566  /*
1567  * We are calling multiple parties or caller is being
1568  * entertained and has thus not been made compatible.
1569  * No need to check any other called parties.
1570  */
1571  goto skip_frame;
1572  }
1573  /* Fall through */
1574  case AST_FRAME_TEXT:
1575  case AST_FRAME_DTMF_BEGIN:
1576  case AST_FRAME_DTMF_END:
1577  if (ast_write(o->chan, f)) {
1578  ast_log(LOG_WARNING, "Unable to forward frametype: %u\n",
1579  f->frametype);
1580  }
1581  break;
1582  case AST_FRAME_CONTROL:
1583  switch (f->subclass.integer) {
1584  case AST_CONTROL_HOLD:
1585  ast_verb(3, "Call on %s placed on hold\n", o->chan->name);
1587  break;
1588  case AST_CONTROL_UNHOLD:
1589  ast_verb(3, "Call on %s left from hold\n", o->chan->name);
1591  break;
1592  case AST_CONTROL_VIDUPDATE:
1593  case AST_CONTROL_SRCUPDATE:
1594  case AST_CONTROL_SRCCHANGE:
1595  if (!single || caller_entertained) {
1596  /*
1597  * We are calling multiple parties or caller is being
1598  * entertained and has thus not been made compatible.
1599  * No need to check any other called parties.
1600  */
1601  goto skip_frame;
1602  }
1603  ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1604  in->name, f->subclass.integer, o->chan->name);
1606  break;
1608  if (ast_channel_connected_line_macro(in, o->chan, f, 0, 1)) {
1610  }
1611  break;
1613  if (ast_channel_redirecting_macro(in, o->chan, f, 0, 1)) {
1615  }
1616  break;
1617  default:
1618  /* We are not going to do anything with this frame. */
1619  goto skip_frame;
1620  }
1621  break;
1622  default:
1623  /* We are not going to do anything with this frame. */
1624  goto skip_frame;
1625  }
1626  }
1627 skip_frame:;
1628  ast_frfree(f);
1629  }
1630  }
1631 
1632  if (!*to) {
1633  ast_verb(3, "Nobody picked up in %d ms\n", orig);
1634  }
1635  if (!*to || ast_check_hangup(in)) {
1636  ast_cdr_noanswer(in->cdr);
1637  }
1638 
1639 #ifdef HAVE_EPOLL
1640  for (epollo = outgoing; epollo; epollo = epollo->next) {
1641  if (epollo->chan)
1642  ast_poll_channel_del(in, epollo->chan);
1643  }
1644 #endif
1645 
1646  if (is_cc_recall) {
1647  ast_cc_completed(in, "Recall completed!");
1648  }
1649  return peer;
1650 }
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:3534
union ast_frame_subclass subclass
Definition: frame.h:146
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode)
Definition: app_dial.c:1652
int sentringing
Definition: app_dial.c:1026
int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
Bridge two channels together (early)
Definition: channel.c:7406
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2308
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
void ast_cdr_failed(struct ast_cdr *cdr)
Fail a call.
Definition: cdr.c:764
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
void ast_poll_channel_add(struct ast_channel *chan0, struct ast_channel *chan1)
Definition: channel.c:2665
#define ast_copy_flags64(dest, src, flagz)
Definition: utils.h:141
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
Definition: app_dial.c:755
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
Definition: ccss.c:3613
unsigned int pending_connected_update
Definition: app_dial.c:671
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:2329
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
void * ptr
Definition: frame.h:160
int congestion
Definition: app_dial.c:713
#define LOG_WARNING
Definition: logger.h:144
#define AST_MAX_WATCHERS
Definition: app_dial.c:705
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:9085
#define AST_FRAME_DTMF
Definition: frame.h:128
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:176
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:4447
#define FEATURE_MAX_LEN
Definition: features.h:30
#define DIAL_STILLGOING
Definition: app_dial.c:580
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
struct ast_cdr * cdr
Definition: channel.h:766
#define ast_str_alloca(init_len)
Definition: strings.h:608
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2353
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int caller, int frame)
Run a connected line interception macro and update a channel&#39;s connected line information.
Definition: channel.c:9618
#define ast_verb(level,...)
Definition: logger.h:243
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:3172
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:2048
static void handle_cause(int cause, struct cause_args *num)
Definition: app_dial.c:717
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
#define CAN_EARLY_BRIDGE(flags, chan, peer)
Definition: app_dial.c:654
int ast_cc_completed(struct ast_channel *chan, const char *const debug,...)
Indicate recall has been acknowledged.
Definition: ccss.c:3576
#define DIAL_CALLERID_ABSENT
Definition: app_dial.c:582
struct chanlist * next
Definition: app_dial.c:665
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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:318
static char dialcontext[AST_MAX_CONTEXT]
struct ast_channel * chan
Definition: app_dial.c:666
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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:519
int datalen
Definition: frame.h:148
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
List of channel drivers.
Definition: app_dial.c:664
#define DIAL_NOFORWARDHTML
Definition: app_dial.c:581
int nochan
Definition: app_dial.c:714
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
struct ast_party_connected_line connected
Definition: app_dial.c:669
struct timeval answer
Definition: cdr.h:102
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:8886
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:1615
const ast_string_field call_forward
Definition: channel.h:787
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:2337
enum ast_channel_state _state
Definition: channel.h:839
Connected Line/Party information.
Definition: channel.h:401
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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:5907
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static struct ast_format f[]
Definition: format_g726.c:181
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:4916
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:182
#define ast_clear_flag64(p, flag)
Definition: utils.h:134
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:3107
void ast_poll_channel_del(struct ast_channel *chan0, struct ast_channel *chan1)
Definition: channel.c:2688
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:2316
int busy
Definition: app_dial.c:712
int ast_channel_make_compatible(struct ast_channel *c0, struct ast_channel *c1)
Makes two channel formats compatible.
Definition: channel.c:5970
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
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:8443
void ast_cdr_noanswer(struct ast_cdr *cdr)
A call wasn&#39;t answered.
Definition: cdr.c:776
#define AST_CAUSE_BUSY
Definition: causes.h:148
Data structure associated with a single frame of data.
Definition: frame.h:142
int hangupcause
Definition: channel.h:849
Definition: aoc.h:64
static int connected
Definition: cdr_pgsql.c:57
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:761
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:837
uint32_t uint32
Definition: frame.h:160
enum ast_frame_type frametype
Definition: frame.h:144
char status[256]
Definition: app_dial.c:1030
long int disposition
Definition: cdr.h:110
#define ast_frfree(fr)
Definition: frame.h:583
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send DTMF to a channel.
Definition: app.c:501
struct ast_aoc_decoded * aoc_s_rate_list
Definition: app_dial.c:672
union ast_frame::@172 data
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
Run a redirecting interception macro and update a channel&#39;s redirecting information.
Definition: channel.c:9663
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
#define ast_test_flag64(p, flag)
Definition: utils.h:120

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static

Definition at line 3205 of file app_dial.c.

const char app[] = "Dial"
static

Definition at line 542 of file app_dial.c.

Definition at line 3205 of file app_dial.c.

struct ast_app_option dial_exec_options[128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'a' ] = { .flag = (1LLU << 40) }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'c' ] = { .flag = (1LLU << 34) }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'e' ] = { .flag = (1LLU << 35) }, [ 'f' ] = { .flag = OPT_FORCECLID , .arg_index = OPT_ARG_FORCECLID + 1 }, [ 'F' ] = { .flag = (1LLU << 36) , .arg_index = OPT_ARG_CALLEE_GO_ON + 1 }, [ 'g' ] = { .flag = OPT_GO_ON }, [ 'G' ] = { .flag = OPT_GOTO , .arg_index = OPT_ARG_GOTO + 1 }, [ 'h' ] = { .flag = OPT_CALLEE_HANGUP }, [ 'H' ] = { .flag = OPT_CALLER_HANGUP }, [ 'i' ] = { .flag = OPT_IGNORE_FORWARDING }, [ 'I' ] = { .flag = OPT_IGNORE_CONNECTEDLINE }, [ 'k' ] = { .flag = OPT_CALLEE_PARK }, [ 'K' ] = { .flag = OPT_CALLER_PARK }, [ 'L' ] = { .flag = OPT_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, [ 'm' ] = { .flag = OPT_MUSICBACK , .arg_index = OPT_ARG_MUSICBACK + 1 }, [ 'M' ] = { .flag = OPT_CALLEE_MACRO , .arg_index = OPT_ARG_CALLEE_MACRO + 1 }, [ 'n' ] = { .flag = OPT_SCREEN_NOINTRO , .arg_index = OPT_ARG_SCREEN_NOINTRO + 1 }, [ 'N' ] = { .flag = OPT_SCREEN_NOCALLERID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID , .arg_index = OPT_ARG_ORIGINAL_CLID + 1 }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK , .arg_index = OPT_ARG_RINGBACK + 1 }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 's' ] = { .flag = (1LLU << 38) , .arg_index = OPT_ARG_FORCE_CID_TAG + 1 }, [ 'u' ] = { .flag = (1LLU << 39) , .arg_index = OPT_ARG_FORCE_CID_PRES + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ '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 652 of file app_dial.c.

Referenced by dial_exec_full().

const char rapp[] = "RetryDial"
static

Definition at line 543 of file app_dial.c.