Asterisk - The Open Source Telephony Project  GIT-master-b91fb3c
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, struct ast_bridge_config *config)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Dialing Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "ccss", }
 
static const char app [] = "Dial"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const struct ast_app_option dial_exec_options [128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'a' ] = { .flag = (1LLU << 40) }, [ 'b' ] = { .flag = (1LLU << 41) , .arg_index = OPT_ARG_PREDIAL_CALLEE + 1 }, [ 'B' ] = { .flag = (1LLU << 42) , .arg_index = OPT_ARG_PREDIAL_CALLER + 1 }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'c' ] = { .flag = (1LLU << 34) }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'e' ] = { .flag = (1LLU << 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 3492 of file app_dial.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3492 of file app_dial.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 3492 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:2058
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 1872 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().

1873 {
1874  char disconnect_code[AST_FEATURE_MAX_LEN];
1875  int res;
1876 
1877  ast_str_append(featurecode, 1, "%c", code);
1878 
1879  res = ast_get_builtin_feature(chan, "disconnect", disconnect_code, sizeof(disconnect_code));
1880  if (res) {
1881  ast_str_reset(*featurecode);
1882  return 0;
1883  }
1884 
1885  if (strlen(disconnect_code) > ast_str_strlen(*featurecode)) {
1886  /* Could be a partial match, anyway */
1887  if (strncmp(disconnect_code, ast_str_buffer(*featurecode), ast_str_strlen(*featurecode))) {
1888  ast_str_reset(*featurecode);
1889  }
1890  return 0;
1891  }
1892 
1893  if (strcmp(disconnect_code, ast_str_buffer(*featurecode))) {
1894  ast_str_reset(*featurecode);
1895  return 0;
1896  }
1897 
1898  return 1;
1899 }
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 3350 of file app_dial.c.

References dial_exec_full(), and NULL.

Referenced by load_module().

3351 {
3352  struct ast_flags64 peerflags;
3353 
3354  memset(&peerflags, 0, sizeof(peerflags));
3355 
3356  return dial_exec_full(chan, data, &peerflags, NULL);
3357 }
#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:2230

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

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

Referenced by dial_exec(), and retrydial_exec().

2231 {
2232  int res = -1; /* default: error */
2233  char *rest, *cur; /* scan the list of destinations */
2234  struct dial_head out_chans = AST_LIST_HEAD_NOLOCK_INIT_VALUE; /* list of destinations */
2235  struct chanlist *outgoing;
2236  struct chanlist *tmp;
2237  struct ast_channel *peer = NULL;
2238  int to; /* timeout */
2239  struct cause_args num = { chan, 0, 0, 0 };
2240  int cause;
2241 
2242  struct ast_bridge_config config = { { 0, } };
2243  struct timeval calldurationlimit = { 0, };
2244  char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress=NULL;
2245  struct privacy_args pa = {
2246  .sentringing = 0,
2247  .privdb_val = 0,
2248  .status = "INVALIDARGS",
2249  };
2250  int sentringing = 0, moh = 0;
2251  const char *outbound_group = NULL;
2252  int result = 0;
2253  char *parse;
2254  int opermode = 0;
2255  int delprivintro = 0;
2257  AST_APP_ARG(peers);
2260  AST_APP_ARG(url);
2261  );
2262  struct ast_flags64 opts = { 0, };
2263  char *opt_args[OPT_ARG_ARRAY_SIZE];
2264  int fulldial = 0, num_dialed = 0;
2265  int ignore_cc = 0;
2266  char device_name[AST_CHANNEL_NAME];
2267  char forced_clid_name[AST_MAX_EXTENSION];
2268  char stored_clid_name[AST_MAX_EXTENSION];
2269  int force_forwards_only; /*!< TRUE if force CallerID on call forward only. Legacy behaviour.*/
2270  /*!
2271  * \brief Forced CallerID party information to send.
2272  * \note This will not have any malloced strings so do not free it.
2273  */
2274  struct ast_party_id forced_clid;
2275  /*!
2276  * \brief Stored CallerID information if needed.
2277  *
2278  * \note If OPT_ORIGINAL_CLID set then this is the o option
2279  * CallerID. Otherwise it is the dialplan extension and hint
2280  * name.
2281  *
2282  * \note This will not have any malloced strings so do not free it.
2283  */
2284  struct ast_party_id stored_clid;
2285  /*!
2286  * \brief CallerID party information to store.
2287  * \note This will not have any malloced strings so do not free it.
2288  */
2289  struct ast_party_caller caller;
2290  int max_forwards;
2291  SCOPE_ENTER(1, "%s: Data: %s\n", ast_channel_name(chan), data);
2292 
2293  /* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
2294  ast_channel_lock(chan);
2296  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
2297  pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
2298  pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
2299  pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
2300  pbx_builtin_setvar_helper(chan, "ANSWEREDTIME_MS", "");
2301  pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
2302  pbx_builtin_setvar_helper(chan, "DIALEDTIME_MS", "");
2303  pbx_builtin_setvar_helper(chan, "RINGTIME", "");
2304  pbx_builtin_setvar_helper(chan, "RINGTIME_MS", "");
2305  pbx_builtin_setvar_helper(chan, "PROGRESSTIME", "");
2306  pbx_builtin_setvar_helper(chan, "PROGRESSTIME_MS", "");
2308  max_forwards = ast_max_forwards_get(chan);
2309  ast_channel_unlock(chan);
2310 
2311  if (max_forwards <= 0) {
2312  ast_log(LOG_WARNING, "Cannot place outbound call from channel '%s'. Max forwards exceeded\n",
2313  ast_channel_name(chan));
2314  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "BUSY");
2315  SCOPE_EXIT_RTN_VALUE(-1, "%s: Max forwards exceeded\n", ast_channel_name(chan));
2316  }
2317 
2318  if (ast_check_hangup_locked(chan)) {
2319  /*
2320  * Caller hung up before we could dial. If dial is executed
2321  * within an AGI then the AGI has likely eaten all queued
2322  * frames before executing the dial in DeadAGI mode. With
2323  * the caller hung up and no pending frames from the caller's
2324  * read queue, dial would not know that the call has hung up
2325  * until a called channel answers. It is rather annoying to
2326  * whoever just answered the non-existent call.
2327  *
2328  * Dial should not continue execution in DeadAGI mode, hangup
2329  * handlers, or the h exten.
2330  */
2331  ast_verb(3, "Caller hung up before dial.\n");
2332  pbx_builtin_setvar_helper(chan, "DIALSTATUS", "CANCEL");
2333  SCOPE_EXIT_RTN_VALUE(-1, "%s: Caller hung up before dial\n", ast_channel_name(chan));
2334  }
2335 
2336  parse = ast_strdupa(data ?: "");
2337 
2338  AST_STANDARD_APP_ARGS(args, parse);
2339 
2340  if (!ast_strlen_zero(args.options) &&
2341  ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
2342  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2343  goto done;
2344  }
2345 
2346  if (ast_cc_call_init(chan, &ignore_cc)) {
2347  goto done;
2348  }
2349 
2351  delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
2352 
2353  if (delprivintro < 0 || delprivintro > 1) {
2354  ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
2355  delprivintro = 0;
2356  }
2357  }
2358 
2359  if (!ast_test_flag64(&opts, OPT_RINGBACK)) {
2360  opt_args[OPT_ARG_RINGBACK] = NULL;
2361  }
2362 
2363  if (ast_test_flag64(&opts, OPT_OPERMODE)) {
2364  opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
2365  ast_verb(3, "Setting operator services mode to %d.\n", opermode);
2366  }
2367 
2369  calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
2370  if (!calldurationlimit.tv_sec) {
2371  ast_log(LOG_WARNING, "Dial does not accept S(%s)\n", opt_args[OPT_ARG_DURATION_STOP]);
2372  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2373  goto done;
2374  }
2375  ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
2376  }
2377 
2378  if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
2379  dtmf_progress = opt_args[OPT_ARG_SENDDTMF];
2380  dtmfcalled = strsep(&dtmf_progress, ":");
2381  dtmfcalling = strsep(&dtmf_progress, ":");
2382  }
2383 
2385  if (ast_bridge_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
2386  goto done;
2387  }
2388 
2389  /* Setup the forced CallerID information to send if used. */
2390  ast_party_id_init(&forced_clid);
2391  force_forwards_only = 0;
2392  if (ast_test_flag64(&opts, OPT_FORCECLID)) {
2393  if (ast_strlen_zero(opt_args[OPT_ARG_FORCECLID])) {
2394  ast_channel_lock(chan);
2395  forced_clid.number.str = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
2396  ast_channel_unlock(chan);
2397  forced_clid_name[0] = '\0';
2398  forced_clid.name.str = (char *) get_cid_name(forced_clid_name,
2399  sizeof(forced_clid_name), chan);
2400  force_forwards_only = 1;
2401  } else {
2402  /* Note: The opt_args[OPT_ARG_FORCECLID] string value is altered here. */
2403  ast_callerid_parse(opt_args[OPT_ARG_FORCECLID], &forced_clid.name.str,
2404  &forced_clid.number.str);
2405  }
2406  if (!ast_strlen_zero(forced_clid.name.str)) {
2407  forced_clid.name.valid = 1;
2408  }
2409  if (!ast_strlen_zero(forced_clid.number.str)) {
2410  forced_clid.number.valid = 1;
2411  }
2412  }
2414  && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_TAG])) {
2415  forced_clid.tag = opt_args[OPT_ARG_FORCE_CID_TAG];
2416  }
2417  forced_clid.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
2419  && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_PRES])) {
2420  int pres;
2421 
2422  pres = ast_parse_caller_presentation(opt_args[OPT_ARG_FORCE_CID_PRES]);
2423  if (0 <= pres) {
2424  forced_clid.number.presentation = pres;
2425  }
2426  }
2427 
2428  /* Setup the stored CallerID information if needed. */
2429  ast_party_id_init(&stored_clid);
2430  if (ast_test_flag64(&opts, OPT_ORIGINAL_CLID)) {
2431  if (ast_strlen_zero(opt_args[OPT_ARG_ORIGINAL_CLID])) {
2432  ast_channel_lock(chan);
2433  ast_party_id_set_init(&stored_clid, &ast_channel_caller(chan)->id);
2434  if (!ast_strlen_zero(ast_channel_caller(chan)->id.name.str)) {
2435  stored_clid.name.str = ast_strdupa(ast_channel_caller(chan)->id.name.str);
2436  }
2437  if (!ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
2438  stored_clid.number.str = ast_strdupa(ast_channel_caller(chan)->id.number.str);
2439  }
2440  if (!ast_strlen_zero(ast_channel_caller(chan)->id.subaddress.str)) {
2441  stored_clid.subaddress.str = ast_strdupa(ast_channel_caller(chan)->id.subaddress.str);
2442  }
2443  if (!ast_strlen_zero(ast_channel_caller(chan)->id.tag)) {
2444  stored_clid.tag = ast_strdupa(ast_channel_caller(chan)->id.tag);
2445  }
2446  ast_channel_unlock(chan);
2447  } else {
2448  /* Note: The opt_args[OPT_ARG_ORIGINAL_CLID] string value is altered here. */
2449  ast_callerid_parse(opt_args[OPT_ARG_ORIGINAL_CLID], &stored_clid.name.str,
2450  &stored_clid.number.str);
2451  if (!ast_strlen_zero(stored_clid.name.str)) {
2452  stored_clid.name.valid = 1;
2453  }
2454  if (!ast_strlen_zero(stored_clid.number.str)) {
2455  stored_clid.number.valid = 1;
2456  }
2457  }
2458  } else {
2459  /*
2460  * In case the new channel has no preset CallerID number by the
2461  * channel driver, setup the dialplan extension and hint name.
2462  */
2463  stored_clid_name[0] = '\0';
2464  stored_clid.name.str = (char *) get_cid_name(stored_clid_name,
2465  sizeof(stored_clid_name), chan);
2466  if (ast_strlen_zero(stored_clid.name.str)) {
2467  stored_clid.name.str = NULL;
2468  } else {
2469  stored_clid.name.valid = 1;
2470  }
2471  ast_channel_lock(chan);
2472  stored_clid.number.str = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
2473  stored_clid.number.valid = 1;
2474  ast_channel_unlock(chan);
2475  }
2476 
2477  if (ast_test_flag64(&opts, OPT_RESETCDR)) {
2478  ast_cdr_reset(ast_channel_name(chan), 0);
2479  }
2480  if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
2481  opt_args[OPT_ARG_PRIVACY] = ast_strdupa(ast_channel_exten(chan));
2482 
2483  if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
2484  res = setup_privacy_args(&pa, &opts, opt_args, chan);
2485  if (res <= 0)
2486  goto out;
2487  res = -1; /* reset default */
2488  }
2489 
2490  if (continue_exec)
2491  *continue_exec = 0;
2492 
2493  /* If a channel group has been specified, get it for use when we create peer channels */
2494 
2495  ast_channel_lock(chan);
2496  if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
2497  outbound_group = ast_strdupa(outbound_group);
2498  pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
2499  } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
2500  outbound_group = ast_strdupa(outbound_group);
2501  }
2502  ast_channel_unlock(chan);
2503 
2504  /* Set per dial instance flags. These flags are also passed back to RetryDial. */
2508 
2509  /* PREDIAL: Run gosub on the caller's channel */
2511  && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {
2512  ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLER]);
2513  ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER], 0);
2514  }
2515 
2516  /* loop through the list of dial destinations */
2517  rest = args.peers;
2518  while ((cur = strsep(&rest, "&"))) {
2519  struct ast_channel *tc; /* channel for this destination */
2520  char *number;
2521  char *tech;
2522  size_t tech_len;
2523  size_t number_len;
2524  struct ast_stream_topology *topology;
2525 
2526  cur = ast_strip(cur);
2527  if (ast_strlen_zero(cur)) {
2528  /* No tech/resource in this position. */
2529  continue;
2530  }
2531 
2532  /* Get a technology/resource pair */
2533  number = cur;
2534  tech = strsep(&number, "/");
2535 
2536  num_dialed++;
2537  if (ast_strlen_zero(number)) {
2538  ast_log(LOG_WARNING, "Dial argument takes format (technology/resource)\n");
2539  goto out;
2540  }
2541 
2542  tech_len = strlen(tech) + 1;
2543  number_len = strlen(number) + 1;
2544  tmp = ast_calloc(1, sizeof(*tmp) + (2 * tech_len) + number_len);
2545  if (!tmp) {
2546  goto out;
2547  }
2548 
2549  /* Save tech, number, and interface. */
2550  cur = tmp->stuff;
2551  strcpy(cur, tech);
2552  tmp->tech = cur;
2553  cur += tech_len;
2554  strcpy(cur, tech);
2555  cur[tech_len - 1] = '/';
2556  tmp->interface = cur;
2557  cur += tech_len;
2558  strcpy(cur, number);
2559  tmp->number = cur;
2560 
2561  if (opts.flags) {
2562  /* Set per outgoing call leg options. */
2563  ast_copy_flags64(tmp, &opts,
2573  }
2574 
2575  /* Request the peer */
2576 
2577  ast_channel_lock(chan);
2578  /*
2579  * Seed the chanlist's connected line information with previously
2580  * acquired connected line info from the incoming channel. The
2581  * previously acquired connected line info could have been set
2582  * through the CONNECTED_LINE dialplan function.
2583  */
2585 
2587 
2588  ast_channel_unlock(chan);
2589 
2590  tc = ast_request_with_stream_topology(tmp->tech, topology, NULL, chan, tmp->number, &cause);
2591 
2592  ast_stream_topology_free(topology);
2593 
2594  if (!tc) {
2595  /* If we can't, just go on to the next call */
2596  ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
2597  tmp->tech, cause, ast_cause2str(cause));
2598  handle_cause(cause, &num);
2599  if (!rest) {
2600  /* we are on the last destination */
2601  ast_channel_hangupcause_set(chan, cause);
2602  }
2603  if (!ignore_cc && (cause == AST_CAUSE_BUSY || cause == AST_CAUSE_CONGESTION)) {
2604  if (!ast_cc_callback(chan, tmp->tech, tmp->number, ast_cc_busy_interface)) {
2606  }
2607  }
2608  chanlist_free(tmp);
2609  continue;
2610  }
2611 
2612  ast_channel_get_device_name(tc, device_name, sizeof(device_name));
2613  if (!ignore_cc) {
2614  ast_cc_extension_monitor_add_dialstring(chan, tmp->interface, device_name);
2615  }
2616 
2617  ast_channel_lock_both(tc, chan);
2619 
2620  pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", tmp->number);
2621 
2622  /* Setup outgoing SDP to match incoming one */
2623  if (!AST_LIST_FIRST(&out_chans) && !rest && CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
2624  /* We are on the only destination. */
2626  }
2627 
2628  /* Inherit specially named variables from parent channel */
2632 
2633  ast_channel_appl_set(tc, "AppDial");
2634  ast_channel_data_set(tc, "(Outgoing Line)");
2635 
2636  memset(ast_channel_whentohangup(tc), 0, sizeof(*ast_channel_whentohangup(tc)));
2637 
2638  /* Determine CallerID to store in outgoing channel. */
2640  if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
2641  caller.id = stored_clid;
2642  ast_channel_set_caller_event(tc, &caller, NULL);
2644  } else if (ast_strlen_zero(S_COR(ast_channel_caller(tc)->id.number.valid,
2645  ast_channel_caller(tc)->id.number.str, NULL))) {
2646  /*
2647  * The new channel has no preset CallerID number by the channel
2648  * driver. Use the dialplan extension and hint name.
2649  */
2650  caller.id = stored_clid;
2651  if (!caller.id.name.valid
2652  && !ast_strlen_zero(S_COR(ast_channel_connected(chan)->id.name.valid,
2653  ast_channel_connected(chan)->id.name.str, NULL))) {
2654  /*
2655  * No hint name available. We have a connected name supplied by
2656  * the dialplan we can use instead.
2657  */
2658  caller.id.name.valid = 1;
2659  caller.id.name = ast_channel_connected(chan)->id.name;
2660  }
2661  ast_channel_set_caller_event(tc, &caller, NULL);
2663  } else if (ast_strlen_zero(S_COR(ast_channel_caller(tc)->id.name.valid, ast_channel_caller(tc)->id.name.str,
2664  NULL))) {
2665  /* The new channel has no preset CallerID name by the channel driver. */
2666  if (!ast_strlen_zero(S_COR(ast_channel_connected(chan)->id.name.valid,
2667  ast_channel_connected(chan)->id.name.str, NULL))) {
2668  /*
2669  * We have a connected name supplied by the dialplan we can
2670  * use instead.
2671  */
2672  caller.id.name.valid = 1;
2673  caller.id.name = ast_channel_connected(chan)->id.name;
2674  ast_channel_set_caller_event(tc, &caller, NULL);
2675  }
2676  }
2677 
2678  /* Determine CallerID for outgoing channel to send. */
2679  if (ast_test_flag64(peerflags, OPT_FORCECLID) && !force_forwards_only) {
2681 
2683  connected.id = forced_clid;
2685  } else {
2687  }
2688 
2690 
2692 
2695  ast_channel_musicclass_set(tc, ast_channel_musicclass(chan));
2696  }
2697 
2698  /* Pass ADSI CPE and transfer capability */
2701 
2702  /* If we have an outbound group, set this peer channel to it */
2703  if (outbound_group)
2704  ast_app_group_set_channel(tc, outbound_group);
2705  /* If the calling channel has the ANSWERED_ELSEWHERE flag set, inherit it. This is to support local channels */
2708 
2709  /* Check if we're forced by configuration */
2712 
2713 
2714  /* Inherit context and extension */
2715  ast_channel_dialcontext_set(tc, ast_strlen_zero(ast_channel_macrocontext(chan)) ? ast_channel_context(chan) : ast_channel_macrocontext(chan));
2718  else
2720 
2722 
2723  /* Save the original channel name to detect call pickup masquerading in. */
2725 
2726  ast_channel_unlock(tc);
2727  ast_channel_unlock(chan);
2728 
2729  /* Put channel in the list of outgoing thingies. */
2730  tmp->chan = tc;
2731  AST_LIST_INSERT_TAIL(&out_chans, tmp, node);
2732  }
2733 
2734  if (AST_LIST_EMPTY(&out_chans)) {
2735  ast_verb(3, "No devices or endpoints to dial (technology/resource)\n");
2736  if (continue_exec) {
2737  /* There is no point in having RetryDial try again */
2738  *continue_exec = 1;
2739  }
2740  strcpy(pa.status, "CHANUNAVAIL");
2741  res = 0;
2742  goto out;
2743  }
2744 
2745  /*
2746  * PREDIAL: Run gosub on all of the callee channels
2747  *
2748  * We run the callee predial before ast_call() in case the user
2749  * wishes to do something on the newly created channels before
2750  * the channel does anything important.
2751  *
2752  * Inside the target gosub we will be able to do something with
2753  * the newly created channel name ie: now the calling channel
2754  * can know what channel will be used to call the destination
2755  * ex: now we will know that SIP/abc-123 is calling SIP/def-124
2756  */
2759  && !AST_LIST_EMPTY(&out_chans)) {
2760  const char *predial_callee;
2761 
2762  ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLEE]);
2763  predial_callee = ast_app_expand_sub_args(chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
2764  if (predial_callee) {
2765  ast_autoservice_start(chan);
2766  AST_LIST_TRAVERSE(&out_chans, tmp, node) {
2767  ast_pre_call(tmp->chan, predial_callee);
2768  }
2769  ast_autoservice_stop(chan);
2770  ast_free((char *) predial_callee);
2771  }
2772  }
2773 
2774  /* Start all outgoing calls */
2775  AST_LIST_TRAVERSE_SAFE_BEGIN(&out_chans, tmp, node) {
2776  res = ast_call(tmp->chan, tmp->number, 0); /* Place the call, but don't wait on the answer */
2777  ast_channel_lock(chan);
2778 
2779  /* check the results of ast_call */
2780  if (res) {
2781  /* Again, keep going even if there's an error */
2782  ast_debug(1, "ast call on peer returned %d\n", res);
2783  ast_verb(3, "Couldn't call %s\n", tmp->interface);
2784  if (ast_channel_hangupcause(tmp->chan)) {
2786  }
2787  ast_channel_unlock(chan);
2788  ast_cc_call_failed(chan, tmp->chan, tmp->interface);
2789  ast_hangup(tmp->chan);
2790  tmp->chan = NULL;
2792  chanlist_free(tmp);
2793  continue;
2794  }
2795 
2796  ast_channel_publish_dial(chan, tmp->chan, tmp->number, NULL);
2797  ast_channel_unlock(chan);
2798 
2799  ast_verb(3, "Called %s\n", tmp->interface);
2801 
2802  /* If this line is up, don't try anybody else */
2803  if (ast_channel_state(tmp->chan) == AST_STATE_UP) {
2804  break;
2805  }
2806  }
2808 
2809  if (ast_strlen_zero(args.timeout)) {
2810  to = -1;
2811  } else {
2812  to = atoi(args.timeout);
2813  if (to > 0)
2814  to *= 1000;
2815  else {
2816  ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
2817  to = -1;
2818  }
2819  }
2820 
2821  outgoing = AST_LIST_FIRST(&out_chans);
2822  if (!outgoing) {
2823  strcpy(pa.status, "CHANUNAVAIL");
2824  if (fulldial == num_dialed) {
2825  res = -1;
2826  goto out;
2827  }
2828  } else {
2829  /* Our status will at least be NOANSWER */
2830  strcpy(pa.status, "NOANSWER");
2831  if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
2832  moh = 1;
2833  if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
2834  char *original_moh = ast_strdupa(ast_channel_musicclass(chan));
2835  ast_channel_musicclass_set(chan, opt_args[OPT_ARG_MUSICBACK]);
2836  ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
2837  ast_channel_musicclass_set(chan, original_moh);
2838  } else {
2839  ast_moh_start(chan, NULL, NULL);
2840  }
2842  } else if (ast_test_flag64(outgoing, OPT_RINGBACK) || ast_test_flag64(outgoing, OPT_RING_WITH_EARLY_MEDIA)) {
2843  if (!ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
2844  if (dial_handle_playtones(chan, opt_args[OPT_ARG_RINGBACK])){
2846  sentringing++;
2847  } else {
2849  }
2850  } else {
2852  sentringing++;
2853  }
2854  }
2855  }
2856 
2857  peer = wait_for_answer(chan, &out_chans, &to, peerflags, opt_args, &pa, &num, &result,
2858  dtmf_progress, ignore_cc, &forced_clid, &stored_clid, &config);
2859 
2860  if (!peer) {
2861  if (result) {
2862  res = result;
2863  } else if (to) { /* Musta gotten hung up */
2864  res = -1;
2865  } else { /* Nobody answered, next please? */
2866  res = 0;
2867  }
2868  } else {
2869  const char *number;
2870  const char *name;
2871  int dial_end_raised = 0;
2872  int cause = -1;
2873 
2874  if (ast_test_flag64(&opts, OPT_CALLER_ANSWER)) {
2875  ast_answer(chan);
2876  }
2877 
2878  /* Ah ha! Someone answered within the desired timeframe. Of course after this
2879  we will always return with -1 so that it is hung up properly after the
2880  conversation. */
2881 
2882  if (ast_test_flag64(&opts, OPT_HANGUPCAUSE)
2883  && !ast_strlen_zero(opt_args[OPT_ARG_HANGUPCAUSE])) {
2884  cause = ast_str2cause(opt_args[OPT_ARG_HANGUPCAUSE]);
2885  if (cause <= 0) {
2886  if (!strcasecmp(opt_args[OPT_ARG_HANGUPCAUSE], "NONE")) {
2887  cause = 0;
2888  } else if (sscanf(opt_args[OPT_ARG_HANGUPCAUSE], "%30d", &cause) != 1
2889  || cause < 0) {
2890  ast_log(LOG_WARNING, "Invalid cause given to Dial(...Q(<cause>)): \"%s\"\n",
2891  opt_args[OPT_ARG_HANGUPCAUSE]);
2892  cause = -1;
2893  }
2894  }
2895  }
2896  hanguptree(&out_chans, peer, cause >= 0 ? cause : AST_CAUSE_ANSWERED_ELSEWHERE);
2897 
2898  /* If appropriate, log that we have a destination channel and set the answer time */
2899 
2900  ast_channel_lock(peer);
2901  name = ast_strdupa(ast_channel_name(peer));
2902 
2903  number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
2904  if (ast_strlen_zero(number)) {
2905  number = NULL;
2906  } else {
2907  number = ast_strdupa(number);
2908  }
2909  ast_channel_unlock(peer);
2910 
2911  ast_channel_lock(chan);
2913 
2914  strcpy(pa.status, "ANSWER");
2915  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2916 
2917  pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", name);
2918  pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
2919 
2921  ast_channel_unlock(chan);
2922 
2923  if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
2924  ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
2925  ast_channel_sendurl( peer, args.url );
2926  }
2928  if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
2929  ast_channel_publish_dial(chan, peer, NULL, pa.status);
2930  /* hang up on the callee -- he didn't want to talk anyway! */
2932  res = 0;
2933  goto out;
2934  }
2935  }
2936  if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
2937  res = 0;
2938  } else {
2939  int digit = 0;
2940  struct ast_channel *chans[2];
2941  struct ast_channel *active_chan;
2942 
2943  chans[0] = chan;
2944  chans[1] = peer;
2945 
2946  /* we need to stream the announcement to the called party when the OPT_ARG_ANNOUNCE (-A) is setted */
2947 
2948  /* stream the file */
2949  res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], ast_channel_language(peer));
2950  if (res) {
2951  res = 0;
2952  ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]);
2953  }
2954 
2956  while (ast_channel_stream(peer)) {
2957  int ms;
2958 
2959  ms = ast_sched_wait(ast_channel_sched(peer));
2960 
2961  if (ms < 0 && !ast_channel_timingfunc(peer)) {
2962  ast_stopstream(peer);
2963  break;
2964  }
2965  if (ms < 0)
2966  ms = 1000;
2967 
2968  active_chan = ast_waitfor_n(chans, 2, &ms);
2969  if (active_chan) {
2970  struct ast_channel *other_chan;
2971  struct ast_frame *fr = ast_read(active_chan);
2972 
2973  if (!fr) {
2975  res = -1;
2976  goto done;
2977  }
2978  switch (fr->frametype) {
2979  case AST_FRAME_DTMF_END:
2980  digit = fr->subclass.integer;
2981  if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
2982  ast_stopstream(peer);
2983  res = ast_senddigit(chan, digit, 0);
2984  }
2985  break;
2986  case AST_FRAME_CONTROL:
2987  switch (fr->subclass.integer) {
2988  case AST_CONTROL_HANGUP:
2989  ast_frfree(fr);
2991  res = -1;
2992  goto done;
2994  /* Pass COLP update to the other channel. */
2995  if (active_chan == chan) {
2996  other_chan = peer;
2997  } else {
2998  other_chan = chan;
2999  }
3000  if (ast_channel_connected_line_sub(active_chan, other_chan, fr, 1)
3001  && ast_channel_connected_line_macro(active_chan,
3002  other_chan, fr, other_chan == chan, 1)) {
3003  ast_indicate_data(other_chan, fr->subclass.integer,
3004  fr->data.ptr, fr->datalen);
3005  }
3006  break;
3007  default:
3008  break;
3009  }
3010  break;
3011  default:
3012  /* Ignore all others */
3013  break;
3014  }
3015  ast_frfree(fr);
3016  }
3018  }
3020  }
3021 
3022  if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
3023  /* chan and peer are going into the PBX; as such neither are considered
3024  * outgoing channels any longer */
3026 
3027  ast_replace_subargument_delimiter(opt_args[OPT_ARG_GOTO]);
3028  ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
3029  /* peer goes to the same context and extension as chan, so just copy info from chan*/
3030  ast_channel_lock(peer);
3037  ast_channel_unlock(peer);
3038  if (ast_pbx_start(peer)) {
3040  }
3041  if (continue_exec)
3042  *continue_exec = 1;
3043  res = 0;
3044  ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
3045  goto done;
3046  }
3047 
3049  const char *macro_result_peer;
3050  int macro_res;
3051 
3052  /* Set peer->exten and peer->context so that MACRO_EXTEN and MACRO_CONTEXT get set */
3053  ast_channel_lock_both(chan, peer);
3056  ast_channel_unlock(peer);
3057  ast_channel_unlock(chan);
3058  ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
3059  macro_res = ast_app_exec_macro(chan, peer, opt_args[OPT_ARG_CALLEE_MACRO]);
3060 
3061  ast_channel_lock(peer);
3062 
3063  if (!macro_res && (macro_result_peer = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
3064  char *macro_result = ast_strdupa(macro_result_peer);
3065  char *macro_transfer_dest;
3066 
3067  ast_channel_unlock(peer);
3068 
3069  if (!strcasecmp(macro_result, "BUSY")) {
3070  ast_copy_string(pa.status, macro_result, sizeof(pa.status));
3071  ast_set_flag64(peerflags, OPT_GO_ON);
3072  macro_res = -1;
3073  } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
3074  ast_copy_string(pa.status, macro_result, sizeof(pa.status));
3075  ast_set_flag64(peerflags, OPT_GO_ON);
3076  macro_res = -1;
3077  } else if (!strcasecmp(macro_result, "CONTINUE")) {
3078  /* hangup peer and keep chan alive assuming the macro has changed
3079  the context / exten / priority or perhaps
3080  the next priority in the current exten is desired.
3081  */
3082  ast_set_flag64(peerflags, OPT_GO_ON);
3083  macro_res = -1;
3084  } else if (!strcasecmp(macro_result, "ABORT")) {
3085  /* Hangup both ends unless the caller has the g flag */
3086  macro_res = -1;
3087  } else if (!strncasecmp(macro_result, "GOTO:", 5)) {
3088  macro_transfer_dest = macro_result + 5;
3089  macro_res = -1;
3090  /* perform a transfer to a new extension */
3091  if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
3092  ast_replace_subargument_delimiter(macro_transfer_dest);
3093  }
3094  if (!ast_parseable_goto(chan, macro_transfer_dest)) {
3095  ast_set_flag64(peerflags, OPT_GO_ON);
3096  }
3097  }
3098  if (macro_res && !dial_end_raised) {
3099  ast_channel_publish_dial(chan, peer, NULL, macro_result);
3100  dial_end_raised = 1;
3101  }
3102  } else {
3103  ast_channel_unlock(peer);
3104  }
3105  res = macro_res;
3106  }
3107 
3109  const char *gosub_result_peer;
3110  char *gosub_argstart;
3111  char *gosub_args = NULL;
3112  int gosub_res = -1;
3113 
3114  ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
3115  gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
3116  if (gosub_argstart) {
3117  const char *what_is_s = "s";
3118  *gosub_argstart = 0;
3119  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)) &&
3120  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))) {
3121  what_is_s = "~~s~~";
3122  }
3123  if (ast_asprintf(&gosub_args, "%s,%s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s, gosub_argstart + 1) < 0) {
3124  gosub_args = NULL;
3125  }
3126  *gosub_argstart = ',';
3127  } else {
3128  const char *what_is_s = "s";
3129  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)) &&
3130  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))) {
3131  what_is_s = "~~s~~";
3132  }
3133  if (ast_asprintf(&gosub_args, "%s,%s,1", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s) < 0) {
3134  gosub_args = NULL;
3135  }
3136  }
3137  if (gosub_args) {
3138  gosub_res = ast_app_exec_sub(chan, peer, gosub_args, 0);
3139  ast_free(gosub_args);
3140  } else {
3141  ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
3142  }
3143 
3144  ast_channel_lock_both(chan, peer);
3145 
3146  if (!gosub_res && (gosub_result_peer = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
3147  char *gosub_transfer_dest;
3148  char *gosub_result = ast_strdupa(gosub_result_peer);
3149  const char *gosub_retval = pbx_builtin_getvar_helper(peer, "GOSUB_RETVAL");
3150 
3151  /* Inherit return value from the peer, so it can be used in the master */
3152  if (gosub_retval) {
3153  pbx_builtin_setvar_helper(chan, "GOSUB_RETVAL", gosub_retval);
3154  }
3155 
3156  ast_channel_unlock(peer);
3157  ast_channel_unlock(chan);
3158 
3159  if (!strcasecmp(gosub_result, "BUSY")) {
3160  ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
3161  ast_set_flag64(peerflags, OPT_GO_ON);
3162  gosub_res = -1;
3163  } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
3164  ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
3165  ast_set_flag64(peerflags, OPT_GO_ON);
3166  gosub_res = -1;
3167  } else if (!strcasecmp(gosub_result, "CONTINUE")) {
3168  /* Hangup peer and continue with the next extension priority. */
3169  ast_set_flag64(peerflags, OPT_GO_ON);
3170  gosub_res = -1;
3171  } else if (!strcasecmp(gosub_result, "ABORT")) {
3172  /* Hangup both ends unless the caller has the g flag */
3173  gosub_res = -1;
3174  } else if (!strncasecmp(gosub_result, "GOTO:", 5)) {
3175  gosub_transfer_dest = gosub_result + 5;
3176  gosub_res = -1;
3177  /* perform a transfer to a new extension */
3178  if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
3179  ast_replace_subargument_delimiter(gosub_transfer_dest);
3180  }
3181  if (!ast_parseable_goto(chan, gosub_transfer_dest)) {
3182  ast_set_flag64(peerflags, OPT_GO_ON);
3183  }
3184  }
3185  if (gosub_res) {
3186  res = gosub_res;
3187  if (!dial_end_raised) {
3188  ast_channel_publish_dial(chan, peer, NULL, gosub_result);
3189  dial_end_raised = 1;
3190  }
3191  }
3192  } else {
3193  ast_channel_unlock(peer);
3194  ast_channel_unlock(chan);
3195  }
3196  }
3197 
3198  if (!res) {
3199 
3200  /* None of the Dial options changed our status; inform
3201  * everyone that this channel answered
3202  */
3203  if (!dial_end_raised) {
3204  ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
3205  dial_end_raised = 1;
3206  }
3207 
3208  if (!ast_tvzero(calldurationlimit)) {
3209  struct timeval whentohangup = ast_tvadd(ast_tvnow(), calldurationlimit);
3210  ast_channel_lock(peer);
3211  ast_channel_whentohangup_set(peer, &whentohangup);
3212  ast_channel_unlock(peer);
3213  }
3214  if (!ast_strlen_zero(dtmfcalled)) {
3215  ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
3216  res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
3217  }
3218  if (!ast_strlen_zero(dtmfcalling)) {
3219  ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
3220  res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
3221  }
3222  }
3223 
3224  if (res) { /* some error */
3225  if (!ast_check_hangup(chan) && ast_check_hangup(peer)) {
3227  }
3228  setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3229  if (ast_bridge_setup_after_goto(peer)
3230  || ast_pbx_start(peer)) {
3232  }
3233  res = -1;
3234  } else {
3235  if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
3237  if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
3239  if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
3241  if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
3243  if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
3245  if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
3247  if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
3249  if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
3251  if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
3253  if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
3255 
3257  config.end_bridge_callback_data = chan;
3259 
3260  if (moh) {
3261  moh = 0;
3262  ast_moh_stop(chan);
3263  } else if (sentringing) {
3264  sentringing = 0;
3265  ast_indicate(chan, -1);
3266  }
3267  /* Be sure no generators are left on it and reset the visible indication */
3270  /* Make sure channels are compatible */
3271  res = ast_channel_make_compatible(chan, peer);
3272  if (res < 0) {
3273  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));
3275  res = -1;
3276  goto done;
3277  }
3278  if (opermode) {
3279  struct oprmode oprmode;
3280 
3281  oprmode.peer = peer;
3282  oprmode.mode = opermode;
3283 
3285  }
3286  setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3287 
3288  res = ast_bridge_call(chan, peer, &config);
3289  }
3290  }
3291 out:
3292  if (moh) {
3293  moh = 0;
3294  ast_moh_stop(chan);
3295  } else if (sentringing) {
3296  sentringing = 0;
3297  ast_indicate(chan, -1);
3298  }
3299 
3300  if (delprivintro && ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3302  if (ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3303  ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
3304  } else {
3305  ast_verb(3, "Successfully deleted %s intro file\n", pa.privintro);
3306  }
3307  }
3308 
3310  /* forward 'answered elsewhere' if we received it */
3311  hanguptree(&out_chans, NULL,
3315  pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
3316  ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
3317 
3318  if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
3319  if (!ast_tvzero(calldurationlimit))
3320  memset(ast_channel_whentohangup(chan), 0, sizeof(*ast_channel_whentohangup(chan)));
3321  res = 0;
3322  }
3323 
3324 done:
3325  if (config.answer_topology) {
3326  ast_trace(2, "%s Cleaning up topology: %p %s\n",
3327  peer ? ast_channel_name(peer) : "<no channel>", &config.answer_topology,
3328  ast_str_tmp(256, ast_stream_topology_to_str(config.answer_topology, &STR_TMP)));
3329 
3330  /*
3331  * At this point, the channel driver that answered should have bumped the
3332  * topology refcount for itself. Here we're cleaning up the reference we added
3333  * in wait_for_answer().
3334  */
3336  }
3337  if (config.warning_sound) {
3338  ast_free((char *)config.warning_sound);
3339  }
3340  if (config.end_sound) {
3341  ast_free((char *)config.end_sound);
3342  }
3343  if (config.start_sound) {
3344  ast_free((char *)config.start_sound);
3345  }
3346  ast_ignore_cc(chan);
3347  SCOPE_EXIT_RTN_VALUE(res, "%s: Done\n", ast_channel_name(chan));
3348 }
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:3152
#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:7375
Information needed to identify an endpoint in a call.
Definition: channel.h:339
char digit
#define ast_channel_lock(chan)
Definition: channel.h:2890
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:10292
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:7335
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:1079
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_stream_topology * answer_topology
Definition: channel.h:1100
struct ast_party_id id
Connected party ID.
Definition: channel.h:459
#define AST_DIGIT_ANY
Definition: file.h:48
const char * ast_app_expand_sub_args(struct ast_channel *chan, const char *args)
Add missing context/exten to subroutine argument string.
Definition: main/app.c:351
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation...
Definition: channel.c:2031
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4291
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
int ast_channel_supports_html(struct ast_channel *channel)
Checks for HTML support on a channel.
Definition: channel.c:6583
#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:4712
union ast_frame::@257 data
static int timeout
Definition: cdr_mysql.c:86
static void end_bridge_callback(void *data)
Definition: app_dial.c:2150
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:6445
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:11089
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4271
#define ast_trace(level,...)
Definition: logger.h:876
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:4667
int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
Bridge a call, optionally allowing redirection.
Definition: features.c:716
#define DIAL_STILLGOING
Definition: app_dial.c: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:4918
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:7385
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:7739
#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:1089
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, struct ast_bridge_config *config)
Definition: app_dial.c:1201
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
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2359
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:2049
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
#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:6680
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
struct ast_channel * chan
Definition: app_dial.c: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:8859
#define AST_MAX_EXTENSION
Definition: channel.h:135
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
bridge configuration
Definition: channel.h:1077
void * end_bridge_callback_data
Definition: channel.h:1092
Caller Party information.
Definition: channel.h:419
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
const char * end_sound
Definition: channel.h:1088
static int dial_handle_playtones(struct ast_channel *chan, const char *data)
Definition: app_dial.c:2166
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
void(* end_bridge_callback_data_fixup)(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
Definition: channel.h:1096
int ast_cdr_reset(const char *channel_name, int keep_variables)
Reset the detail record.
Definition: cdr.c:3598
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
List of channel drivers.
Definition: app_dial.c: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:6341
#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:4179
int ast_app_exec_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_args)
Run a macro on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:273
int ast_pre_call(struct ast_channel *chan, const char *sub_args)
Execute a Gosub call on the channel before a call is placed.
Definition: channel.c:6428
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:6418
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:1078
int ast_cc_callback(struct ast_channel *inbound, const char *const tech, const char *const dest, ast_cc_callback_fn callback)
Run a callback for potential matching destinations.
Definition: ccss.c:4244
uint64_t flags
Definition: utils.h:205
int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
Start the CC process on a call.
Definition: ccss.c:2409
#define AST_PBX_INCOMPLETE
Definition: pbx.h:51
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
#define OPT_CALLER_ANSWER
Definition: app_dial.c: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:1985
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
Definition: channel.c:11082
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:10396
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:869
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
Connected Line/Party information.
Definition: channel.h:457
void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
Initialize the given party id structure using the given guide for a set update operation.
Definition: channel.c:1766
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:7729
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:2208
#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:6595
#define ast_channel_unlock(chan)
Definition: channel.h:2891
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:6729
#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:2534
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
#define SCOPE_ENTER(level,...)
Definition: logger.h:885
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:1743
#define ast_set2_flag64(p, value, flag)
Definition: utils.h:151
#define AST_PRIVACY_UNKNOWN
Definition: privacy.h:34
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
Definition: linkedlists.h:251
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct ast_channel * peer
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
Callback made from ast_cc_callback for certain channel types.
Definition: ccss.c:4232
Definition: astman.c:88
void(* end_bridge_callback)(void *)
Definition: channel.h:1091
#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:332
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2897
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:904
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:2888
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:2017
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:8246
#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:2800
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:10554
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:1087
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
Definition: app_dial.c:2162
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:743
const char * ast_channel_macrocontext(const struct ast_channel *chan)
static char url[512]
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c_dst, struct ast_channel *c_src)
Make two channels compatible for early bridging.
Definition: rtp_engine.c:2251
static void hanguptree(struct dial_head *out_chans, struct ast_channel *exception, int hangupcause)
Definition: app_dial.c: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:8261
#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:2121
const char * ast_channel_musicclass(const struct ast_channel *chan)
#define AST_APP_ARG(name)
Define an application argument.
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1008
int ast_bridge_timelimit(struct ast_channel *chan, struct ast_bridge_config *config, char *parse, struct timeval *calldurationlimit)
parse L option and read associated channel variables to set warning, warning frequency, and timelimit
Definition: features.c:886
char * orig_chan_name
Definition: app_dial.c: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 2166 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().

