Asterisk - The Open Source Telephony Project  GIT-master-9ed6387
Data Structures | Macros | Enumerations | Functions | Variables
app_dial.c File Reference

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

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

Go to the source code of this file.

Data Structures

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

Macros

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

Enumerations

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

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void chanlist_free (struct chanlist *outgoing)
 
static int detect_disconnect (struct ast_channel *chan, char code, struct ast_str **featurecode)
 
static int dial_exec (struct ast_channel *chan, const char *data)
 
static int dial_exec_full (struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
 
static int dial_handle_playtones (struct ast_channel *chan, const char *data)
 
static void do_forward (struct chanlist *o, struct cause_args *num, struct ast_flags64 *peerflags, int single, int caller_entertained, int *to, struct ast_party_id *forced_clid, struct ast_party_id *stored_clid)
 
static void end_bridge_callback (void *data)
 
static void end_bridge_callback_data_fixup (struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
 
static const char * get_cid_name (char *name, int namelen, struct ast_channel *chan)
 
static void handle_cause (int cause, struct cause_args *num)
 
static void hanguptree (struct dial_head *out_chans, struct ast_channel *exception, int hangupcause)
 
static int load_module (void)
 
static int onedigit_goto (struct ast_channel *chan, const char *context, char exten, int pri)
 
static void publish_dial_end_event (struct ast_channel *in, struct dial_head *out_chans, struct ast_channel *exception, const char *status)
 
static int retrydial_exec (struct ast_channel *chan, const char *data)
 
static void set_duration_var (struct ast_channel *chan, const char *var_base, int64_t duration)
 
static void setup_peer_after_bridge_goto (struct ast_channel *chan, struct ast_channel *peer, struct ast_flags64 *opts, char *opt_args[])
 
static int setup_privacy_args (struct privacy_args *pa, struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
 returns 1 if successful, 0 or <0 if the caller should 'goto out' More...
 
static int unload_module (void)
 
static void update_connected_line_from_peer (struct ast_channel *chan, struct ast_channel *peer, int is_caller)
 
static int valid_priv_reply (struct ast_flags64 *opts, int res)
 
static struct ast_channelwait_for_answer (struct ast_channel *in, struct dial_head *out_chans, int *to, struct ast_flags64 *peerflags, char *opt_args[], struct privacy_args *pa, const struct cause_args *num_in, int *result, char *dtmf_progress, 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_DEFAULT , .description = "Dialing Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "ccss", }
 
static const char app [] = "Dial"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const struct ast_app_option dial_exec_options [128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'a' ] = { .flag = (1LLU << 40) }, [ 'b' ] = { .flag = (1LLU << 41) , .arg_index = OPT_ARG_PREDIAL_CALLEE + 1 }, [ 'B' ] = { .flag = (1LLU << 42) , .arg_index = OPT_ARG_PREDIAL_CALLER + 1 }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'c' ] = { .flag = (1LLU << 34) }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'e' ] = { .flag = (1LLU << 35) }, [ 'f' ] = { .flag = OPT_FORCECLID , .arg_index = OPT_ARG_FORCECLID + 1 }, [ 'F' ] = { .flag = (1LLU << 36) , .arg_index = OPT_ARG_CALLEE_GO_ON + 1 }, [ 'g' ] = { .flag = OPT_GO_ON }, [ 'G' ] = { .flag = OPT_GOTO , .arg_index = OPT_ARG_GOTO + 1 }, [ 'h' ] = { .flag = OPT_CALLEE_HANGUP }, [ 'H' ] = { .flag = OPT_CALLER_HANGUP }, [ 'i' ] = { .flag = OPT_IGNORE_FORWARDING }, [ 'I' ] = { .flag = OPT_IGNORE_CONNECTEDLINE }, [ 'k' ] = { .flag = OPT_CALLEE_PARK }, [ 'K' ] = { .flag = OPT_CALLER_PARK }, [ 'L' ] = { .flag = OPT_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, [ 'm' ] = { .flag = OPT_MUSICBACK , .arg_index = OPT_ARG_MUSICBACK + 1 }, [ 'M' ] = { .flag = OPT_CALLEE_MACRO , .arg_index = OPT_ARG_CALLEE_MACRO + 1 }, [ 'n' ] = { .flag = OPT_SCREEN_NOINTRO , .arg_index = OPT_ARG_SCREEN_NOINTRO + 1 }, [ 'N' ] = { .flag = OPT_SCREEN_NOCALLERID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID , .arg_index = OPT_ARG_ORIGINAL_CLID + 1 }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'Q' ] = { .flag = (1LLU << 44) , .arg_index = OPT_ARG_HANGUPCAUSE + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK , .arg_index = OPT_ARG_RINGBACK + 1 }, [ 'R' ] = { .flag = (1LLU << 43) }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 's' ] = { .flag = (1LLU << 38) , .arg_index = OPT_ARG_FORCE_CID_TAG + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'u' ] = { .flag = (1LLU << 39) , .arg_index = OPT_ARG_FORCE_CID_PRES + 1 }, [ 'U' ] = { .flag = OPT_CALLEE_GOSUB , .arg_index = OPT_ARG_CALLEE_GOSUB + 1 }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR }, [ 'x' ] = { .flag = OPT_CALLEE_MIXMONITOR }, [ 'X' ] = { .flag = OPT_CALLER_MIXMONITOR }, [ 'z' ] = { .flag = (1LLU << 37) }, }
 
static const char rapp [] = "RetryDial"
 

Detailed Description

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

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

Definition in file app_dial.c.

Macro Definition Documentation

◆ AST_MAX_WATCHERS

#define AST_MAX_WATCHERS   256

Definition at line 846 of file app_dial.c.

Referenced by wait_for_answer().

◆ CAN_EARLY_BRIDGE

#define CAN_EARLY_BRIDGE (   flags,
  chan,
  peer 
)

Definition at line 785 of file app_dial.c.

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

◆ DIAL_CALLERID_ABSENT

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

Definition at line 702 of file app_dial.c.

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

◆ DIAL_NOFORWARDHTML

#define DIAL_NOFORWARDHTML   (1LLU << 32)

Definition at line 701 of file app_dial.c.

Referenced by dial_exec_full(), and wait_for_answer().

◆ DIAL_STILLGOING

#define DIAL_STILLGOING   (1LLU << 31)

Definition at line 700 of file app_dial.c.

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

◆ OPT_CALLEE_GO_ON

#define OPT_CALLEE_GO_ON   (1LLU << 36)

Definition at line 705 of file app_dial.c.

Referenced by setup_peer_after_bridge_goto().

◆ OPT_CALLER_ANSWER

#define OPT_CALLER_ANSWER   (1LLU << 40)

Definition at line 709 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_CANCEL_ELSEWHERE

#define OPT_CANCEL_ELSEWHERE   (1LLU << 34)

Definition at line 703 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_CANCEL_TIMEOUT

#define OPT_CANCEL_TIMEOUT   (1LLU << 37)

Definition at line 706 of file app_dial.c.

Referenced by dial_exec_full(), and do_forward().

◆ OPT_FORCE_CID_PRES

#define OPT_FORCE_CID_PRES   (1LLU << 39)

Definition at line 708 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_FORCE_CID_TAG

#define OPT_FORCE_CID_TAG   (1LLU << 38)

Definition at line 707 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_HANGUPCAUSE

#define OPT_HANGUPCAUSE   (1LLU << 44)

Definition at line 713 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_PEER_H

#define OPT_PEER_H   (1LLU << 35)

Definition at line 704 of file app_dial.c.

Referenced by setup_peer_after_bridge_goto().

◆ OPT_PREDIAL_CALLEE

#define OPT_PREDIAL_CALLEE   (1LLU << 41)

Definition at line 710 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_PREDIAL_CALLER

#define OPT_PREDIAL_CALLER   (1LLU << 42)

Definition at line 711 of file app_dial.c.

Referenced by dial_exec_full().

◆ OPT_RING_WITH_EARLY_MEDIA

#define OPT_RING_WITH_EARLY_MEDIA   (1LLU << 43)

Definition at line 712 of file app_dial.c.

Referenced by dial_exec_full(), and valid_priv_reply().

Enumeration Type Documentation

◆ anonymous enum

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

Definition at line 665 of file app_dial.c.

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

◆ anonymous enum

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

Definition at line 715 of file app_dial.c.

715  {
716  OPT_ARG_ANNOUNCE = 0,
718  OPT_ARG_GOTO,
736  /* note: this entry _MUST_ be the last one in the enum */
738 };

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 3462 of file app_dial.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3462 of file app_dial.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 3462 of file app_dial.c.

◆ chanlist_free()

static void chanlist_free ( struct chanlist outgoing)
static

Definition at line 820 of file app_dial.c.

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

Referenced by dial_exec_full(), and hanguptree().

821 {
824  ast_free(outgoing->orig_chan_name);
825  ast_free(outgoing);
826 }
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2047
struct ast_party_connected_line connected
Definition: app_dial.c:808
#define ast_free(a)
Definition: astmm.h:182
struct ast_aoc_decoded * aoc_s_rate_list
Definition: app_dial.c:811
char * orig_chan_name
Definition: app_dial.c:805

◆ detect_disconnect()

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

Definition at line 1855 of file app_dial.c.

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

Referenced by wait_for_answer().