2167 {
2168  struct ast_tone_zone_sound *ts = NULL;
2169  int res;
2170  const char *str = data;
2171 
2172  if (ast_strlen_zero(str)) {
2173  ast_debug(1,"Nothing to play\n");
2174  return -1;
2175  }
2176 
2177  ts = ast_get_indication_tone(ast_channel_zone(chan), str);
2178 
2179  if (ts && ts->data[0]) {
2180  res = ast_playtones_start(chan, 0, ts->data, 0);
2181  } else {
2182  res = -1;
2183  }
2184 
2185  if (ts) {
2186  ts = ast_tone_zone_sound_unref(ts);
2187  }
2188 
2189  if (res) {
2190  ast_log(LOG_WARNING, "Unable to start playtone \'%s\'\n", str);
2191  }
2192 
2193  return res;
2194 }
#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:2008
#define ast_channel_lock(chan)
Definition: channel.h:2890
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:7335
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:4291
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:10236
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6445
#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:2359
#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:6680
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:10441
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
Definition: channel.c:1630
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:6341
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:6418
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:1677
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:1985
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:2891
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:6729
#define AST_CHANNEL_NAME
Definition: channel.h:172
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2534
#define ast_clear_flag64(p, flag)
Definition: utils.h:134
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2897
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:2165
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:2017
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:8246
#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:2108
#define AST_CAUSE_BUSY
Definition: causes.h:148
const char * ast_channel_context(const struct ast_channel *chan)
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c_dst, struct ast_channel *c_src)
Make two channels compatible for early bridging.
Definition: rtp_engine.c:2251
char connected
Definition: eagi_proxy.c:82
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
const char * ast_channel_macroexten(const struct ast_channel *chan)
void ast_channel_data_set(struct ast_channel *chan, const char *value)
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Definition: channel.c:2121
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:10344
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 2150 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().