1856 {
1857  char disconnect_code[AST_FEATURE_MAX_LEN];
1858  int res;
1859 
1860  ast_str_append(featurecode, 1, "%c", code);
1861 
1862  res = ast_get_builtin_feature(chan, "disconnect", disconnect_code, sizeof(disconnect_code));
1863  if (res) {
1864  ast_str_reset(*featurecode);
1865  return 0;
1866  }
1867 
1868  if (strlen(disconnect_code) > ast_str_strlen(*featurecode)) {
1869  /* Could be a partial match, anyway */
1870  if (strncmp(disconnect_code, ast_str_buffer(*featurecode), ast_str_strlen(*featurecode))) {
1871  ast_str_reset(*featurecode);
1872  }
1873  return 0;
1874  }
1875 
1876  if (strcmp(disconnect_code, ast_str_buffer(*featurecode))) {
1877  ast_str_reset(*featurecode);
1878  return 0;
1879  }
1880 
1881  return 1;
1882 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
int ast_get_builtin_feature(struct ast_channel *chan, const char *feature, char *buf, size_t len)
Get the DTMF code for a builtin feature.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define AST_FEATURE_MAX_LEN

◆ dial_exec()

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

Definition at line 3320 of file app_dial.c.

References dial_exec_full(), and NULL.

Referenced by load_module().

3321 {
3322  struct ast_flags64 peerflags;
3323 
3324  memset(&peerflags, 0, sizeof(peerflags));
3325 
3326  return dial_exec_full(chan, data, &peerflags, NULL);
3327 }
#define NULL
Definition: resample.c:96
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
Definition: app_dial.c:2213

◆ dial_exec_full()

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

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

Forced CallerID party information to send.

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

Stored CallerID information if needed.

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

CallerID party information to store.

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

Definition at line 2213 of file app_dial.c.

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

Referenced by dial_exec(), and retrydial_exec().

2214 {
2215  int res = -1; /* default: error */
2216  char *rest, *cur; /* scan the list of destinations */
2217  struct dial_head out_chans = AST_LIST_HEAD_NOLOCK_INIT_VALUE; /* list of destinations */
2218  struct chanlist *outgoing;
2219  struct chanlist *tmp;
2220  struct ast_channel *peer;
2221  int to; /* timeout */
2222  struct cause_args num = { chan, 0, 0, 0 };
2223  int cause;
2224 
2225  struct ast_bridge_config config = { { 0, } };
2226  struct timeval calldurationlimit = { 0, };
2227  char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress=NULL;
2228  struct privacy_args pa = {
2229  .sentringing = 0,
2230  .privdb_val = 0,
2231  .status = "INVALIDARGS",
2232  };
2233  int sentringing = 0, moh = 0;
2234  const char *outbound_group = NULL;
2235  int result = 0;
2236  char *parse;
2237  int opermode = 0;
2238  int delprivintro = 0;
2240  AST_APP_ARG(peers);
2243  AST_APP_ARG(url);
2244  );
2245  struct ast_flags64 opts = { 0, };
2246  char *opt_args[OPT_ARG_ARRAY_SIZE];
2247  int fulldial = 0, num_dialed = 0;
2248  int ignore_cc = 0;
2249  char device_name[AST_CHANNEL_NAME];
2250  char forced_clid_name[AST_MAX_EXTENSION];
2251  char stored_clid_name[AST_MAX_EXTENSION];
2252  int force_forwards_only; /*!< TRUE if force CallerID on call forward only. Legacy behaviour.*/
2253  /*!
2254  * \brief Forced CallerID party information to send.
2255  * \note This will not have any malloced strings so do not free it.
2256  */
2257  struct ast_party_id forced_clid;
2258  /*!
2259  * \brief Stored CallerID information if needed.
2260  *
2261  * \note If OPT_ORIGINAL_CLID set then this is the o option
2262  * CallerID. Otherwise it is the dialplan extension and hint
2263  * name.
2264  *
2265  * \note This will not have any malloced strings so do not free it.
2266  */
2267  struct ast_party_id stored_clid;
2268  /*!
2269  * \brief CallerID party information to store.
2270  * \note This will not have any malloced strings so do not free it.
2271  */
2272  struct ast_party_caller caller;
2273  int max_forwards;
2274  SCOPE_TRACE(1, "%s Data: %s\n", ast_channel_name(chan), data);
2275 
2276  /* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
2277  ast_channel_lock(chan);
2279  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
2280  pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
2281  pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
2282  pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
2283  pbx_builtin_setvar_helper(chan, "ANSWEREDTIME_MS", "");
2284  pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
2285  pbx_builtin_setvar_helper(chan, "DIALEDTIME_MS", "");
2286  pbx_builtin_setvar_helper(chan, "RINGTIME", "");
2287  pbx_builtin_setvar_helper(chan, "RINGTIME_MS", "");
2288  pbx_builtin_setvar_helper(chan, "PROGRESSTIME", "");
2289  pbx_builtin_setvar_helper(chan, "PROGRESSTIME_MS", "");
2291  max_forwards = ast_max_forwards_get(chan);
2292  ast_channel_unlock(chan);
2293 
2294  if (max_forwards <= 0) {
2295  ast_log(LOG_WARNING, "Cannot place outbound call from channel '%s'. Max forwards exceeded\n",
2296  ast_channel_name(chan));
2297  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "BUSY");
2298  return -1;
2299  }
2300 
2301  if (ast_check_hangup_locked(chan)) {
2302  /*
2303  * Caller hung up before we could dial. If dial is executed
2304  * within an AGI then the AGI has likely eaten all queued
2305  * frames before executing the dial in DeadAGI mode. With
2306  * the caller hung up and no pending frames from the caller's
2307  * read queue, dial would not know that the call has hung up
2308  * until a called channel answers. It is rather annoying to
2309  * whoever just answered the non-existent call.
2310  *
2311  * Dial should not continue execution in DeadAGI mode, hangup
2312  * handlers, or the h exten.
2313  */
2314  ast_verb(3, "Caller hung up before dial.\n");
2315  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "CANCEL");
2316  return -1;
2317  }
2318 
2319  parse = ast_strdupa(data ?: "");
2320 
2321  AST_STANDARD_APP_ARGS(args, parse);
2322 
2323  if (!ast_strlen_zero(args.options) &&
2324  ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
2325  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2326  goto done;
2327  }
2328 
2329  if (ast_cc_call_init(chan, &ignore_cc)) {
2330  goto done;
2331  }
2332 
2334  delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
2335 
2336  if (delprivintro < 0 || delprivintro > 1) {
2337  ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
2338  delprivintro = 0;
2339  }
2340  }
2341 
2342  if (!ast_test_flag64(&opts, OPT_RINGBACK)) {
2343  opt_args[OPT_ARG_RINGBACK] = NULL;
2344  }
2345 
2346  if (ast_test_flag64(&opts, OPT_OPERMODE)) {
2347  opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
2348  ast_verb(3, "Setting operator services mode to %d.\n", opermode);
2349  }
2350 
2352  calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
2353  if (!calldurationlimit.tv_sec) {
2354  ast_log(LOG_WARNING, "Dial does not accept S(%s)\n", opt_args[OPT_ARG_DURATION_STOP]);
2355  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2356  goto done;
2357  }
2358  ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
2359  }
2360 
2361  if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
2362  dtmf_progress = opt_args[OPT_ARG_SENDDTMF];
2363  dtmfcalled = strsep(&dtmf_progress, ":");
2364  dtmfcalling = strsep(&dtmf_progress, ":");
2365  }
2366 
2368  if (ast_bridge_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
2369  goto done;
2370  }
2371 
2372  /* Setup the forced CallerID information to send if used. */
2373  ast_party_id_init(&forced_clid);
2374  force_forwards_only = 0;
2375  if (ast_test_flag64(&opts, OPT_FORCECLID)) {
2376  if (ast_strlen_zero(opt_args[OPT_ARG_FORCECLID])) {
2377  ast_channel_lock(chan);
2378  forced_clid.number.str = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
2379  ast_channel_unlock(chan);
2380  forced_clid_name[0] = '\0';
2381  forced_clid.name.str = (char *) get_cid_name(forced_clid_name,
2382  sizeof(forced_clid_name), chan);
2383  force_forwards_only = 1;
2384  } else {
2385  /* Note: The opt_args[OPT_ARG_FORCECLID] string value is altered here. */
2386  ast_callerid_parse(opt_args[OPT_ARG_FORCECLID], &forced_clid.name.str,
2387  &forced_clid.number.str);
2388  }
2389  if (!ast_strlen_zero(forced_clid.name.str)) {
2390  forced_clid.name.valid = 1;
2391  }
2392  if (!ast_strlen_zero(forced_clid.number.str)) {
2393  forced_clid.number.valid = 1;
2394  }
2395  }
2397  && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_TAG])) {
2398  forced_clid.tag = opt_args[OPT_ARG_FORCE_CID_TAG];
2399  }
2400  forced_clid.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
2402  && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_PRES])) {
2403  int pres;
2404 
2405  pres = ast_parse_caller_presentation(opt_args[OPT_ARG_FORCE_CID_PRES]);
2406  if (0 <= pres) {
2407  forced_clid.number.presentation = pres;
2408  }
2409  }
2410 
2411  /* Setup the stored CallerID information if needed. */
2412  ast_party_id_init(&stored_clid);
2413  if (ast_test_flag64(&opts, OPT_ORIGINAL_CLID)) {
2414  if (ast_strlen_zero(opt_args[OPT_ARG_ORIGINAL_CLID])) {
2415  ast_channel_lock(chan);
2416  ast_party_id_set_init(&stored_clid, &ast_channel_caller(chan)->id);
2417  if (!ast_strlen_zero(ast_channel_caller(chan)->id.name.str)) {
2418  stored_clid.name.str = ast_strdupa(ast_channel_caller(chan)->id.name.str);
2419  }
2420  if (!ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
2421  stored_clid.number.str = ast_strdupa(ast_channel_caller(chan)->id.number.str);
2422  }
2423  if (!ast_strlen_zero(ast_channel_caller(chan)->id.subaddress.str)) {
2424  stored_clid.subaddress.str = ast_strdupa(ast_channel_caller(chan)->id.subaddress.str);
2425  }
2426  if (!ast_strlen_zero(ast_channel_caller(chan)->id.tag)) {
2427  stored_clid.tag = ast_strdupa(ast_channel_caller(chan)->id.tag);
2428  }
2429  ast_channel_unlock(chan);
2430  } else {
2431  /* Note: The opt_args[OPT_ARG_ORIGINAL_CLID] string value is altered here. */
2432  ast_callerid_parse(opt_args[OPT_ARG_ORIGINAL_CLID], &stored_clid.name.str,
2433  &stored_clid.number.str);
2434  if (!ast_strlen_zero(stored_clid.name.str)) {
2435  stored_clid.name.valid = 1;
2436  }
2437  if (!ast_strlen_zero(stored_clid.number.str)) {
2438  stored_clid.number.valid = 1;
2439  }
2440  }
2441  } else {
2442  /*
2443  * In case the new channel has no preset CallerID number by the
2444  * channel driver, setup the dialplan extension and hint name.
2445  */
2446  stored_clid_name[0] = '\0';
2447  stored_clid.name.str = (char *) get_cid_name(stored_clid_name,
2448  sizeof(stored_clid_name), chan);
2449  if (ast_strlen_zero(stored_clid.name.str)) {
2450  stored_clid.name.str = NULL;
2451  } else {
2452  stored_clid.name.valid = 1;
2453  }
2454  ast_channel_lock(chan);
2455  stored_clid.number.str = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
2456  stored_clid.number.valid = 1;
2457  ast_channel_unlock(chan);
2458  }
2459 
2460  if (ast_test_flag64(&opts, OPT_RESETCDR)) {
2461  ast_cdr_reset(ast_channel_name(chan), 0);
2462  }
2463  if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
2464  opt_args[OPT_ARG_PRIVACY] = ast_strdupa(ast_channel_exten(chan));
2465 
2466  if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
2467  res = setup_privacy_args(&pa, &opts, opt_args, chan);
2468  if (res <= 0)
2469  goto out;
2470  res = -1; /* reset default */
2471  }
2472 
2473  if (continue_exec)
2474  *continue_exec = 0;
2475 
2476  /* If a channel group has been specified, get it for use when we create peer channels */
2477 
2478  ast_channel_lock(chan);
2479  if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
2480  outbound_group = ast_strdupa(outbound_group);
2481  pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
2482  } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
2483  outbound_group = ast_strdupa(outbound_group);
2484  }
2485  ast_channel_unlock(chan);
2486 
2487  /* Set per dial instance flags. These flags are also passed back to RetryDial. */
2491 
2492  /* PREDIAL: Run gosub on the caller's channel */
2494  && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {
2495  ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLER]);
2496  ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER], 0);
2497  }
2498 
2499  /* loop through the list of dial destinations */
2500  rest = args.peers;
2501  while ((cur = strsep(&rest, "&"))) {
2502  struct ast_channel *tc; /* channel for this destination */
2503  char *number;
2504  char *tech;
2505  size_t tech_len;
2506  size_t number_len;
2507  struct ast_stream_topology *topology;
2508 
2509  cur = ast_strip(cur);
2510  if (ast_strlen_zero(cur)) {
2511  /* No tech/resource in this position. */
2512  continue;
2513  }
2514 
2515  /* Get a technology/resource pair */
2516  number = cur;
2517  tech = strsep(&number, "/");
2518 
2519  num_dialed++;
2520  if (ast_strlen_zero(number)) {
2521  ast_log(LOG_WARNING, "Dial argument takes format (technology/resource)\n");
2522  goto out;
2523  }
2524 
2525  tech_len = strlen(tech) + 1;
2526  number_len = strlen(number) + 1;
2527  tmp = ast_calloc(1, sizeof(*tmp) + (2 * tech_len) + number_len);
2528  if (!tmp) {
2529  goto out;
2530  }
2531 
2532  /* Save tech, number, and interface. */
2533  cur = tmp->stuff;
2534  strcpy(cur, tech);
2535  tmp->tech = cur;
2536  cur += tech_len;
2537  strcpy(cur, tech);
2538  cur[tech_len - 1] = '/';
2539  tmp->interface = cur;
2540  cur += tech_len;
2541  strcpy(cur, number);
2542  tmp->number = cur;
2543 
2544  if (opts.flags) {
2545  /* Set per outgoing call leg options. */
2546  ast_copy_flags64(tmp, &opts,
2556  }
2557 
2558  /* Request the peer */
2559 
2560  ast_channel_lock(chan);
2561  /*
2562  * Seed the chanlist's connected line information with previously
2563  * acquired connected line info from the incoming channel. The
2564  * previously acquired connected line info could have been set
2565  * through the CONNECTED_LINE dialplan function.
2566  */
2568 
2570 
2571  ast_channel_unlock(chan);
2572 
2573  tc = ast_request_with_stream_topology(tmp->tech, topology, NULL, chan, tmp->number, &cause);
2574 
2575  ast_stream_topology_free(topology);
2576 
2577  if (!tc) {
2578  /* If we can't, just go on to the next call */
2579  ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
2580  tmp->tech, cause, ast_cause2str(cause));
2581  handle_cause(cause, &num);
2582  if (!rest) {
2583  /* we are on the last destination */
2584  ast_channel_hangupcause_set(chan, cause);
2585  }
2586  if (!ignore_cc && (cause == AST_CAUSE_BUSY || cause == AST_CAUSE_CONGESTION)) {
2587  if (!ast_cc_callback(chan, tmp->tech, tmp->number, ast_cc_busy_interface)) {
2589  }
2590  }
2591  chanlist_free(tmp);
2592  continue;
2593  }
2594 
2595  ast_channel_get_device_name(tc, device_name, sizeof(device_name));
2596  if (!ignore_cc) {
2597  ast_cc_extension_monitor_add_dialstring(chan, tmp->interface, device_name);
2598  }
2599 
2600  ast_channel_lock_both(tc, chan);
2602 
2603  pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", tmp->number);
2604 
2605  /* Setup outgoing SDP to match incoming one */
2606  if (!AST_LIST_FIRST(&out_chans) && !rest && CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
2607  /* We are on the only destination. */
2609  }
2610 
2611  /* Inherit specially named variables from parent channel */
2615 
2616  ast_channel_appl_set(tc, "AppDial");
2617  ast_channel_data_set(tc, "(Outgoing Line)");
2618 
2619  memset(ast_channel_whentohangup(tc), 0, sizeof(*ast_channel_whentohangup(tc)));
2620 
2621  /* Determine CallerID to store in outgoing channel. */
2623  if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
2624  caller.id = stored_clid;
2625  ast_channel_set_caller_event(tc, &caller, NULL);
2627  } else if (ast_strlen_zero(S_COR(ast_channel_caller(tc)->id.number.valid,
2628  ast_channel_caller(tc)->id.number.str, NULL))) {
2629  /*
2630  * The new channel has no preset CallerID number by the channel
2631  * driver. Use the dialplan extension and hint name.
2632  */
2633  caller.id = stored_clid;
2634  if (!caller.id.name.valid
2635  && !ast_strlen_zero(S_COR(ast_channel_connected(chan)->id.name.valid,
2636  ast_channel_connected(chan)->id.name.str, NULL))) {
2637  /*
2638  * No hint name available. We have a connected name supplied by
2639  * the dialplan we can use instead.
2640  */
2641  caller.id.name.valid = 1;
2642  caller.id.name = ast_channel_connected(chan)->id.name;
2643  }
2644  ast_channel_set_caller_event(tc, &caller, NULL);
2646  } else if (ast_strlen_zero(S_COR(ast_channel_caller(tc)->id.name.valid, ast_channel_caller(tc)->id.name.str,
2647  NULL))) {
2648  /* The new channel has no preset CallerID name by the channel driver. */
2649  if (!ast_strlen_zero(S_COR(ast_channel_connected(chan)->id.name.valid,
2650  ast_channel_connected(chan)->id.name.str, NULL))) {
2651  /*
2652  * We have a connected name supplied by the dialplan we can
2653  * use instead.
2654  */
2655  caller.id.name.valid = 1;
2656  caller.id.name = ast_channel_connected(chan)->id.name;
2657  ast_channel_set_caller_event(tc, &caller, NULL);
2658  }
2659  }
2660 
2661  /* Determine CallerID for outgoing channel to send. */
2662  if (ast_test_flag64(peerflags, OPT_FORCECLID) && !force_forwards_only) {
2664 
2666  connected.id = forced_clid;
2668  } else {
2670  }
2671 
2673 
2675 
2678  ast_channel_musicclass_set(tc, ast_channel_musicclass(chan));
2679  }
2680 
2681  /* Pass ADSI CPE and transfer capability */
2684 
2685  /* If we have an outbound group, set this peer channel to it */
2686  if (outbound_group)
2687  ast_app_group_set_channel(tc, outbound_group);
2688  /* If the calling channel has the ANSWERED_ELSEWHERE flag set, inherit it. This is to support local channels */
2691 
2692  /* Check if we're forced by configuration */
2695 
2696 
2697  /* Inherit context and extension */
2698  ast_channel_dialcontext_set(tc, ast_strlen_zero(ast_channel_macrocontext(chan)) ? ast_channel_context(chan) : ast_channel_macrocontext(chan));
2701  else
2703 
2705 
2706  /* Save the original channel name to detect call pickup masquerading in. */
2708 
2709  ast_channel_unlock(tc);
2710  ast_channel_unlock(chan);
2711 
2712  /* Put channel in the list of outgoing thingies. */
2713  tmp->chan = tc;
2714  AST_LIST_INSERT_TAIL(&out_chans, tmp, node);
2715  }
2716 
2717  if (AST_LIST_EMPTY(&out_chans)) {
2718  ast_verb(3, "No devices or endpoints to dial (technology/resource)\n");
2719  if (continue_exec) {
2720  /* There is no point in having RetryDial try again */
2721  *continue_exec = 1;
2722  }
2723  strcpy(pa.status, "CHANUNAVAIL");
2724  res = 0;
2725  goto out;
2726  }
2727 
2728  /*
2729  * PREDIAL: Run gosub on all of the callee channels
2730  *
2731  * We run the callee predial before ast_call() in case the user
2732  * wishes to do something on the newly created channels before
2733  * the channel does anything important.
2734  *
2735  * Inside the target gosub we will be able to do something with
2736  * the newly created channel name ie: now the calling channel
2737  * can know what channel will be used to call the destination
2738  * ex: now we will know that SIP/abc-123 is calling SIP/def-124
2739  */
2742  && !AST_LIST_EMPTY(&out_chans)) {
2743  const char *predial_callee;
2744 
2745  ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLEE]);
2746  predial_callee = ast_app_expand_sub_args(chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
2747  if (predial_callee) {
2748  ast_autoservice_start(chan);
2749  AST_LIST_TRAVERSE(&out_chans, tmp, node) {
2750  ast_pre_call(tmp->chan, predial_callee);
2751  }
2752  ast_autoservice_stop(chan);
2753  ast_free((char *) predial_callee);
2754  }
2755  }
2756 
2757  /* Start all outgoing calls */
2758  AST_LIST_TRAVERSE_SAFE_BEGIN(&out_chans, tmp, node) {
2759  res = ast_call(tmp->chan, tmp->number, 0); /* Place the call, but don't wait on the answer */
2760  ast_channel_lock(chan);
2761 
2762  /* check the results of ast_call */
2763  if (res) {
2764  /* Again, keep going even if there's an error */
2765  ast_debug(1, "ast call on peer returned %d\n", res);
2766  ast_verb(3, "Couldn't call %s\n", tmp->interface);
2767  if (ast_channel_hangupcause(tmp->chan)) {
2769  }
2770  ast_channel_unlock(chan);
2771  ast_cc_call_failed(chan, tmp->chan, tmp->interface);
2772  ast_hangup(tmp->chan);
2773  tmp->chan = NULL;
2775  chanlist_free(tmp);
2776  continue;
2777  }
2778 
2779  ast_channel_publish_dial(chan, tmp->chan, tmp->number, NULL);
2780  ast_channel_unlock(chan);
2781 
2782  ast_verb(3, "Called %s\n", tmp->interface);
2784 
2785  /* If this line is up, don't try anybody else */
2786  if (ast_channel_state(tmp->chan) == AST_STATE_UP) {
2787  break;
2788  }
2789  }
2791 
2792  if (ast_strlen_zero(args.timeout)) {
2793  to = -1;
2794  } else {
2795  to = atoi(args.timeout);
2796  if (to > 0)
2797  to *= 1000;
2798  else {
2799  ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
2800  to = -1;
2801  }
2802  }
2803 
2804  outgoing = AST_LIST_FIRST(&out_chans);
2805  if (!outgoing) {
2806  strcpy(pa.status, "CHANUNAVAIL");
2807  if (fulldial == num_dialed) {
2808  res = -1;
2809  goto out;
2810  }
2811  } else {
2812  /* Our status will at least be NOANSWER */
2813  strcpy(pa.status, "NOANSWER");
2814  if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
2815  moh = 1;
2816  if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
2817  char *original_moh = ast_strdupa(ast_channel_musicclass(chan));
2818  ast_channel_musicclass_set(chan, opt_args[OPT_ARG_MUSICBACK]);
2819  ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
2820  ast_channel_musicclass_set(chan, original_moh);
2821  } else {
2822  ast_moh_start(chan, NULL, NULL);
2823  }
2825  } else if (ast_test_flag64(outgoing, OPT_RINGBACK) || ast_test_flag64(outgoing, OPT_RING_WITH_EARLY_MEDIA)) {
2826  if (!ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
2827  if (dial_handle_playtones(chan, opt_args[OPT_ARG_RINGBACK])){
2829  sentringing++;
2830  } else {
2832  }
2833  } else {
2835  sentringing++;
2836  }
2837  }
2838  }
2839 
2840  peer = wait_for_answer(chan, &out_chans, &to, peerflags, opt_args, &pa, &num, &result,
2841  dtmf_progress, ignore_cc, &forced_clid, &stored_clid);
2842 
2843  if (!peer) {
2844  if (result) {
2845  res = result;
2846  } else if (to) { /* Musta gotten hung up */
2847  res = -1;
2848  } else { /* Nobody answered, next please? */
2849  res = 0;
2850  }
2851  } else {
2852  const char *number;
2853  const char *name;
2854  int dial_end_raised = 0;
2855  int cause = -1;
2856 
2857  if (ast_test_flag64(&opts, OPT_CALLER_ANSWER)) {
2858  ast_answer(chan);
2859  }
2860 
2861  /* Ah ha! Someone answered within the desired timeframe. Of course after this
2862  we will always return with -1 so that it is hung up properly after the
2863  conversation. */
2864 
2865  if (ast_test_flag64(&opts, OPT_HANGUPCAUSE)
2866  && !ast_strlen_zero(opt_args[OPT_ARG_HANGUPCAUSE])) {
2867  cause = ast_str2cause(opt_args[OPT_ARG_HANGUPCAUSE]);
2868  if (cause <= 0) {
2869  if (!strcasecmp(opt_args[OPT_ARG_HANGUPCAUSE], "NONE")) {
2870  cause = 0;
2871  } else if (sscanf(opt_args[OPT_ARG_HANGUPCAUSE], "%30d", &cause) != 1
2872  || cause < 0) {
2873  ast_log(LOG_WARNING, "Invalid cause given to Dial(...Q(<cause>)): \"%s\"\n",
2874  opt_args[OPT_ARG_HANGUPCAUSE]);
2875  cause = -1;
2876  }
2877  }
2878  }
2879  hanguptree(&out_chans, peer, cause >= 0 ? cause : AST_CAUSE_ANSWERED_ELSEWHERE);
2880 
2881  /* If appropriate, log that we have a destination channel and set the answer time */
2882 
2883  ast_channel_lock(peer);
2884  name = ast_strdupa(ast_channel_name(peer));
2885 
2886  number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
2887  if (ast_strlen_zero(number)) {
2888  number = NULL;
2889  } else {
2890  number = ast_strdupa(number);
2891  }
2892  ast_channel_unlock(peer);
2893 
2894  ast_channel_lock(chan);
2896 
2897  strcpy(pa.status, "ANSWER");
2898  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2899 
2900  pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", name);
2901  pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
2902 
2904  ast_channel_unlock(chan);
2905 
2906  if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
2907  ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
2908  ast_channel_sendurl( peer, args.url );
2909  }
2911  if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
2912  ast_channel_publish_dial(chan, peer, NULL, pa.status);
2913  /* hang up on the callee -- he didn't want to talk anyway! */
2915  res = 0;
2916  goto out;
2917  }
2918  }
2919  if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
2920  res = 0;
2921  } else {
2922  int digit = 0;
2923  struct ast_channel *chans[2];
2924  struct ast_channel *active_chan;
2925 
2926  chans[0] = chan;
2927  chans[1] = peer;
2928 
2929  /* we need to stream the announcement to the called party when the OPT_ARG_ANNOUNCE (-A) is setted */
2930 
2931  /* stream the file */
2932  res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], ast_channel_language(peer));
2933  if (res) {
2934  res = 0;
2935  ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]);
2936  }
2937 
2939  while (ast_channel_stream(peer)) {
2940  int ms;
2941 
2942  ms = ast_sched_wait(ast_channel_sched(peer));
2943 
2944  if (ms < 0 && !ast_channel_timingfunc(peer)) {
2945  ast_stopstream(peer);
2946  break;
2947  }
2948  if (ms < 0)
2949  ms = 1000;
2950 
2951  active_chan = ast_waitfor_n(chans, 2, &ms);
2952  if (active_chan) {
2953  struct ast_channel *other_chan;
2954  struct ast_frame *fr = ast_read(active_chan);
2955 
2956  if (!fr) {
2958  res = -1;
2959  goto done;
2960  }
2961  switch (fr->frametype) {
2962  case AST_FRAME_DTMF_END:
2963  digit = fr->subclass.integer;
2964  if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
2965  ast_stopstream(peer);
2966  res = ast_senddigit(chan, digit, 0);
2967  }
2968  break;
2969  case AST_FRAME_CONTROL:
2970  switch (fr->subclass.integer) {
2971  case AST_CONTROL_HANGUP:
2972  ast_frfree(fr);
2974  res = -1;
2975  goto done;
2977  /* Pass COLP update to the other channel. */
2978  if (active_chan == chan) {
2979  other_chan = peer;
2980  } else {
2981  other_chan = chan;
2982  }
2983  if (ast_channel_connected_line_sub(active_chan, other_chan, fr, 1)
2984  && ast_channel_connected_line_macro(active_chan,
2985  other_chan, fr, other_chan == chan, 1)) {
2986  ast_indicate_data(other_chan, fr->subclass.integer,
2987  fr->data.ptr, fr->datalen);
2988  }
2989  break;
2990  default:
2991  break;
2992  }
2993  break;
2994  default:
2995  /* Ignore all others */
2996  break;
2997  }
2998  ast_frfree(fr);
2999  }
3001  }
3003  }
3004 
3005  if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
3006  /* chan and peer are going into the PBX; as such neither are considered
3007  * outgoing channels any longer */
3009 
3010  ast_replace_subargument_delimiter(opt_args[OPT_ARG_GOTO]);
3011  ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
3012  /* peer goes to the same context and extension as chan, so just copy info from chan*/
3013  ast_channel_lock(peer);
3020  ast_channel_unlock(peer);
3021  if (ast_pbx_start(peer)) {
3023  }
3024  if (continue_exec)
3025  *continue_exec = 1;
3026  res = 0;
3027  ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
3028  goto done;
3029  }
3030 
3032  const char *macro_result_peer;
3033  int macro_res;
3034 
3035  /* Set peer->exten and peer->context so that MACRO_EXTEN and MACRO_CONTEXT get set */
3036  ast_channel_lock_both(chan, peer);
3039  ast_channel_unlock(peer);
3040  ast_channel_unlock(chan);
3041  ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
3042  macro_res = ast_app_exec_macro(chan, peer, opt_args[OPT_ARG_CALLEE_MACRO]);
3043 
3044  ast_channel_lock(peer);
3045 
3046  if (!macro_res && (macro_result_peer = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
3047  char *macro_result = ast_strdupa(macro_result_peer);
3048  char *macro_transfer_dest;
3049 
3050  ast_channel_unlock(peer);
3051 
3052  if (!strcasecmp(macro_result, "BUSY")) {
3053  ast_copy_string(pa.status, macro_result, sizeof(pa.status));
3054  ast_set_flag64(peerflags, OPT_GO_ON);
3055  macro_res = -1;
3056  } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
3057  ast_copy_string(pa.status, macro_result, sizeof(pa.status));
3058  ast_set_flag64(peerflags, OPT_GO_ON);
3059  macro_res = -1;
3060  } else if (!strcasecmp(macro_result, "CONTINUE")) {
3061  /* hangup peer and keep chan alive assuming the macro has changed
3062  the context / exten / priority or perhaps
3063  the next priority in the current exten is desired.
3064  */
3065  ast_set_flag64(peerflags, OPT_GO_ON);
3066  macro_res = -1;
3067  } else if (!strcasecmp(macro_result, "ABORT")) {
3068  /* Hangup both ends unless the caller has the g flag */
3069  macro_res = -1;
3070  } else if (!strncasecmp(macro_result, "GOTO:", 5)) {
3071  macro_transfer_dest = macro_result + 5;
3072  macro_res = -1;
3073  /* perform a transfer to a new extension */
3074  if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
3075  ast_replace_subargument_delimiter(macro_transfer_dest);
3076  }
3077  if (!ast_parseable_goto(chan, macro_transfer_dest)) {
3078  ast_set_flag64(peerflags, OPT_GO_ON);
3079  }
3080  }
3081  if (macro_res && !dial_end_raised) {
3082  ast_channel_publish_dial(chan, peer, NULL, macro_result);
3083  dial_end_raised = 1;
3084  }
3085  } else {
3086  ast_channel_unlock(peer);
3087  }
3088  res = macro_res;
3089  }
3090 
3092  const char *gosub_result_peer;
3093  char *gosub_argstart;
3094  char *gosub_args = NULL;
3095  int gosub_res = -1;
3096 
3097  ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
3098  gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
3099  if (gosub_argstart) {
3100  const char *what_is_s = "s";
3101  *gosub_argstart = 0;
3102  if (!ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
3103  ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
3104  what_is_s = "~~s~~";
3105  }
3106  if (ast_asprintf(&gosub_args, "%s,%s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s, gosub_argstart + 1) < 0) {
3107  gosub_args = NULL;
3108  }
3109  *gosub_argstart = ',';
3110  } else {
3111  const char *what_is_s = "s";
3112  if (!ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
3113  ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
3114  what_is_s = "~~s~~";
3115  }
3116  if (ast_asprintf(&gosub_args, "%s,%s,1", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s) < 0) {
3117  gosub_args = NULL;
3118  }
3119  }
3120  if (gosub_args) {
3121  gosub_res = ast_app_exec_sub(chan, peer, gosub_args, 0);
3122  ast_free(gosub_args);
3123  } else {
3124  ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
3125  }
3126 
3127  ast_channel_lock_both(chan, peer);
3128 
3129  if (!gosub_res && (gosub_result_peer = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
3130  char *gosub_transfer_dest;
3131  char *gosub_result = ast_strdupa(gosub_result_peer);
3132  const char *gosub_retval = pbx_builtin_getvar_helper(peer, "GOSUB_RETVAL");
3133 
3134  /* Inherit return value from the peer, so it can be used in the master */
3135  if (gosub_retval) {
3136  pbx_builtin_setvar_helper(chan, "GOSUB_RETVAL", gosub_retval);
3137  }
3138 
3139  ast_channel_unlock(peer);
3140  ast_channel_unlock(chan);
3141 
3142  if (!strcasecmp(gosub_result, "BUSY")) {
3143  ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
3144  ast_set_flag64(peerflags, OPT_GO_ON);
3145  gosub_res = -1;
3146  } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
3147  ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
3148  ast_set_flag64(peerflags, OPT_GO_ON);
3149  gosub_res = -1;
3150  } else if (!strcasecmp(gosub_result, "CONTINUE")) {
3151  /* Hangup peer and continue with the next extension priority. */
3152  ast_set_flag64(peerflags, OPT_GO_ON);
3153  gosub_res = -1;
3154  } else if (!strcasecmp(gosub_result, "ABORT")) {
3155  /* Hangup both ends unless the caller has the g flag */
3156  gosub_res = -1;
3157  } else if (!strncasecmp(gosub_result, "GOTO:", 5)) {
3158  gosub_transfer_dest = gosub_result + 5;
3159  gosub_res = -1;
3160  /* perform a transfer to a new extension */
3161  if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
3162  ast_replace_subargument_delimiter(gosub_transfer_dest);
3163  }
3164  if (!ast_parseable_goto(chan, gosub_transfer_dest)) {
3165  ast_set_flag64(peerflags, OPT_GO_ON);
3166  }
3167  }
3168  if (gosub_res) {
3169  res = gosub_res;
3170  if (!dial_end_raised) {
3171  ast_channel_publish_dial(chan, peer, NULL, gosub_result);
3172  dial_end_raised = 1;
3173  }
3174  }
3175  } else {
3176  ast_channel_unlock(peer);
3177  ast_channel_unlock(chan);
3178  }
3179  }
3180 
3181  if (!res) {
3182 
3183  /* None of the Dial options changed our status; inform
3184  * everyone that this channel answered
3185  */
3186  if (!dial_end_raised) {
3187  ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
3188  dial_end_raised = 1;
3189  }
3190 
3191  if (!ast_tvzero(calldurationlimit)) {
3192  struct timeval whentohangup = ast_tvadd(ast_tvnow(), calldurationlimit);
3193  ast_channel_lock(peer);
3194  ast_channel_whentohangup_set(peer, &whentohangup);
3195  ast_channel_unlock(peer);
3196  }
3197  if (!ast_strlen_zero(dtmfcalled)) {
3198  ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
3199  res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
3200  }
3201  if (!ast_strlen_zero(dtmfcalling)) {
3202  ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
3203  res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
3204  }
3205  }
3206 
3207  if (res) { /* some error */
3208  if (!ast_check_hangup(chan) && ast_check_hangup(peer)) {
3210  }
3211  setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3212  if (ast_bridge_setup_after_goto(peer)
3213  || ast_pbx_start(peer)) {
3215  }
3216  res = -1;
3217  } else {
3218  if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
3220  if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
3222  if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
3224  if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
3226  if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
3228  if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
3230  if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
3232  if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
3234  if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
3236  if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
3238 
3240  config.end_bridge_callback_data = chan;
3242 
3243  if (moh) {
3244  moh = 0;
3245  ast_moh_stop(chan);
3246  } else if (sentringing) {
3247  sentringing = 0;
3248  ast_indicate(chan, -1);
3249  }
3250  /* Be sure no generators are left on it and reset the visible indication */
3253  /* Make sure channels are compatible */
3254  res = ast_channel_make_compatible(chan, peer);
3255  if (res < 0) {
3256  ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", ast_channel_name(chan), ast_channel_name(peer));
3258  res = -1;
3259  goto done;
3260  }
3261  if (opermode) {
3262  struct oprmode oprmode;
3263 
3264  oprmode.peer = peer;
3265  oprmode.mode = opermode;
3266 
3268  }
3269  setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3270  res = ast_bridge_call(chan, peer, &config);
3271  }
3272  }
3273 out:
3274  if (moh) {
3275  moh = 0;
3276  ast_moh_stop(chan);
3277  } else if (sentringing) {
3278  sentringing = 0;
3279  ast_indicate(chan, -1);
3280  }
3281 
3282  if (delprivintro && ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3284  if (ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3285  ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
3286  } else {
3287  ast_verb(3, "Successfully deleted %s intro file\n", pa.privintro);
3288  }
3289  }
3290 
3292  /* forward 'answered elsewhere' if we received it */
3293  hanguptree(&out_chans, NULL,
3297  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
3298  ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
3299 
3300  if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
3301  if (!ast_tvzero(calldurationlimit))
3302  memset(ast_channel_whentohangup(chan), 0, sizeof(*ast_channel_whentohangup(chan)));
3303  res = 0;
3304  }
3305 
3306 done:
3307  if (config.warning_sound) {
3308  ast_free((char *)config.warning_sound);
3309  }
3310  if (config.end_sound) {
3311  ast_free((char *)config.end_sound);
3312  }
3313  if (config.start_sound) {
3314  ast_free((char *)config.start_sound);
3315  }
3316  ast_ignore_cc(chan);
3317  return res;
3318 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
Definition: main/app.c:904
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:3132
#define OPT_FORCE_CID_PRES
Definition: app_dial.c:708
int sentringing
Definition: app_dial.c:1138
int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
Bridge two channels together (early)
Definition: channel.c:7351
Information needed to identify an endpoint in a call.
Definition: channel.h:339
char digit
#define ast_channel_lock(chan)
Definition: channel.h:2837
Main Channel structure associated with a channel.
Definition: test_heap.c:38
int ast_max_forwards_get(struct ast_channel *chan)
Get the current max forwards for a particular channel.
Definition: max_forwards.c:121
#define OPT_RING_WITH_EARLY_MEDIA
Definition: app_dial.c:712
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
char stuff[0]
Definition: app_dial.c:813
char privintro[1024]
Definition: app_dial.c:1141
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame)
Run a connected line interception macro and update a channel&#39;s connected line information.
Definition: channel.c:10268
void ast_channel_visible_indication_set(struct ast_channel *chan, int value)
#define ast_copy_flags64(dest, src, flagz)
Definition: utils.h:141
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
Definition: channel.c:7311
void ast_channel_whentohangup_set(struct ast_channel *chan, struct timeval *value)
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
#define OPT_CANCEL_ELSEWHERE
Definition: app_dial.c:703
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
struct ast_flags features_callee
Definition: channel.h:1066
const char * tech
Definition: app_dial.c:801
char * config
Definition: conf2ael.c:66
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:755
struct ast_party_id id
Connected party ID.
Definition: channel.h:459
#define AST_DIGIT_ANY
Definition: file.h:48
const char * ast_app_expand_sub_args(struct ast_channel *chan, const char *args)
Add missing context/exten to subroutine argument string.
Definition: main/app.c:351
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation...
Definition: channel.c:2020
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4271
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define OPT_PREDIAL_CALLEE
Definition: app_dial.c:710
#define SCOPE_TRACE(__level,...)
Definition: logger.h:871
int ast_channel_supports_html(struct ast_channel *channel)
Checks for HTML support on a channel.
Definition: channel.c:6559
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:455
#define AST_OPTION_OPRMODE
#define LOG_WARNING
Definition: logger.h:274
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4703
static int timeout
Definition: cdr_mysql.c:86
static void end_bridge_callback(void *data)
Definition: app_dial.c:2133
static int tmp()
Definition: bt_open.c:389
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6421
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Definition: channel.c:11063
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4251
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4647
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:710
#define DIAL_STILLGOING
Definition: app_dial.c:700
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * args
#define NULL
Definition: resample.c:96
int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
Send a DTMF digit to a channel.
Definition: channel.c:4898
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
#define OPT_CANCEL_TIMEOUT
Definition: app_dial.c:706
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:7361
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7715
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
int ast_channel_priority(const struct ast_channel *chan)
#define ast_verb(level,...)
Definition: logger.h:455
static void handle_cause(int cause, struct cause_args *num)
Definition: app_dial.c:858
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
void ast_cc_call_failed(struct ast_channel *incoming, struct ast_channel *outgoing, const char *const dialstring)
Make CCBS available in the case that ast_call fails.
Definition: ccss.c:4199
#define CAN_EARLY_BRIDGE(flags, chan, peer)
Definition: app_dial.c:785
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
const char * start_sound
Definition: channel.h:1076
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
int done
Definition: test_amihooks.c:48
#define DIAL_CALLERID_ABSENT
Definition: app_dial.c:702
Number structure.
Definition: app_followme.c:154
const struct ast_channel_tech * tech
union ast_frame::@255 data
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2348
static int setup_privacy_args(struct privacy_args *pa, struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
returns 1 if successful, 0 or <0 if the caller should &#39;goto out&#39;
Definition: app_dial.c:2032
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
void ast_replace_subargument_delimiter(char *s)
Replace &#39;^&#39; in a string with &#39;,&#39;.
Definition: main/utils.c:1966
#define ast_log
Definition: astobj2.c:42
void ast_cc_extension_monitor_add_dialstring(struct ast_channel *incoming, const char *const dialstring, const char *const device_name)
Add a child dialstring to an extension monitor.
Definition: ccss.c:2005
const char * interface
Definition: app_dial.c:799
static const char * get_cid_name(char *name, int namelen, struct ast_channel *chan)
Definition: app_dial.c:899
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Definition: channel.c:6656
struct ast_channel * chan
Definition: app_dial.c:797
#define OPT_PREDIAL_CALLER
Definition: app_dial.c:711
#define OPT_HANGUPCAUSE
Definition: app_dial.c:713
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
#define OPT_FORCE_CID_TAG
Definition: app_dial.c:707
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:113
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8840
#define AST_MAX_EXTENSION
Definition: channel.h:135
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
bridge configuration
Definition: channel.h:1064
void * end_bridge_callback_data
Definition: channel.h:1079
Caller Party information.
Definition: channel.h:419
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
const char * end_sound
Definition: channel.h:1075
static int dial_handle_playtones(struct ast_channel *chan, const char *data)
Definition: app_dial.c:2149
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
void(* end_bridge_callback_data_fixup)(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
Definition: channel.h:1083
int ast_cdr_reset(const char *channel_name, int keep_variables)
Reset the detail record.
Definition: cdr.c:3598
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
List of channel drivers.
Definition: app_dial.c:795
struct ast_channel * ast_request_with_stream_topology(const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel (specifying stream topology)
Definition: channel.c:6317
#define DIAL_NOFORWARDHTML
Definition: app_dial.c:701
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:4170
int ast_app_exec_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_args)
Run a macro on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:273
int ast_pre_call(struct ast_channel *chan, const char *sub_args)
Execute a Gosub call on the channel before a call is placed.
Definition: channel.c:6404
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
Definition: channel.c:6394
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
const char * ast_channel_exten(const struct ast_channel *chan)
int ast_parse_caller_presentation(const char *data)
Convert caller ID text code to value (used in config file parsing)
Definition: callerid.c:1143
int ast_app_parse_options64(const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:2834
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:441
struct ast_party_connected_line connected
Definition: app_dial.c:808
struct ast_flags features_caller
Definition: channel.h:1065
int ast_cc_callback(struct ast_channel *inbound, const char *const tech, const char *const dest, ast_cc_callback_fn callback)
Run a callback for potential matching destinations.
Definition: ccss.c:4244
uint64_t flags
Definition: utils.h:205
int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
Start the CC process on a call.
Definition: ccss.c:2409
#define AST_PBX_INCOMPLETE
Definition: pbx.h:51
static struct ast_channel * wait_for_answer(struct ast_channel *in, struct dial_head *out_chans, int *to, struct ast_flags64 *peerflags, char *opt_args[], struct privacy_args *pa, const struct cause_args *num_in, int *result, char *dtmf_progress, const int ignore_cc, struct ast_party_id *forced_clid, struct ast_party_id *stored_clid)
Definition: app_dial.c:1201
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
#define OPT_CALLER_ANSWER
Definition: app_dial.c:709
struct ast_sched_context * ast_channel_sched(const struct ast_channel *chan)
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
Definition: channel.c:1974
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
Definition: channel.c:11056
int privdb_val
Definition: app_dial.c:1139
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel&#39;s connected line information...
Definition: channel.c:10372
Channel datastore data for max forwards.
Definition: max_forwards.c:29
const char * number
Definition: app_dial.c:803
ast_channel_adsicpe
Definition: channel.h:856
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
Connected Line/Party information.
Definition: channel.h:457
void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
Initialize the given party id structure using the given guide for a set update operation.
Definition: channel.c:1755
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
struct ast_channel * chan
Definition: app_dial.c:852
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:7705
static void setup_peer_after_bridge_goto(struct ast_channel *chan, struct ast_channel *peer, struct ast_flags64 *opts, char *opt_args[])
Definition: app_dial.c:2191
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_strlen_zero(a)
Definition: muted.c:73
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:6571
#define ast_channel_unlock(chan)
Definition: channel.h:2838
const char * ast_cause2str(int state) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:608
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static const char name[]
Definition: cdr_mysql.c:74
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
Definition: channel.c:6705
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define AST_CHANNEL_NAME
Definition: channel.h:172
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2523
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
static const struct ast_app_option dial_exec_options[128]
Definition: app_dial.c:783
void ast_autoservice_chan_hangup_peer(struct ast_channel *chan, struct ast_channel *peer)
Put chan into autoservice while hanging up peer.
Definition: autoservice.c:342
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
Definition: channel.c:1732
#define ast_set2_flag64(p, value, flag)
Definition: utils.h:151
#define AST_PRIVACY_UNKNOWN
Definition: privacy.h:34
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
Definition: linkedlists.h:251
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct ast_channel * peer
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:662
void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
Callback made from ast_cc_callback for certain channel types.
Definition: ccss.c:4232
Definition: astman.c:88
void(* end_bridge_callback)(void *)
Definition: channel.h:1078
#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:332
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2844
void ast_ignore_cc(struct ast_channel *chan)
Mark the channel to ignore further CC activity.
Definition: ccss.c:3720
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:2868
int transit_network_select
Transit Network Select.
Definition: channel.h:398
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
Definition: channel.c:2006
char * strsep(char **str, const char *delims)
int ast_max_forwards_decrement(struct ast_channel *chan)
Decrement the max forwards count for a particular channel.
Definition: max_forwards.c:135
FILE * out
Definition: utils/frame.c:33
int ast_channel_hangupcause(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
static void chanlist_free(struct chanlist *outgoing)
Definition: app_dial.c:820
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8222
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
#define ast_frfree(fr)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2780
static PGresult * result
Definition: cel_pgsql.c:88
#define AST_CAUSE_BUSY
Definition: causes.h:148
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition: sched.c:431
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Definition: channel.c:10530
Data structure associated with a single frame of data.
int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
Run a subroutine on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:370
const char * ast_channel_language(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
enum ast_frame_type frametype
int ast_str2cause(const char *name) attribute_pure
Convert the string form of a cause code to a number.
Definition: channel.c:621
const char * warning_sound
Definition: channel.h:1074
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
Definition: app_dial.c:2145
char status[256]
Definition: app_dial.c:1142
static struct test_options options
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:738
const char * ast_channel_macrocontext(const struct ast_channel *chan)
static char url[512]
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c_dst, struct ast_channel *c_src)
Make two channels compatible for early bridging.
Definition: rtp_engine.c:2251
static void hanguptree(struct dial_head *out_chans, struct ast_channel *exception, int hangupcause)
Definition: app_dial.c:828
char connected
Definition: eagi_proxy.c:82
ast_timing_func_t ast_channel_timingfunc(const struct ast_channel *chan)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:447
void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Set the connected line information in the Asterisk channel.
Definition: channel.c:8237
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
const char * ast_channel_macroexten(const struct ast_channel *chan)
void ast_channel_data_set(struct ast_channel *chan, const char *value)
int ast_app_group_set_channel(struct ast_channel *chan, const char *data)
Set the group for a channel, splitting the provided data into group and category, if specified...
Definition: main/app.c:1959
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Definition: channel.c:2110
const char * ast_channel_musicclass(const struct ast_channel *chan)
#define AST_APP_ARG(name)
Define an application argument.
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1008
int ast_bridge_timelimit(struct ast_channel *chan, struct ast_bridge_config *config, char *parse, struct timeval *calldurationlimit)
parse L option and read associated channel variables to set warning, warning frequency, and timelimit
Definition: features.c:880
char * orig_chan_name
Definition: app_dial.c:805
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ dial_handle_playtones()

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

Definition at line 2149 of file app_dial.c.

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

Referenced by dial_exec_full().

2150 {
2151  struct ast_tone_zone_sound *ts = NULL;
2152  int res;
2153  const char *str = data;
2154 
2155  if (ast_strlen_zero(str)) {
2156  ast_debug(1,"Nothing to play\n");
2157  return -1;
2158  }
2159 
2160  ts = ast_get_indication_tone(ast_channel_zone(chan), str);
2161 
2162  if (ts && ts->data[0]) {
2163  res = ast_playtones_start(chan, 0, ts->data, 0);
2164  } else {
2165  res = -1;
2166  }
2167 
2168  if (ts) {
2169  ts = ast_tone_zone_sound_unref(ts);
2170  }
2171 
2172  if (res) {
2173  ast_log(LOG_WARNING, "Unable to start playtone \'%s\'\n", str);
2174  }
2175 
2176  return res;
2177 }
#define LOG_WARNING
Definition: logger.h:274
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
Definition: indications.h:227
Description of a tone.
Definition: indications.h:35
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Definition: indications.c:455
#define ast_strlen_zero(a)
Definition: muted.c:73
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302
const char * data
Description of a tone.
Definition: indications.h:52

◆ do_forward()

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

helper function for wait_for_answer()

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

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

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

Definition at line 929 of file app_dial.c.

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

Referenced by wait_for_answer().

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

◆ end_bridge_callback()

static void end_bridge_callback ( void *  data)
static

Definition at line 2133 of file app_dial.c.

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

Referenced by dial_exec_full().

2134 {
2135  struct ast_channel *chan = data;
2136 
2137  ast_channel_lock(chan);
2139  set_duration_var(chan, "ANSWEREDTIME", ast_channel_get_up_time_ms(chan));
2140  set_duration_var(chan, "DIALEDTIME", ast_channel_get_duration_ms(chan));
2142  ast_channel_unlock(chan);
2143 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
Main Channel structure associated with a channel.
int64_t ast_channel_get_duration_ms(struct ast_channel *chan)
Obtain how long it&#39;s been, in milliseconds, since the channel was created.
Definition: channel.c:2795
int64_t ast_channel_get_up_time_ms(struct ast_channel *chan)
Obtain how long it has been since the channel was answered in ms.
Definition: channel.c:2810
const char * data
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
#define ast_channel_unlock(chan)
Definition: channel.h:2838
static void set_duration_var(struct ast_channel *chan, const char *var_base, int64_t duration)
Definition: app_dial.c:1188

◆ end_bridge_callback_data_fixup()

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

Definition at line 2145 of file app_dial.c.

References ast_bridge_config::end_bridge_callback_data.

Referenced by dial_exec_full().

2145  {
2146  bconfig->end_bridge_callback_data = originator;
2147 }
void * end_bridge_callback_data
Definition: channel.h:1079

◆ get_cid_name()

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

Definition at line 899 of file app_dial.c.

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

Referenced by dial_exec_full().

900 {
901  const char *context;
902  const char *exten;
903 
904  ast_channel_lock(chan);
907  ast_channel_unlock(chan);
908 
909  return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
910 }
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:4132
#define ast_channel_lock(chan)
Definition: channel.h:2837
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define NULL
Definition: resample.c:96
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2838
static const char name[]
Definition: cdr_mysql.c:74
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_context(const struct ast_channel *chan)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
const char * ast_channel_macrocontext(const struct ast_channel *chan)
const char * ast_channel_macroexten(const struct ast_channel *chan)

◆ handle_cause()

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

Definition at line 858 of file app_dial.c.

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

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

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

◆ hanguptree()

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

Definition at line 828 of file app_dial.c.

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

Referenced by dial_exec_full().

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

◆ load_module()

static int load_module ( void  )
static

Definition at line 3447 of file app_dial.c.

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

3448 {
3449  int res;
3450 
3453 
3454  return res;
3455 }
static int retrydial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3329
static int dial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3320
static const char app[]
Definition: app_dial.c:662
static const char rapp[]
Definition: app_dial.c:663
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ onedigit_goto()

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

Definition at line 880 of file app_dial.c.

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

Referenced by retrydial_exec(), and wait_for_answer().

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

◆ publish_dial_end_event()

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

Definition at line 1145 of file app_dial.c.

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

Referenced by wait_for_answer().

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

◆ retrydial_exec()

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

Definition at line 3329 of file app_dial.c.

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

Referenced by load_module().

3330 {
3331  char *parse;
3332  const char *context = NULL;
3333  int sleepms = 0, loops = 0, res = -1;
3334  struct ast_flags64 peerflags = { 0, };
3336  AST_APP_ARG(announce);
3337  AST_APP_ARG(sleep);
3338  AST_APP_ARG(retries);
3339  AST_APP_ARG(dialdata);
3340  );
3341 
3342  if (ast_strlen_zero(data)) {
3343  ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
3344  return -1;
3345  }
3346 
3347  parse = ast_strdupa(data);
3348  AST_STANDARD_APP_ARGS(args, parse);
3349 
3350  if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
3351  sleepms *= 1000;
3352 
3353  if (!ast_strlen_zero(args.retries)) {
3354  loops = atoi(args.retries);
3355  }
3356 
3357  if (!args.dialdata) {
3358  ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
3359  goto done;
3360  }
3361 
3362  if (sleepms < 1000)
3363  sleepms = 10000;
3364 
3365  if (!loops)
3366  loops = -1; /* run forever */
3367 
3368  ast_channel_lock(chan);
3369  context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
3370  context = !ast_strlen_zero(context) ? ast_strdupa(context) : NULL;
3371  ast_channel_unlock(chan);
3372 
3373  res = 0;
3374  while (loops) {
3375  int continue_exec;
3376 
3377  ast_channel_data_set(chan, "Retrying");
3379  ast_moh_stop(chan);
3380 
3381  res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
3382  if (continue_exec)
3383  break;
3384 
3385  if (res == 0) {
3386  if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
3387  if (!ast_strlen_zero(args.announce)) {
3388  if (ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3389  if (!(res = ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3391  } else
3392  ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3393  }
3394  if (!res && sleepms) {
3396  ast_moh_start(chan, NULL, NULL);
3397  res = ast_waitfordigit(chan, sleepms);
3398  }
3399  } else {
3400  if (!ast_strlen_zero(args.announce)) {
3401  if (ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3402  if (!(res = ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3403  res = ast_waitstream(chan, "");
3404  } else
3405  ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3406  }
3407  if (sleepms) {
3409  ast_moh_start(chan, NULL, NULL);
3410  if (!res)
3411  res = ast_waitfordigit(chan, sleepms);
3412  }
3413  }
3414  }
3415 
3416  if (res < 0 || res == AST_PBX_INCOMPLETE) {
3417  break;
3418  } else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
3419  if (onedigit_goto(chan, context, (char) res, 1)) {
3420  res = 0;
3421  break;
3422  }
3423  }
3424  loops--;
3425  }
3426  if (loops == 0)
3427  res = 0;
3428  else if (res == 1)
3429  res = 0;
3430 
3432  ast_moh_stop(chan);
3433  done:
3434  return res;
3435 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
Definition: app_dial.c:880
#define AST_DIGIT_ANY
Definition: file.h:48
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define NULL
Definition: resample.c:96
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7715
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int done
Definition: test_amihooks.c:48
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define AST_PBX_INCOMPLETE
Definition: pbx.h:51
#define LOG_ERROR
Definition: logger.h:285
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7705
#define ast_strlen_zero(a)
Definition: muted.c:73
#define ast_channel_unlock(chan)
Definition: channel.h:2838
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3150
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1775
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
static const char rapp[]
Definition: app_dial.c:663
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
Definition: app_dial.c:2213
const char * ast_channel_language(const struct ast_channel *chan)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
void ast_channel_data_set(struct ast_channel *chan, const char *value)
#define AST_APP_ARG(name)
Define an application argument.
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ set_duration_var()

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

Definition at line 1188 of file app_dial.c.

References buf, and pbx_builtin_setvar_helper().

Referenced by end_bridge_callback(), and wait_for_answer().

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

◆ setup_peer_after_bridge_goto()

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

Definition at line 2191 of file app_dial.c.

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

Referenced by dial_exec_full().

2192 {
2193  const char *context;
2194  const char *extension;
2195  int priority;
2196 
2197  if (ast_test_flag64(opts, OPT_PEER_H)) {
2198  ast_channel_lock(chan);
2199  context = ast_strdupa(ast_channel_context(chan));
2200  ast_channel_unlock(chan);
2201  ast_bridge_set_after_h(peer, context);
2202  } else if (ast_test_flag64(opts, OPT_CALLEE_GO_ON)) {
2203  ast_channel_lock(chan);
2204  context = ast_strdupa(ast_channel_context(chan));
2205  extension = ast_strdupa(ast_channel_exten(chan));
2206  priority = ast_channel_priority(chan);
2207  ast_channel_unlock(chan);
2208  ast_bridge_set_after_go_on(peer, context, extension, priority,
2209  opt_args[OPT_ARG_CALLEE_GO_ON]);
2210  }
2211 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
#define OPT_CALLEE_GO_ON
Definition: app_dial.c:705
static int priority
int ast_channel_priority(const struct ast_channel *chan)
void ast_bridge_set_after_h(struct ast_channel *chan, const char *context)
Set channel to run the h exten after the bridge.
Definition: bridge_after.c:631
structure to hold extensions
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define OPT_PEER_H
Definition: app_dial.c:704
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2838
const char * ast_channel_context(const struct ast_channel *chan)
void ast_bridge_set_after_go_on(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *parseable_goto)
Set channel to go on in the dialplan after the bridge.
Definition: bridge_after.c:636
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ setup_privacy_args()

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

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

Definition at line 2032 of file app_dial.c.

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

Referenced by dial_exec_full().

2034 {
2035  char callerid[60];
2036  int res;
2037  char *l;
2038 
2039  if (ast_channel_caller(chan)->id.number.valid
2040  && !ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
2041  l = ast_strdupa(ast_channel_caller(chan)->id.number.str);
2043  if (ast_test_flag64(opts, OPT_PRIVACY) ) {
2044  ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
2045  pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
2046  } else {
2047  ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
2049  }
2050  } else {
2051  char *tnam, *tn2;
2052 
2053  tnam = ast_strdupa(ast_channel_name(chan));
2054  /* clean the channel name so slashes don't try to end up in disk file name */
2055  for (tn2 = tnam; *tn2; tn2++) {
2056  if (*tn2 == '/') /* any other chars to be afraid of? */
2057  *tn2 = '=';
2058  }
2059  ast_verb(3, "Privacy-- callerid is empty\n");
2060 
2061  snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", ast_channel_exten(chan), tnam);
2062  l = callerid;
2064  }
2065 
2066  ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
2067 
2068  if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
2069  /* if callerid is set and OPT_SCREEN_NOCALLERID is set also */
2070  ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
2072  } else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
2073  ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
2074  }
2075 
2076  if (pa->privdb_val == AST_PRIVACY_DENY) {
2077  ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
2078  ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
2079  return 0;
2080  } else if (pa->privdb_val == AST_PRIVACY_KILL) {
2081  ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
2082  return 0; /* Is this right? */
2083  } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
2084  ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
2085  return 0; /* is this right??? */
2086  } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
2087  /* Get the user's intro, store it in priv-callerintros/$CID,
2088  unless it is already there-- this should be done before the
2089  call is actually dialed */
2090 
2091  /* make sure the priv-callerintros dir actually exists */
2092  snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
2093  if ((res = ast_mkdir(pa->privintro, 0755))) {
2094  ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
2095  return -1;
2096  }
2097 
2098  snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
2099  if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
2100  /* the DELUX version of this code would allow this caller the
2101  option to hear and retape their previously recorded intro.
2102  */
2103  } else {
2104  int duration; /* for feedback from play_and_wait */
2105  /* the file doesn't exist yet. Let the caller submit his
2106  vocal intro for posterity */
2107  /* priv-recordintro script:
2108 
2109  "At the tone, please say your name:"
2110 
2111  */
2113  ast_answer(chan);
2114  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 */
2115  /* don't think we'll need a lock removed, we took care of
2116  conflicts by naming the pa.privintro file */
2117  if (res == -1) {
2118  /* Delete the file regardless since they hung up during recording */
2120  if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
2121  ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
2122  else
2123  ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
2124  return -1;
2125  }
2126  if (!ast_streamfile(chan, "vm-dialout", ast_channel_language(chan)) )
2127  ast_waitstream(chan, "");
2128  }
2129  }
2130  return 1; /* success */
2131 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define AST_PRIVACY_ALLOW
Definition: privacy.h:31
char privintro[1024]
Definition: app_dial.c:1141
char privcid[256]
Definition: app_dial.c:1140
int ast_privacy_check(char *dest, char *cid)
Definition: privacy.c:46
#define LOG_WARNING
Definition: logger.h:274
#define AST_PRIVACY_TORTURE
Definition: privacy.h:33
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
#define ast_verb(level,...)
Definition: logger.h:455
Number structure.
Definition: app_followme.c:154
#define ast_log
Definition: astobj2.c:42
#define AST_PRIVACY_KILL
Definition: privacy.h:32
static int silencethreshold
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_channel_exten(const struct ast_channel *chan)
const char * ast_config_AST_DATA_DIR
Definition: options.c:155
int privdb_val
Definition: app_dial.c:1139
int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path)
Record a file based on input from a channel. Use default accept and cancel DTMF. This function will p...
Definition: main/app.c:1920
#define LOG_NOTICE
Definition: logger.h:263
#define ast_strlen_zero(a)
Definition: muted.c:73
#define AST_PRIVACY_UNKNOWN
Definition: privacy.h:34
#define AST_PRIVACY_DENY
Definition: privacy.h:30
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1775
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2780
const char * ast_channel_language(const struct ast_channel *chan)
char status[256]
Definition: app_dial.c:1142
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:947
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1959
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: main/utils.c:2102
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 3437 of file app_dial.c.

References app, ast_unregister_application(), and rapp.

Referenced by load_module().

3438 {
3439  int res;
3440 
3443 
3444  return res;
3445 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static const char app[]
Definition: app_dial.c:662
static const char rapp[]
Definition: app_dial.c:663

◆ update_connected_line_from_peer()

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

Definition at line 1167 of file app_dial.c.

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

Referenced by wait_for_answer().

1168 {
1169  struct ast_party_connected_line connected_caller;
1170 
1171  ast_party_connected_line_init(&connected_caller);
1172 
1173  ast_channel_lock(peer);
1174  ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(peer));
1175  ast_channel_unlock(peer);
1176  connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1177  if (ast_channel_connected_line_sub(peer, chan, &connected_caller, 0)
1178  && ast_channel_connected_line_macro(peer, chan, &connected_caller, is_caller, 0)) {
1179  ast_channel_update_connected_line(chan, &connected_caller, NULL);
1180  }
1181  ast_party_connected_line_free(&connected_caller);
1182 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:1997
#define ast_channel_lock(chan)
Definition: channel.h:2837
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame)
Run a connected line interception macro and update a channel&#39;s connected line information.
Definition: channel.c:10268
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:9022
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2047
#define NULL
Definition: resample.c:96
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel&#39;s connected line information...
Definition: channel.c:10372
Connected Line/Party information.
Definition: channel.h:457
#define ast_channel_unlock(chan)
Definition: channel.h:2838
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:8222

◆ valid_priv_reply()

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

◆ wait_for_answer()

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

Definition at line 1201 of file app_dial.c.

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

Referenced by dial_exec_full().

1208 {
1209  struct cause_args num = *num_in;
1210  int prestart = num.busy + num.congestion + num.nochan;
1211  int orig = *to;
1212  struct ast_channel *peer = NULL;
1213  struct chanlist *outgoing = AST_LIST_FIRST(out_chans);
1214  /* single is set if only one destination is enabled */
1215  int single = outgoing && !AST_LIST_NEXT(outgoing, node);
1216  int caller_entertained = outgoing
1217  && ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
1218  struct ast_str *featurecode = ast_str_alloca(AST_FEATURE_MAX_LEN + 1);
1219  int cc_recall_core_id;
1220  int is_cc_recall;
1221  int cc_frame_received = 0;
1222  int num_ringing = 0;
1223  int sent_ring = 0;
1224  int sent_progress = 0;
1225  struct timeval start = ast_tvnow();
1226  SCOPE_TRACE(1, "%s\n", ast_channel_name(in));
1227 
1228  if (single) {
1229  /* Turn off hold music, etc */
1230  if (!caller_entertained) {
1232  /* If we are calling a single channel, and not providing ringback or music, */
1233  /* then, make them compatible for in-band tone purpose */
1234  if (ast_channel_make_compatible(in, outgoing->chan) < 0) {
1235  /* If these channels can not be made compatible,
1236  * there is no point in continuing. The bridge
1237  * will just fail if it gets that far.
1238  */
1239  *to = -1;
1240  strcpy(pa->status, "CONGESTION");
1241  ast_channel_publish_dial(in, outgoing->chan, NULL, pa->status);
1242  return NULL;
1243  }
1244  }
1245 
1247  && !ast_test_flag64(outgoing, DIAL_CALLERID_ABSENT)) {
1248  update_connected_line_from_peer(in, outgoing->chan, 1);
1249  }
1250  }
1251 
1252  is_cc_recall = ast_cc_is_recall(in, &cc_recall_core_id, NULL);
1253 
1254  while ((*to = ast_remaining_ms(start, orig)) && !peer) {
1255  struct chanlist *o;
1256  int pos = 0; /* how many channels do we handle */
1257  int numlines = prestart;
1258  struct ast_channel *winner;
1259  struct ast_channel *watchers[AST_MAX_WATCHERS];
1260 
1261  watchers[pos++] = in;
1262  AST_LIST_TRAVERSE(out_chans, o, node) {
1263  /* Keep track of important channels */
1264  if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
1265  watchers[pos++] = o->chan;
1266  numlines++;
1267  }
1268  if (pos == 1) { /* only the input channel is available */
1269  if (numlines == (num.busy + num.congestion + num.nochan)) {
1270  ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1271  if (num.busy)
1272  strcpy(pa->status, "BUSY");
1273  else if (num.congestion)
1274  strcpy(pa->status, "CONGESTION");
1275  else if (num.nochan)
1276  strcpy(pa->status, "CHANUNAVAIL");
1277  } else {
1278  ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1279  }
1280  *to = 0;
1281  if (is_cc_recall) {
1282  ast_cc_failed(cc_recall_core_id, "Everyone is busy/congested for the recall. How sad");
1283  }
1284  return NULL;
1285  }
1286  winner = ast_waitfor_n(watchers, pos, to);
1287  AST_LIST_TRAVERSE(out_chans, o, node) {
1288  struct ast_frame *f;
1289  struct ast_channel *c = o->chan;
1290 
1291  if (c == NULL)
1292  continue;
1294  if (!peer) {
1295  ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1296  if (o->orig_chan_name
1297  && strcmp(o->orig_chan_name, ast_channel_name(c))) {
1298  /*
1299  * The channel name changed so we must generate COLP update.
1300  * Likely because a call pickup channel masqueraded in.
1301  */
1303  } else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1304  if (o->pending_connected_update) {
1305  if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
1306  ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
1308  }
1309  } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1311  }
1312  }
1313  if (o->aoc_s_rate_list) {
1314  size_t encoded_size;
1315  struct ast_aoc_encoded *encoded;
1316  if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1317  ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1318  ast_aoc_destroy_encoded(encoded);
1319  }
1320  }
1321  peer = c;
1322  publish_dial_end_event(in, out_chans, peer, "CANCEL");
1323  ast_copy_flags64(peerflags, o,
1330  ast_channel_dialcontext_set(c, "");
1331  ast_channel_exten_set(c, "");
1332  }
1333  continue;
1334  }
1335  if (c != winner)
1336  continue;
1337  /* here, o->chan == c == winner */
1339  pa->sentringing = 0;
1340  if (!ignore_cc && (f = ast_read(c))) {
1342  /* This channel is forwarding the call, and is capable of CC, so
1343  * be sure to add the new device interface to the list
1344  */
1346  }
1347  ast_frfree(f);
1348  }
1349 
1350  if (o->pending_connected_update) {
1351  /*
1352  * Re-seed the chanlist's connected line information with
1353  * previously acquired connected line info from the incoming
1354  * channel. The previously acquired connected line info could
1355  * have been set through the CONNECTED_LINE dialplan function.
1356  */
1357  o->pending_connected_update = 0;
1358  ast_channel_lock(in);
1360  ast_channel_unlock(in);
1361  }
1362 
1363  do_forward(o, &num, peerflags, single, caller_entertained, &orig,
1364  forced_clid, stored_clid);
1365 
1366  if (o->chan) {
1369  if (single
1373  }
1374  }
1375  continue;
1376  }
1377  f = ast_read(winner);
1378  if (!f) {
1381  ast_hangup(c);
1382  c = o->chan = NULL;
1385  continue;
1386  }
1387  switch (f->frametype) {
1388  case AST_FRAME_CONTROL:
1389  switch (f->subclass.integer) {
1390  case AST_CONTROL_ANSWER:
1391  /* This is our guy if someone answered. */
1392  if (!peer) {
1393  ast_trace(1, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1394  ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1395  if (o->orig_chan_name
1396  && strcmp(o->orig_chan_name, ast_channel_name(c))) {
1397  /*
1398  * The channel name changed so we must generate COLP update.
1399  * Likely because a call pickup channel masqueraded in.
1400  */
1402  } else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1403  if (o->pending_connected_update) {
1404  if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
1405  ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
1407  }
1408  } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1410  }
1411  }
1412  if (o->aoc_s_rate_list) {
1413  size_t encoded_size;
1414  struct ast_aoc_encoded *encoded;
1415  if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1416  ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1417  ast_aoc_destroy_encoded(encoded);
1418  }
1419  }
1420  peer = c;
1421  /* Inform everyone else that they've been canceled.
1422  * The dial end event for the peer will be sent out after
1423  * other Dial options have been handled.
1424  */
1425  publish_dial_end_event(in, out_chans, peer, "CANCEL");
1426  ast_copy_flags64(peerflags, o,
1433  ast_channel_dialcontext_set(c, "");
1434  ast_channel_exten_set(c, "");
1435  if (CAN_EARLY_BRIDGE(peerflags, in, peer)) {
1436  /* Setup early bridge if appropriate */
1437  ast_channel_early_bridge(in, peer);
1438  }
1439  }
1440  /* If call has been answered, then the eventual hangup is likely to be normal hangup */
1443  break;
1444  case AST_CONTROL_BUSY:
1445  ast_verb(3, "%s is busy\n", ast_channel_name(c));
1447  ast_channel_publish_dial(in, c, NULL, "BUSY");
1448  ast_hangup(c);
1449  c = o->chan = NULL;
1452  break;
1454  ast_verb(3, "%s is circuit-busy\n", ast_channel_name(c));
1456  ast_channel_publish_dial(in, c, NULL, "CONGESTION");
1457  ast_hangup(c);
1458  c = o->chan = NULL;
1461  break;
1462  case AST_CONTROL_RINGING:
1463  /* This is a tricky area to get right when using a native
1464  * CC agent. The reason is that we do the best we can to send only a
1465  * single ringing notification to the caller.
1466  *
1467  * Call completion complicates the logic used here. CCNR is typically
1468  * offered during a ringing message. Let's say that party A calls
1469  * parties B, C, and D. B and C do not support CC requests, but D
1470  * does. If we were to receive a ringing notification from B before
1471  * the others, then we would end up sending a ringing message to
1472  * A with no CCNR offer present.
1473  *
1474  * The approach that we have taken is that if we receive a ringing
1475  * response from a party and no CCNR offer is present, we need to
1476  * wait. Specifically, we need to wait until either a) a called party
1477  * offers CCNR in its ringing response or b) all called parties have
1478  * responded in some way to our call and none offers CCNR.
1479  *
1480  * The drawback to this is that if one of the parties has a delayed
1481  * response or, god forbid, one just plain doesn't respond to our
1482  * outgoing call, then this will result in a significant delay between
1483  * when the caller places the call and hears ringback.
1484  *
1485  * Note also that if CC is disabled for this call, then it is perfectly
1486  * fine for ringing frames to get sent through.
1487  */
1488  ++num_ringing;
1489  if (ignore_cc || cc_frame_received || num_ringing == numlines) {
1490  ast_verb(3, "%s is ringing\n", ast_channel_name(c));
1491  /* Setup early media if appropriate */
1492  if (single && !caller_entertained
1493  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1494  ast_channel_early_bridge(in, c);
1495  }
1496  if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK) && ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
1498  pa->sentringing++;
1499  }
1500  if (!sent_ring) {
1501  struct timeval now, then;
1502  int64_t diff;
1503 
1504  now = ast_tvnow();
1505 
1506  ast_channel_lock(in);
1508 
1509  then = ast_channel_creationtime(c);
1510  diff = ast_tvzero(then) ? 0 : ast_tvdiff_ms(now, then);
1511  set_duration_var(in, "RINGTIME", diff);
1512 
1514  ast_channel_unlock(in);
1515  sent_ring = 1;
1516  }
1517  }
1518  ast_channel_publish_dial(in, c, NULL, "RINGING");
1519  break;
1520  case AST_CONTROL_PROGRESS:
1521  ast_verb(3, "%s is making progress passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1522  /* Setup early media if appropriate */
1523  if (single && !caller_entertained
1524  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1525  ast_channel_early_bridge(in, c);
1526  }
1527  if (!ast_test_flag64(outgoing, OPT_RINGBACK)) {
1528  if (single || (!single && !pa->sentringing)) {
1530  }
1531  }
1532  if (!sent_progress) {
1533  struct timeval now, then;
1534  int64_t diff;
1535 
1536  now = ast_tvnow();
1537 
1538  ast_channel_lock(in);
1540 
1541  then = ast_channel_creationtime(c);
1542  diff = ast_tvzero(then) ? 0 : ast_tvdiff_ms(now, then);
1543  set_duration_var(in, "PROGRESSTIME", diff);
1544 
1546  ast_channel_unlock(in);
1547  sent_progress = 1;
1548  }
1549  if (!ast_strlen_zero(dtmf_progress)) {
1550  ast_verb(3,
1551  "Sending DTMF '%s' to the called party as result of receiving a PROGRESS message.\n",
1552  dtmf_progress);
1553  ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
1554  }
1555  ast_channel_publish_dial(in, c, NULL, "PROGRESS");
1556  break;
1557  case AST_CONTROL_VIDUPDATE:
1558  case AST_CONTROL_SRCUPDATE:
1559  case AST_CONTROL_SRCCHANGE:
1560  if (!single || caller_entertained) {
1561  break;
1562  }
1563  ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1565  ast_indicate(in, f->subclass.integer);
1566  break;
1569  ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(in));
1570  break;
1571  }
1572  if (!single) {
1574 
1575  ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n",
1581  o->pending_connected_update = 1;
1582  break;
1583  }
1584  if (ast_channel_connected_line_sub(c, in, f, 1) &&
1585  ast_channel_connected_line_macro(c, in, f, 1, 1)) {
1587  }
1588  break;
1589  case AST_CONTROL_AOC:
1590  {
1591  struct ast_aoc_decoded *decoded = ast_aoc_decode(f->data.ptr, f->datalen, o->chan);
1592  if (decoded && (ast_aoc_get_msg_type(decoded) == AST_AOC_S)) {
1594  o->aoc_s_rate_list = decoded;
1595  } else {
1596  ast_aoc_destroy_decoded(decoded);
1597  }
1598  }
1599  break;
1601  if (!single) {
1602  /*
1603  * Redirecting updates to the caller make sense only on single
1604  * calls.
1605  */
1606  break;
1607  }
1609  ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(in));
1610  break;
1611  }
1612  ast_verb(3, "%s redirecting info has changed, passing it to %s\n",
1614  if (ast_channel_redirecting_sub(c, in, f, 1) &&
1615  ast_channel_redirecting_macro(c, in, f, 1, 1)) {
1617  }
1618  pa->sentringing = 0;
1619  break;
1621  ast_verb(3, "%s is proceeding passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1622  if (single && !caller_entertained
1623  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1624  ast_channel_early_bridge(in, c);
1625  }
1626  if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1628  ast_channel_publish_dial(in, c, NULL, "PROCEEDING");
1629  break;
1630  case AST_CONTROL_HOLD:
1631  /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1632  ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(c));
1634  break;
1635  case AST_CONTROL_UNHOLD:
1636  /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1637  ast_verb(3, "Call on %s left from hold\n", ast_channel_name(c));
1639  break;
1640  case AST_CONTROL_OFFHOOK:
1641  case AST_CONTROL_FLASH:
1642  /* Ignore going off hook and flash */
1643  break;
1644  case AST_CONTROL_CC:
1645  if (!ignore_cc) {
1647  cc_frame_received = 1;
1648  }
1649  break;
1652  break;
1653  case -1:
1654  if (single && !caller_entertained) {
1655  ast_verb(3, "%s stopped sounds\n", ast_channel_name(c));
1656  ast_indicate(in, -1);
1657  pa->sentringing = 0;
1658  }
1659  break;
1660  default:
1661  ast_debug(1, "Dunno what to do with control type %d\n", f->subclass.integer);
1662  break;
1663  }
1664  break;
1665  case AST_FRAME_VIDEO:
1666  case AST_FRAME_VOICE:
1667  case AST_FRAME_IMAGE:
1668  if (caller_entertained) {
1669  break;
1670  }
1671  /* Fall through */
1672  case AST_FRAME_TEXT:
1673  if (single && ast_write(in, f)) {
1674  ast_log(LOG_WARNING, "Unable to write frametype: %u\n",
1675  f->frametype);
1676  }
1677  break;
1678  case AST_FRAME_HTML:
1679  if (single && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML)
1680  && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1681  ast_log(LOG_WARNING, "Unable to send URL\n");
1682  }
1683  break;
1684  default:
1685  break;
1686  }
1687  ast_frfree(f);
1688  } /* end for */
1689  if (winner == in) {
1690  struct ast_frame *f = ast_read(in);
1691 #if 0
1692  if (f && (f->frametype != AST_FRAME_VOICE))
1693  printf("Frame type: %d, %d\n", f->frametype, f->subclass);
1694  else if (!f || (f->frametype != AST_FRAME_VOICE))
1695  printf("Hangup received on %s\n", in->name);
1696 #endif
1697  if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP))) {
1698  /* Got hung up */
1699  *to = -1;
1700  strcpy(pa->status, "CANCEL");
1701  publish_dial_end_event(in, out_chans, NULL, pa->status);
1702  if (f) {
1703  if (f->data.uint32) {
1705  }
1706  ast_frfree(f);
1707  }
1708  if (is_cc_recall) {
1709  ast_cc_completed(in, "CC completed, although the caller hung up (cancelled)");
1710  }
1711  return NULL;
1712  }
1713 
1714  /* now f is guaranteed non-NULL */
1715  if (f->frametype == AST_FRAME_DTMF) {
1716  if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
1717  const char *context;
1718  ast_channel_lock(in);
1719  context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
1720  if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
1721  ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
1722  *to = 0;
1723  *result = f->subclass.integer;
1724  strcpy(pa->status, "CANCEL");
1725  publish_dial_end_event(in, out_chans, NULL, pa->status);
1726  ast_frfree(f);
1727  ast_channel_unlock(in);
1728  if (is_cc_recall) {
1729  ast_cc_completed(in, "CC completed, but the caller used DTMF to exit");
1730  }
1731  return NULL;
1732  }
1733  ast_channel_unlock(in);
1734  }
1735 
1736  if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
1737  detect_disconnect(in, f->subclass.integer, &featurecode)) {
1738  ast_verb(3, "User requested call disconnect.\n");
1739  *to = 0;
1740  strcpy(pa->status, "CANCEL");
1741  publish_dial_end_event(in, out_chans, NULL, pa->status);
1742  ast_frfree(f);
1743  if (is_cc_recall) {
1744  ast_cc_completed(in, "CC completed, but the caller hung up with DTMF");
1745  }
1746  return NULL;
1747  }
1748  }
1749 
1750  /* Send the frame from the in channel to all outgoing channels. */
1751  AST_LIST_TRAVERSE(out_chans, o, node) {
1752  if (!o->chan || !ast_test_flag64(o, DIAL_STILLGOING)) {
1753  /* This outgoing channel has died so don't send the frame to it. */
1754  continue;
1755  }
1756  switch (f->frametype) {
1757  case AST_FRAME_HTML:
1758  /* Forward HTML stuff */
1760  && ast_channel_sendhtml(o->chan, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1761  ast_log(LOG_WARNING, "Unable to send URL\n");
1762  }
1763  break;
1764  case AST_FRAME_VIDEO:
1765  case AST_FRAME_VOICE:
1766  case AST_FRAME_IMAGE:
1767  if (!single || caller_entertained) {
1768  /*
1769  * We are calling multiple parties or caller is being
1770  * entertained and has thus not been made compatible.
1771  * No need to check any other called parties.
1772  */
1773  goto skip_frame;
1774  }
1775  /* Fall through */
1776  case AST_FRAME_TEXT:
1777  case AST_FRAME_DTMF_BEGIN:
1778  case AST_FRAME_DTMF_END:
1779  if (ast_write(o->chan, f)) {
1780  ast_log(LOG_WARNING, "Unable to forward frametype: %u\n",
1781  f->frametype);
1782  }
1783  break;
1784  case AST_FRAME_CONTROL:
1785  switch (f->subclass.integer) {
1786  case AST_CONTROL_HOLD:
1787  ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(o->chan));
1789  break;
1790  case AST_CONTROL_UNHOLD:
1791  ast_verb(3, "Call on %s left from hold\n", ast_channel_name(o->chan));
1793  break;
1794  case AST_CONTROL_VIDUPDATE:
1795  case AST_CONTROL_SRCUPDATE:
1796  case AST_CONTROL_SRCCHANGE:
1797  if (!single || caller_entertained) {
1798  /*
1799  * We are calling multiple parties or caller is being
1800  * entertained and has thus not been made compatible.
1801  * No need to check any other called parties.
1802  */
1803  goto skip_frame;
1804  }
1805  ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1808  break;
1811  ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(o->chan));
1812  break;
1813  }
1814  if (ast_channel_connected_line_sub(in, o->chan, f, 1) &&
1815  ast_channel_connected_line_macro(in, o->chan, f, 0, 1)) {
1817  }
1818  break;
1821  ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(o->chan));
1822  break;
1823  }
1824  if (ast_channel_redirecting_sub(in, o->chan, f, 1) &&
1825  ast_channel_redirecting_macro(in, o->chan, f, 0, 1)) {
1827  }
1828  break;
1829  default:
1830  /* We are not going to do anything with this frame. */
1831  goto skip_frame;
1832  }
1833  break;
1834  default:
1835  /* We are not going to do anything with this frame. */
1836  goto skip_frame;
1837  }
1838  }
1839 skip_frame:;
1840  ast_frfree(f);
1841  }
1842  }
1843 
1844  if (!*to || ast_check_hangup(in)) {
1845  ast_verb(3, "Nobody picked up in %d ms\n", orig);
1846  publish_dial_end_event(in, out_chans, NULL, "NOANSWER");
1847  }
1848 
1849  if (is_cc_recall) {
1850  ast_cc_completed(in, "Recall completed!");
1851  }
1852  return peer;
1853 }
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
Definition: main/app.c:904
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:3132
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode)
Definition: app_dial.c:1855
int sentringing
Definition: app_dial.c:1138
int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
Bridge two channels together (early)
Definition: channel.c:7351
#define ast_channel_lock(chan)
Definition: channel.h:2837
Main Channel structure associated with a channel.
Definition: test_heap.c:38
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame)
Run a connected line interception macro and update a channel&#39;s connected line information.
Definition: channel.c:10268
#define ast_copy_flags64(dest, src, flagz)
Definition: utils.h:141
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
Definition: app_dial.c:880
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
Definition: ccss.c:3879
unsigned int pending_connected_update
Definition: app_dial.c:810
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:2020
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4271
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
#define ast_trace(__level,...)
Definition: logger.h:866
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define SCOPE_TRACE(__level,...)
Definition: logger.h:871
int congestion
Definition: app_dial.c:854
#define LOG_WARNING
Definition: logger.h:274
#define AST_MAX_WATCHERS
Definition: app_dial.c:846
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:9022
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4251
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4647
#define DIAL_STILLGOING
Definition: app_dial.c:700
const char * ast_hangup_cause_to_dial_status(int hangup_cause)
Convert a hangup cause to a publishable dial status.
Definition: dial.c:753
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
static struct test_val c
#define ast_str_alloca(init_len)
Definition: strings.h:800
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2047
#define NULL
Definition: resample.c:96
#define AST_FRAME_DTMF
const char * ast_channel_call_forward(const struct ast_channel *chan)
#define ast_verb(level,...)
Definition: logger.h:455
int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char *const monitor_type)
Decide if a call to a particular channel is a CC recall.
Definition: ccss.c:3438
void ast_handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
Properly react to a CC control frame.
Definition: ccss.c:2316
static void handle_cause(int cause, struct cause_args *num)
Definition: app_dial.c:858
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
#define CAN_EARLY_BRIDGE(flags, chan, peer)
Definition: app_dial.c:785
int ast_cc_completed(struct ast_channel *chan, const char *const debug,...)
Indicate recall has been acknowledged.
Definition: ccss.c:3842
#define DIAL_CALLERID_ABSENT
Definition: app_dial.c:702
union ast_frame::@255 data
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Definition: channel.c:6656
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
Definition: aoc.c:449
FILE * in
Definition: utils/frame.c:33
struct ast_channel * chan
Definition: app_dial.c:797
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
Definition: aoc.c:650
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
Run a redirecting interception subroutine and update a channel&#39;s redirecting information.
Definition: channel.c:10417
List of channel drivers.
Definition: app_dial.c:795
#define DIAL_NOFORWARDHTML
Definition: app_dial.c:701
int nochan
Definition: app_dial.c:855