2151 {
2152  struct ast_channel *chan = data;
2153 
2154  ast_channel_lock(chan);
2156  set_duration_var(chan, "ANSWEREDTIME", ast_channel_get_up_time_ms(chan));
2157  set_duration_var(chan, "DIALEDTIME", ast_channel_get_duration_ms(chan));
2159  ast_channel_unlock(chan);
2160 }
#define ast_channel_lock(chan)
Definition: channel.h:2890
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:2815
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:2830
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:2891
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 2162 of file app_dial.c.

References ast_bridge_config::end_bridge_callback_data.

Referenced by dial_exec_full().

2162  {
2163  bconfig->end_bridge_callback_data = originator;
2164 }
void * end_bridge_callback_data
Definition: channel.h:1092

◆ get_cid_name()

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

Definition at line 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:4141
#define ast_channel_lock(chan)
Definition: channel.h:2890
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:2891
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:2534
static void chanlist_free(struct chanlist *outgoing)
Definition: app_dial.c:820

◆ load_module()

static int load_module ( void  )
static

Definition at line 3477 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().

3478 {
3479  int res;
3480 
3483 
3484  return res;
3485 }
static int retrydial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3359
static int dial_exec(struct ast_channel *chan, const char *data)
Definition: app_dial.c:3350
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:8793
#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 3359 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().

3360 {
3361  char *parse;
3362  const char *context = NULL;
3363  int sleepms = 0, loops = 0, res = -1;
3364  struct ast_flags64 peerflags = { 0, };
3366  AST_APP_ARG(announce);
3367  AST_APP_ARG(sleep);
3368  AST_APP_ARG(retries);
3369  AST_APP_ARG(dialdata);
3370  );
3371 
3372  if (ast_strlen_zero(data)) {
3373  ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
3374  return -1;
3375  }
3376 
3377  parse = ast_strdupa(data);
3378  AST_STANDARD_APP_ARGS(args, parse);
3379 
3380  if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
3381  sleepms *= 1000;
3382 
3383  if (!ast_strlen_zero(args.retries)) {
3384  loops = atoi(args.retries);
3385  }
3386 
3387  if (!args.dialdata) {
3388  ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
3389  goto done;
3390  }
3391 
3392  if (sleepms < 1000)
3393  sleepms = 10000;
3394 
3395  if (!loops)
3396  loops = -1; /* run forever */
3397 
3398  ast_channel_lock(chan);
3399  context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
3400  context = !ast_strlen_zero(context) ? ast_strdupa(context) : NULL;
3401  ast_channel_unlock(chan);
3402 
3403  res = 0;
3404  while (loops) {
3405  int continue_exec;
3406 
3407  ast_channel_data_set(chan, "Retrying");
3409  ast_moh_stop(chan);
3410 
3411  res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
3412  if (continue_exec)
3413  break;
3414 
3415  if (res == 0) {
3416  if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
3417  if (!ast_strlen_zero(args.announce)) {
3418  if (ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3419  if (!(res = ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3421  } else
3422  ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3423  }
3424  if (!res && sleepms) {
3426  ast_moh_start(chan, NULL, NULL);
3427  res = ast_waitfordigit(chan, sleepms);
3428  }
3429  } else {
3430  if (!ast_strlen_zero(args.announce)) {
3431  if (ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3432  if (!(res = ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3433  res = ast_waitstream(chan, "");
3434  } else
3435  ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3436  }
3437  if (sleepms) {
3439  ast_moh_start(chan, NULL, NULL);
3440  if (!res)
3441  res = ast_waitfordigit(chan, sleepms);
3442  }
3443  }
3444  }
3445 
3446  if (res < 0 || res == AST_PBX_INCOMPLETE) {
3447  break;
3448  } else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
3449  if (onedigit_goto(chan, context, (char) res, 1)) {
3450  res = 0;
3451  break;
3452  }
3453  }
3454  loops--;
3455  }
3456  if (loops == 0)
3457  res = 0;
3458  else if (res == 1)
3459  res = 0;
3460 
3462  ast_moh_stop(chan);
3463  done:
3464  return res;
3465 }
#define ast_channel_lock(chan)
Definition: channel.h:2890
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:7739
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:7729
#define ast_strlen_zero(a)
Definition: muted.c:73
#define ast_channel_unlock(chan)
Definition: channel.h:2891
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:3170
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:2230
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 2208 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().

2209 {
2210  const char *context;
2211  const char *extension;
2212  int priority;
2213 
2214  if (ast_test_flag64(opts, OPT_PEER_H)) {
2215  ast_channel_lock(chan);
2216  context = ast_strdupa(ast_channel_context(chan));
2217  ast_channel_unlock(chan);
2218  ast_bridge_set_after_h(peer, context);
2219  } else if (ast_test_flag64(opts, OPT_CALLEE_GO_ON)) {
2220  ast_channel_lock(chan);
2221  context = ast_strdupa(ast_channel_context(chan));
2222  extension = ast_strdupa(ast_channel_exten(chan));
2223  priority = ast_channel_priority(chan);
2224  ast_channel_unlock(chan);
2225  ast_bridge_set_after_go_on(peer, context, extension, priority,
2226  opt_args[OPT_ARG_CALLEE_GO_ON]);
2227  }
2228 }
#define ast_channel_lock(chan)
Definition: channel.h:2890
#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:2891
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 2049 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().

2051 {
2052  char callerid[60];
2053  int res;
2054  char *l;
2055 
2056  if (ast_channel_caller(chan)->id.number.valid
2057  && !ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
2058  l = ast_strdupa(ast_channel_caller(chan)->id.number.str);
2060  if (ast_test_flag64(opts, OPT_PRIVACY) ) {
2061  ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
2062  pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
2063  } else {
2064  ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
2066  }
2067  } else {
2068  char *tnam, *tn2;
2069 
2070  tnam = ast_strdupa(ast_channel_name(chan));
2071  /* clean the channel name so slashes don't try to end up in disk file name */
2072  for (tn2 = tnam; *tn2; tn2++) {
2073  if (*tn2 == '/') /* any other chars to be afraid of? */
2074  *tn2 = '=';
2075  }
2076  ast_verb(3, "Privacy-- callerid is empty\n");
2077 
2078  snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", ast_channel_exten(chan), tnam);
2079  l = callerid;
2081  }
2082 
2083  ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
2084 
2085  if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
2086  /* if callerid is set and OPT_SCREEN_NOCALLERID is set also */
2087  ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
2089  } else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
2090  ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
2091  }
2092 
2093  if (pa->privdb_val == AST_PRIVACY_DENY) {
2094  ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
2095  ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
2096  return 0;
2097  } else if (pa->privdb_val == AST_PRIVACY_KILL) {
2098  ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
2099  return 0; /* Is this right? */
2100  } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
2101  ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
2102  return 0; /* is this right??? */
2103  } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
2104  /* Get the user's intro, store it in priv-callerintros/$CID,
2105  unless it is already there-- this should be done before the
2106  call is actually dialed */
2107 
2108  /* make sure the priv-callerintros dir actually exists */
2109  snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
2110  if ((res = ast_mkdir(pa->privintro, 0755))) {
2111  ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
2112  return -1;
2113  }
2114 
2115  snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
2116  if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
2117  /* the DELUX version of this code would allow this caller the
2118  option to hear and retape their previously recorded intro.
2119  */
2120  } else {
2121  int duration; /* for feedback from play_and_wait */
2122  /* the file doesn't exist yet. Let the caller submit his
2123  vocal intro for posterity */
2124  /* priv-recordintro script:
2125 
2126  "At the tone, please say your name:"
2127 
2128  */
2130  ast_answer(chan);
2131  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 */
2132  /* don't think we'll need a lock removed, we took care of
2133  conflicts by naming the pa.privintro file */
2134  if (res == -1) {
2135  /* Delete the file regardless since they hung up during recording */
2137  if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
2138  ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
2139  else
2140  ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
2141  return -1;
2142  }
2143  if (!ast_streamfile(chan, "vm-dialout", ast_channel_language(chan)) )
2144  ast_waitstream(chan, "");
2145  }
2146  }
2147  return 1; /* success */
2148 }
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:2800
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 3467 of file app_dial.c.

References app, ast_unregister_application(), and rapp.

Referenced by load_module().

3468 {
3469  int res;
3470 
3473 
3474  return res;
3475 }
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:2008
#define ast_channel_lock(chan)
Definition: channel.h:2890
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:10292
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:9046
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2058
#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:10396
Connected Line/Party information.
Definition: channel.h:457
#define ast_channel_unlock(chan)
Definition: channel.h:2891
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:8246

◆ 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,
struct ast_bridge_config config 
)
static

Definition at line 1201 of file app_dial.c.

References ast_bridge_config::answer_topology, ao2_bump, chanlist::aoc_s_rate_list, ast_aoc_decode(), ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), ast_aoc_encode(), ast_aoc_get_msg_type(), AST_AOC_S, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL_CLEARING, ast_cc_completed(), ast_cc_failed(), ast_cc_is_recall(), ast_channel_call_forward(), ast_channel_connected(), ast_channel_connected_line_macro(), ast_channel_connected_line_sub(), ast_channel_creationtime(), ast_channel_early_bridge(), ast_channel_exten_set(), ast_channel_hangupcause(), ast_channel_hangupcause_set(), ast_channel_lock, ast_channel_make_compatible(), ast_channel_name(), ast_channel_publish_dial(), ast_channel_redirecting_macro(), ast_channel_redirecting_sub(), ast_channel_sendhtml(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_unlock, ast_channel_update_connected_line(), ast_check_hangup(), ast_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_str_tmp, ast_strdup, ast_stream_topology_to_str(), ast_strlen_zero, ast_test_flag64, ast_trace, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_verb, ast_waitfor_n(), ast_write(), cause_args::busy, c, CAN_EARLY_BRIDGE, chanlist::chan, cause_args::congestion, chanlist::connected, context, ast_frame::data, ast_frame::datalen, detect_disconnect(), DIAL_CALLERID_ABSENT, DIAL_NOFORWARDHTML, DIAL_STILLGOING, do_forward(), ast_frame::frametype, handle_cause(), in, ast_frame_subclass::integer, LOG_WARNING, ast_channel::name, cause_args::nochan, NULL, onedigit_goto(), OPT_ARG_RINGBACK, OPT_CALLEE_HANGUP, OPT_CALLEE_MIXMONITOR, OPT_CALLEE_MONITOR, OPT_CALLEE_PARK, OPT_CALLEE_TRANSFER, OPT_CALLER_HANGUP, OPT_CALLER_MIXMONITOR, OPT_CALLER_MONITOR, OPT_CALLER_PARK, OPT_CALLER_TRANSFER, OPT_DTMF_EXIT, OPT_IGNORE_CONNECTEDLINE, OPT_MUSICBACK, OPT_RINGBACK, chanlist::orig_chan_name, pbx_builtin_getvar_helper(), chanlist::pending_connected_update, ast_frame::ptr, publish_dial_end_event(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, privacy_args::sentringing, set_duration_var(), privacy_args::status, ast_frame::subclass, ast_frame_subclass::topology, ast_frame::uint32, and update_connected_line_from_peer().

Referenced by dial_exec_full().

1209 {
1210  struct cause_args num = *num_in;
1211  int prestart = num.busy + num.congestion + num.nochan;
1212  int orig = *to;
1213  struct ast_channel *peer = NULL;
1214  struct chanlist *outgoing = AST_LIST_FIRST(out_chans);
1215  /* single is set if only one destination is enabled */
1216  int single = outgoing && !AST_LIST_NEXT(outgoing, node);
1217  int caller_entertained = outgoing
1218  && ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
1219  struct ast_str *featurecode = ast_str_alloca(AST_FEATURE_MAX_LEN + 1);
1220  int cc_recall_core_id;
1221  int is_cc_recall;
1222  int cc_frame_received = 0;
1223  int num_ringing = 0;
1224  int sent_ring = 0;
1225  int sent_progress = 0;
1226  struct timeval start = ast_tvnow();
1227  SCOPE_ENTER(3, "%s\n", ast_channel_name(in));
1228 
1229  if (single) {
1230  /* Turn off hold music, etc */
1231  if (!caller_entertained) {
1233  /* If we are calling a single channel, and not providing ringback or music, */
1234  /* then, make them compatible for in-band tone purpose */
1235  if (ast_channel_make_compatible(in, outgoing->chan) < 0) {
1236  /* If these channels can not be made compatible,
1237  * there is no point in continuing. The bridge
1238  * will just fail if it gets that far.
1239  */
1240  *to = -1;
1241  strcpy(pa->status, "CONGESTION");
1242  ast_channel_publish_dial(in, outgoing->chan, NULL, pa->status);
1243  SCOPE_EXIT_RTN_VALUE(NULL, "%s: can't be made compat with %s\n",
1244  ast_channel_name(in), ast_channel_name(outgoing->chan));
1245  }
1246  }
1247 
1249  && !ast_test_flag64(outgoing, DIAL_CALLERID_ABSENT)) {
1250  update_connected_line_from_peer(in, outgoing->chan, 1);
1251  }
1252  }
1253 
1254  is_cc_recall = ast_cc_is_recall(in, &cc_recall_core_id, NULL);
1255 
1256  while ((*to = ast_remaining_ms(start, orig)) && !peer) {
1257  struct chanlist *o;
1258  int pos = 0; /* how many channels do we handle */
1259  int numlines = prestart;
1260  struct ast_channel *winner;
1261  struct ast_channel *watchers[AST_MAX_WATCHERS];
1262 
1263  watchers[pos++] = in;
1264  AST_LIST_TRAVERSE(out_chans, o, node) {
1265  /* Keep track of important channels */
1266  if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
1267  watchers[pos++] = o->chan;
1268  numlines++;
1269  }
1270  if (pos == 1) { /* only the input channel is available */
1271  if (numlines == (num.busy + num.congestion + num.nochan)) {
1272  ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1273  if (num.busy)
1274  strcpy(pa->status, "BUSY");
1275  else if (num.congestion)
1276  strcpy(pa->status, "CONGESTION");
1277  else if (num.nochan)
1278  strcpy(pa->status, "CHANUNAVAIL");
1279  } else {
1280  ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1281  }
1282  *to = 0;
1283  if (is_cc_recall) {
1284  ast_cc_failed(cc_recall_core_id, "Everyone is busy/congested for the recall. How sad");
1285  }
1286  SCOPE_EXIT_RTN_VALUE(NULL, "%s: No outging channels available\n", ast_channel_name(in));
1287  }
1288  winner = ast_waitfor_n(watchers, pos, to);
1289  AST_LIST_TRAVERSE(out_chans, o, node) {
1290  struct ast_frame *f;
1291  struct ast_channel *c = o->chan;
1292 
1293  if (c == NULL)
1294  continue;
1296  if (!peer) {
1297  ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1298  if (o->orig_chan_name
1299  && strcmp(o->orig_chan_name, ast_channel_name(c))) {
1300  /*
1301  * The channel name changed so we must generate COLP update.
1302  * Likely because a call pickup channel masqueraded in.
1303  */
1305  } else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1306  if (o->pending_connected_update) {
1307  if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
1308  ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
1310  }
1311  } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1313  }
1314  }
1315  if (o->aoc_s_rate_list) {
1316  size_t encoded_size;
1317  struct ast_aoc_encoded *encoded;
1318  if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1319  ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1320  ast_aoc_destroy_encoded(encoded);
1321  }
1322  }
1323  peer = c;
1324  publish_dial_end_event(in, out_chans, peer, "CANCEL");
1325  ast_copy_flags64(peerflags, o,
1332  ast_channel_dialcontext_set(c, "");
1333  ast_channel_exten_set(c, "");
1334  }
1335  continue;
1336  }
1337  if (c != winner)
1338  continue;
1339  /* here, o->chan == c == winner */
1341  pa->sentringing = 0;
1342  if (!ignore_cc && (f = ast_read(c))) {
1344  /* This channel is forwarding the call, and is capable of CC, so
1345  * be sure to add the new device interface to the list
1346  */
1348  }
1349  ast_frfree(f);
1350  }
1351 
1352  if (o->pending_connected_update) {
1353  /*
1354  * Re-seed the chanlist's connected line information with
1355  * previously acquired connected line info from the incoming
1356  * channel. The previously acquired connected line info could
1357  * have been set through the CONNECTED_LINE dialplan function.
1358  */
1359  o->pending_connected_update = 0;
1360  ast_channel_lock(in);
1362  ast_channel_unlock(in);
1363  }
1364 
1365  do_forward(o, &num, peerflags, single, caller_entertained, &orig,
1366  forced_clid, stored_clid);
1367 
1368  if (o->chan) {
1371  if (single
1375  }
1376  }
1377  continue;
1378  }
1379  f = ast_read(winner);
1380  if (!f) {
1383  ast_hangup(c);
1384  c = o->chan = NULL;
1387  continue;
1388  }
1389  switch (f->frametype) {
1390  case AST_FRAME_CONTROL:
1391  switch (f->subclass.integer) {
1392  case AST_CONTROL_ANSWER:
1393  /* This is our guy if someone answered. */
1394  if (!peer) {
1395  ast_trace(-1, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1396  ast_verb(3, "%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1397  if (o->orig_chan_name
1398  && strcmp(o->orig_chan_name, ast_channel_name(c))) {
1399  /*
1400  * The channel name changed so we must generate COLP update.
1401  * Likely because a call pickup channel masqueraded in.
1402  */
1404  } else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1405  if (o->pending_connected_update) {
1406  if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
1407  ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
1409  }
1410  } else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1412  }
1413  }
1414  if (o->aoc_s_rate_list) {
1415  size_t encoded_size;
1416  struct ast_aoc_encoded *encoded;
1417  if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1418  ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
1419  ast_aoc_destroy_encoded(encoded);
1420  }
1421  }
1422  peer = c;
1423  /* Answer can optionally include a topology */
1424  if (f->subclass.topology) {
1425  /*
1426  * We need to bump the refcount on the topology to prevent it
1427  * from being cleaned up when the frame is cleaned up.
1428  */
1429  config->answer_topology = ao2_bump(f->subclass.topology);
1430  ast_trace(-1, "%s Found topology in frame: %p %p %s\n",
1431  ast_channel_name(peer), f, config->answer_topology,
1432  ast_str_tmp(256, ast_stream_topology_to_str(config->answer_topology, &STR_TMP)));
1433  }
1434 
1435  /* Inform everyone else that they've been canceled.
1436  * The dial end event for the peer will be sent out after
1437  * other Dial options have been handled.
1438  */
1439  publish_dial_end_event(in, out_chans, peer, "CANCEL");
1440  ast_copy_flags64(peerflags, o,
1447  ast_channel_dialcontext_set(c, "");
1448  ast_channel_exten_set(c, "");
1449  if (CAN_EARLY_BRIDGE(peerflags, in, peer)) {
1450  /* Setup early bridge if appropriate */
1451  ast_channel_early_bridge(in, peer);
1452  }
1453  }
1454  /* If call has been answered, then the eventual hangup is likely to be normal hangup */
1457  break;
1458  case AST_CONTROL_BUSY:
1459  ast_verb(3, "%s is busy\n", ast_channel_name(c));
1461  ast_channel_publish_dial(in, c, NULL, "BUSY");
1462  ast_hangup(c);
1463  c = o->chan = NULL;
1466  break;
1468  ast_verb(3, "%s is circuit-busy\n", ast_channel_name(c));
1470  ast_channel_publish_dial(in, c, NULL, "CONGESTION");
1471  ast_hangup(c);
1472  c = o->chan = NULL;
1475  break;
1476  case AST_CONTROL_RINGING:
1477  /* This is a tricky area to get right when using a native
1478  * CC agent. The reason is that we do the best we can to send only a
1479  * single ringing notification to the caller.
1480  *
1481  * Call completion complicates the logic used here. CCNR is typically
1482  * offered during a ringing message. Let's say that party A calls
1483  * parties B, C, and D. B and C do not support CC requests, but D
1484  * does. If we were to receive a ringing notification from B before
1485  * the others, then we would end up sending a ringing message to
1486  * A with no CCNR offer present.
1487  *
1488  * The approach that we have taken is that if we receive a ringing
1489  * response from a party and no CCNR offer is present, we need to
1490  * wait. Specifically, we need to wait until either a) a called party
1491  * offers CCNR in its ringing response or b) all called parties have
1492  * responded in some way to our call and none offers CCNR.
1493  *
1494  * The drawback to this is that if one of the parties has a delayed
1495  * response or, god forbid, one just plain doesn't respond to our
1496  * outgoing call, then this will result in a significant delay between
1497  * when the caller places the call and hears ringback.
1498  *
1499  * Note also that if CC is disabled for this call, then it is perfectly
1500  * fine for ringing frames to get sent through.
1501  */
1502  ++num_ringing;
1503  if (ignore_cc || cc_frame_received || num_ringing == numlines) {
1504  ast_verb(3, "%s is ringing\n", ast_channel_name(c));
1505  /* Setup early media if appropriate */
1506  if (single && !caller_entertained
1507  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1508  ast_channel_early_bridge(in, c);
1509  }
1510  if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK) && ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
1512  pa->sentringing++;
1513  }
1514  if (!sent_ring) {
1515  struct timeval now, then;
1516  int64_t diff;
1517 
1518  now = ast_tvnow();
1519 
1520  ast_channel_lock(in);
1522 
1523  then = ast_channel_creationtime(c);
1524  diff = ast_tvzero(then) ? 0 : ast_tvdiff_ms(now, then);
1525  set_duration_var(in, "RINGTIME", diff);
1526 
1528  ast_channel_unlock(in);
1529  sent_ring = 1;
1530  }
1531  }
1532  ast_channel_publish_dial(in, c, NULL, "RINGING");
1533  break;
1534  case AST_CONTROL_PROGRESS:
1535  ast_verb(3, "%s is making progress passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1536  /* Setup early media if appropriate */
1537  if (single && !caller_entertained
1538  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1539  ast_channel_early_bridge(in, c);
1540  }
1541  if (!ast_test_flag64(outgoing, OPT_RINGBACK)) {
1542  if (single || (!single && !pa->sentringing)) {
1544  }
1545  }
1546  if (!sent_progress) {
1547  struct timeval now, then;
1548  int64_t diff;
1549 
1550  now = ast_tvnow();
1551 
1552  ast_channel_lock(in);
1554 
1555  then = ast_channel_creationtime(c);
1556  diff = ast_tvzero(then) ? 0 : ast_tvdiff_ms(now, then);
1557  set_duration_var(in, "PROGRESSTIME", diff);
1558 
1560  ast_channel_unlock(in);
1561  sent_progress = 1;
1562  }
1563  if (!ast_strlen_zero(dtmf_progress)) {
1564  ast_verb(3,
1565  "Sending DTMF '%s' to the called party as result of receiving a PROGRESS message.\n",
1566  dtmf_progress);
1567  ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
1568  }
1569  ast_channel_publish_dial(in, c, NULL, "PROGRESS");
1570  break;
1571  case AST_CONTROL_VIDUPDATE:
1572  case AST_CONTROL_SRCUPDATE:
1573  case AST_CONTROL_SRCCHANGE:
1574  if (!single || caller_entertained) {
1575  break;
1576  }
1577  ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1579  ast_indicate(in, f->subclass.integer);
1580  break;
1583  ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(in));
1584  break;
1585  }
1586  if (!single) {
1588 
1589  ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n",
1595  o->pending_connected_update = 1;
1596  break;
1597  }
1598  if (ast_channel_connected_line_sub(c, in, f, 1) &&
1599  ast_channel_connected_line_macro(c, in, f, 1, 1)) {
1601  }
1602  break;
1603  case AST_CONTROL_AOC:
1604  {
1605  struct ast_aoc_decoded *decoded = ast_aoc_decode(f->data.ptr, f->datalen, o->chan);
1606  if (decoded && (ast_aoc_get_msg_type(decoded) == AST_AOC_S)) {
1608  o->aoc_s_rate_list = decoded;
1609  } else {
1610  ast_aoc_destroy_decoded(decoded);
1611  }
1612  }
1613  break;
1615  if (!single) {
1616  /*
1617  * Redirecting updates to the caller make sense only on single
1618  * calls.
1619  */
1620  break;
1621  }
1623  ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(in));
1624  break;
1625  }
1626  ast_verb(3, "%s redirecting info has changed, passing it to %s\n",
1628  if (ast_channel_redirecting_sub(c, in, f, 1) &&
1629  ast_channel_redirecting_macro(c, in, f, 1, 1)) {
1631  }
1632  pa->sentringing = 0;
1633  break;
1635  ast_verb(3, "%s is proceeding passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1636  if (single && !caller_entertained
1637  && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1638  ast_channel_early_bridge(in, c);
1639  }
1640  if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1642  ast_channel_publish_dial(in, c, NULL, "PROCEEDING");
1643  break;
1644  case AST_CONTROL_HOLD:
1645  /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1646  ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(c));
1648  break;
1649  case AST_CONTROL_UNHOLD:
1650  /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
1651  ast_verb(3, "Call on %s left from hold\n", ast_channel_name(c));
1653  break;
1654  case AST_CONTROL_OFFHOOK:
1655  case AST_CONTROL_FLASH:
1656  /* Ignore going off hook and flash */
1657  break;
1658  case AST_CONTROL_CC:
1659  if (!ignore_cc) {
1661  cc_frame_received = 1;
1662  }
1663  break;
1666  break;
1667  case -1:
1668  if (single && !caller_entertained) {
1669  ast_verb(3, "%s stopped sounds\n", ast_channel_name(c));
1670  ast_indicate(in, -1);
1671  pa->sentringing = 0;
1672  }
1673  break;
1674  default:
1675  ast_debug(1, "Dunno what to do with control type %d\n", f->subclass.integer);
1676  break;
1677  }
1678  break;
1679  case AST_FRAME_VIDEO:
1680  case AST_FRAME_VOICE:
1681  case AST_FRAME_IMAGE:
1682  if (caller_entertained) {
1683  break;
1684  }
1685  /* Fall through */
1686  case AST_FRAME_TEXT:
1687  if (single && ast_write(in, f)) {
1688  ast_log(LOG_WARNING, "Unable to write frametype: %u\n",
1689  f->frametype);
1690  }
1691  break;
1692  case AST_FRAME_HTML:
1693  if (single && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML)
1694  && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1695  ast_log(LOG_WARNING, "Unable to send URL\n");
1696  }
1697  break;
1698  default:
1699  break;
1700  }
1701  ast_frfree(f);
1702  } /* end for */
1703  if (winner == in) {
1704  struct ast_frame *f = ast_read(in);
1705 #if 0
1706  if (f && (f->frametype != AST_FRAME_VOICE))
1707  printf("Frame type: %d, %d\n", f->frametype, f->subclass);
1708  else if (!f || (f->frametype != AST_FRAME_VOICE))
1709  printf("Hangup received on %s\n", in->name);
1710 #endif
1711  if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP))) {
1712  /* Got hung up */
1713  *to = -1;
1714  strcpy(pa->status, "CANCEL");
1715  publish_dial_end_event(in, out_chans, NULL, pa->status);
1716  if (f) {
1717  if (f->data.uint32) {
1719  }
1720  ast_frfree(f);
1721  }
1722  if (is_cc_recall) {
1723  ast_cc_completed(in, "CC completed, although the caller hung up (cancelled)");
1724  }
1725  SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller hung up\n", ast_channel_name(in));
1726  }
1727 
1728  /* now f is guaranteed non-NULL */
1729  if (f->frametype == AST_FRAME_DTMF) {
1730  if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
1731  const char *context;
1732  ast_channel_lock(in);
1733  context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
1734  if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
1735  ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
1736  *to = 0;
1737  *result = f->subclass.integer;
1738  strcpy(pa->status, "CANCEL");
1739  publish_dial_end_event(in, out_chans, NULL, pa->status);
1740  ast_frfree(f);
1741  ast_channel_unlock(in);
1742  if (is_cc_recall) {
1743  ast_cc_completed(in, "CC completed, but the caller used DTMF to exit");
1744  }
1745  SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller pressed %c to end call\n",
1747  }
1748  ast_channel_unlock(in);
1749  }
1750 
1751  if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
1752  detect_disconnect(in, f->subclass.integer, &featurecode)) {
1753  ast_verb(3, "User requested call disconnect.\n");
1754  *to = 0;
1755  strcpy(pa->status, "CANCEL");
1756  publish_dial_end_event(in, out_chans, NULL, pa->status);
1757  ast_frfree(f);
1758  if (is_cc_recall) {
1759  ast_cc_completed(in, "CC completed, but the caller hung up with DTMF");
1760  }
1761  SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller requested disconnect\n",
1762  ast_channel_name(in));
1763  }
1764  }
1765 
1766  /* Send the frame from the in channel to all outgoing channels. */
1767  AST_LIST_TRAVERSE(out_chans, o, node) {
1768  if (!o->chan || !ast_test_flag64(o, DIAL_STILLGOING)) {
1769  /* This outgoing channel has died so don't send the frame to it. */
1770  continue;
1771  }
1772  switch (f->frametype) {
1773  case AST_FRAME_HTML:
1774  /* Forward HTML stuff */
1776  && ast_channel_sendhtml(o->chan, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1777  ast_log(LOG_WARNING, "Unable to send URL\n");
1778  }
1779  break;
1780  case AST_FRAME_VIDEO:
1781  case AST_FRAME_VOICE:
1782  case AST_FRAME_IMAGE:
1783  if (!single || caller_entertained) {
1784  /*
1785  * We are calling multiple parties or caller is being
1786  * entertained and has thus not been made compatible.
1787  * No need to check any other called parties.
1788  */
1789  goto skip_frame;
1790  }
1791  /* Fall through */
1792  case AST_FRAME_TEXT:
1793  case AST_FRAME_DTMF_BEGIN:
1794  case AST_FRAME_DTMF_END:
1795  if (ast_write(o->chan, f)) {
1796  ast_log(LOG_WARNING, "Unable to forward frametype: %u\n",
1797  f->frametype);
1798  }
1799  break;
1800  case AST_FRAME_CONTROL:
1801  switch (f->subclass.integer) {
1802  case AST_CONTROL_HOLD:
1803  ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(o->chan));
1805  break;
1806  case AST_CONTROL_UNHOLD:
1807  ast_verb(3, "Call on %s left from hold\n", ast_channel_name(o->chan));
1809  break;
1810  case AST_CONTROL_VIDUPDATE:
1811  case AST_CONTROL_SRCUPDATE:
1812  case AST_CONTROL_SRCCHANGE:
1813  if (!single || caller_entertained) {
1814  /*
1815  * We are calling multiple parties or caller is being
1816  * entertained and has thus not been made compatible.
1817  * No need to check any other called parties.
1818  */
1819  goto skip_frame;
1820  }
1821  ast_verb(3, "%s requested media update control %d, passing it to %s\n",
1824  break;
1827  ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(o->chan));
1828  break;
1829  }
1830  if (ast_channel_connected_line_sub(in, o->chan, f, 1) &&
1831  ast_channel_connected_line_macro(in, o->chan, f, 0, 1)) {
1833  }
1834  break;
1837  ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(o->chan));
1838  break;
1839  }
1840  if (ast_channel_redirecting_sub(in, o->chan, f, 1) &&
1841  ast_channel_redirecting_macro(in, o->chan, f, 0, 1)) {
1843  }
1844  break;
1845  default:
1846  /* We are not going to do anything with this frame. */
1847  goto skip_frame;
1848  }
1849  break;
1850  default:
1851  /* We are not going to do anything with this frame. */
1852  goto skip_frame;
1853  }
1854  }
1855 skip_frame:;
1856  ast_frfree(f);
1857  }
1858  }
1859 
1860  if (!*to || ast_check_hangup(in)) {
1861  ast_verb(3, "Nobody picked up in %d ms\n", orig);
1862  publish_dial_end_event(in, out_chans, NULL, "NOANSWER");
1863  }
1864 
1865  if (is_cc_recall) {
1866  ast_cc_completed(in, "Recall completed!");
1867  }
1868  SCOPE_EXIT_RTN_VALUE(peer, "%s: %s%s\n", ast_channel_name(in),
1869  peer ? "Answered by " : "No answer", peer ? ast_channel_name(peer) : "");
1870 }
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:3152
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode)
Definition: app_dial.c:1872
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:7375
#define ast_channel_lock(chan)
Definition: channel.h:2890
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:10292
#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
struct ast_stream_topology * answer_topology
Definition: channel.h:1100
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation...
Definition: channel.c:2031
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4291
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int congestion
Definition: app_dial.c:854
#define LOG_WARNING
Definition: logger.h:274
union ast_frame::@257 data
#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:9046
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:4271
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
#define ast_trace(level,...)
Definition: logger.h:876
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:4667
#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:2058
#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
<