Tue Apr 28 22:50:14 2009

Asterisk developer's documentation


app_dial.c File Reference

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

#include "asterisk.h"
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/options.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.h"
#include "asterisk/cdr.h"
#include "asterisk/manager.h"
#include "asterisk/privacy.h"
#include "asterisk/stringfields.h"
#include "asterisk/global_datastores.h"

Go to the source code of this file.

Data Structures

struct  dial_localuser

Defines

#define AST_MAX_WATCHERS   256
#define CAN_EARLY_BRIDGE(flags, chan, peer)
#define DIAL_NOFORWARDHTML   (1 << 31)
#define DIAL_STILLGOING   (1 << 30)
#define HANDLE_CAUSE(cause, chan)

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_PRIORITY_JUMP = (1 << 8), OPT_DURATION_LIMIT = (1 << 9), OPT_MUSICBACK = (1 << 10), OPT_CALLEE_MACRO = (1 << 11),
  OPT_SCREEN_NOINTRO = (1 << 12), OPT_SCREEN_NOCLID = (1 << 13), OPT_ORIGINAL_CLID = (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)
}
enum  {
  OPT_ARG_ANNOUNCE = 0, OPT_ARG_SENDDTMF, OPT_ARG_GOTO, OPT_ARG_DURATION_LIMIT,
  OPT_ARG_MUSICBACK, OPT_ARG_CALLEE_MACRO, OPT_ARG_PRIVACY, OPT_ARG_DURATION_STOP,
  OPT_ARG_OPERMODE, OPT_ARG_ARRAY_SIZE
}

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int dial_exec (struct ast_channel *chan, void *data)
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 hanguptree (struct dial_localuser *outgoing, struct ast_channel *exception)
static int load_module (void)
static int onedigit_goto (struct ast_channel *chan, const char *context, char exten, int pri)
static void replace_macro_delimiter (char *s)
static int retrydial_exec (struct ast_channel *chan, void *data)
static void senddialevent (struct ast_channel *src, struct ast_channel *dst)
static int unload_module (void)
static int valid_priv_reply (struct ast_flags *opts, int res)
static struct ast_channelwait_for_answer (struct ast_channel *in, struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int priority_jump, int *result)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, }
static char * app = "Dial"
static const struct ast_module_infoast_module_info = &__mod_info
static char * descrip
enum { ... }  dial_exec_option_args
enum { ... }  dial_exec_option_flags
static struct ast_app_option dial_exec_options [128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'f' ] = { .flag = OPT_FORCECLID }, [ '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 }, [ 'j' ] = { .flag = OPT_PRIORITY_JUMP }, [ '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 }, [ 'N' ] = { .flag = OPT_SCREEN_NOCLID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR },}
static char * rapp = "RetryDial"
static char * rdescrip
static char * rsynopsis = "Place a call, retrying on failure allowing optional exit extension."
static char * synopsis = "Place a call and connect to the current channel"


Detailed Description

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

Author:
Mark Spencer <markster@digium.com>

Definition in file app_dial.c.


Define Documentation

#define AST_MAX_WATCHERS   256

Definition at line 339 of file app_dial.c.

#define CAN_EARLY_BRIDGE ( flags,
chan,
peer   ) 

Value:

Definition at line 309 of file app_dial.c.

Referenced by wait_for_answer().

#define DIAL_NOFORWARDHTML   (1 << 31)

Definition at line 262 of file app_dial.c.

Referenced by wait_for_answer().

#define DIAL_STILLGOING   (1 << 30)

Definition at line 261 of file app_dial.c.

Referenced by wait_for_answer().

#define HANDLE_CAUSE ( cause,
chan   ) 

Definition at line 341 of file app_dial.c.

Referenced by wait_for_answer().


Enumeration Type Documentation

anonymous enum

Enumerator:
OPT_ANNOUNCE 
OPT_RESETCDR 
OPT_DTMF_EXIT 
OPT_SENDDTMF 
OPT_FORCECLID 
OPT_GO_ON 
OPT_CALLEE_HANGUP 
OPT_CALLER_HANGUP 
OPT_PRIORITY_JUMP 
OPT_DURATION_LIMIT 
OPT_MUSICBACK 
OPT_CALLEE_MACRO 
OPT_SCREEN_NOINTRO 
OPT_SCREEN_NOCLID 
OPT_ORIGINAL_CLID 
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 

Definition at line 230 of file app_dial.c.

00230      {
00231    OPT_ANNOUNCE =    (1 << 0),
00232    OPT_RESETCDR =    (1 << 1),
00233    OPT_DTMF_EXIT =      (1 << 2),
00234    OPT_SENDDTMF =    (1 << 3),
00235    OPT_FORCECLID =      (1 << 4),
00236    OPT_GO_ON =    (1 << 5),
00237    OPT_CALLEE_HANGUP =  (1 << 6),
00238    OPT_CALLER_HANGUP =  (1 << 7),
00239    OPT_PRIORITY_JUMP =  (1 << 8),
00240    OPT_DURATION_LIMIT = (1 << 9),
00241    OPT_MUSICBACK =      (1 << 10),
00242    OPT_CALLEE_MACRO =   (1 << 11),
00243    OPT_SCREEN_NOINTRO = (1 << 12),
00244    OPT_SCREEN_NOCLID =  (1 << 13),
00245    OPT_ORIGINAL_CLID =  (1 << 14),
00246    OPT_SCREENING =      (1 << 15),
00247    OPT_PRIVACY =     (1 << 16),
00248    OPT_RINGBACK =    (1 << 17),
00249    OPT_DURATION_STOP =  (1 << 18),
00250    OPT_CALLEE_TRANSFER =   (1 << 19),
00251    OPT_CALLER_TRANSFER =   (1 << 20),
00252    OPT_CALLEE_MONITOR = (1 << 21),
00253    OPT_CALLER_MONITOR = (1 << 22),
00254    OPT_GOTO =     (1 << 23),
00255    OPT_OPERMODE =       (1 << 24),
00256    OPT_CALLEE_PARK = (1 << 25),
00257    OPT_CALLER_PARK = (1 << 26),
00258    OPT_IGNORE_FORWARDING = (1 << 27),
00259 } dial_exec_option_flags;

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_PRIVACY 
OPT_ARG_DURATION_STOP 
OPT_ARG_OPERMODE 
OPT_ARG_ARRAY_SIZE 

Definition at line 264 of file app_dial.c.

00264      {
00265    OPT_ARG_ANNOUNCE = 0,
00266    OPT_ARG_SENDDTMF,
00267    OPT_ARG_GOTO,
00268    OPT_ARG_DURATION_LIMIT,
00269    OPT_ARG_MUSICBACK,
00270    OPT_ARG_CALLEE_MACRO,
00271    OPT_ARG_PRIVACY,
00272    OPT_ARG_DURATION_STOP,
00273    OPT_ARG_OPERMODE,
00274    /* note: this entry _MUST_ be the last one in the enum */
00275    OPT_ARG_ARRAY_SIZE,
00276 } dial_exec_option_args;


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 1945 of file app_dial.c.

static void __unreg_module ( void   )  [static]

Definition at line 1945 of file app_dial.c.

static int dial_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 1798 of file app_dial.c.

Referenced by load_module().

01799 {
01800    struct ast_flags peerflags;
01801 
01802    memset(&peerflags, 0, sizeof(peerflags));
01803 
01804    return dial_exec_full(chan, data, &peerflags, NULL);
01805 }

static void end_bridge_callback ( void *  data  )  [static]

Definition at line 809 of file app_dial.c.

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

Referenced by app_exec().

00810 {
00811    char buf[80];
00812    time_t end;
00813    struct ast_channel *chan = data;
00814 
00815    if (!chan->cdr) {
00816       return;
00817    }
00818 
00819    time(&end);
00820 
00821    ast_channel_lock(chan);
00822    if (chan->cdr->answer.tv_sec) {
00823       snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->answer.tv_sec);
00824       pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
00825    }
00826 
00827    if (chan->cdr->start.tv_sec) {
00828       snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->start.tv_sec);
00829       pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
00830    }
00831    ast_channel_unlock(chan);
00832 }

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

Definition at line 834 of file app_dial.c.

References ast_bridge_config::end_bridge_callback_data.

Referenced by app_exec().

00834                                                                                                                                               {
00835    bconfig->end_bridge_callback_data = originator;
00836 }

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

Definition at line 387 of file app_dial.c.

References ast_get_hint(), dial_localuser::chan, ast_channel::context, context, ast_channel::exten, exten, ast_channel::macrocontext, ast_channel::macroexten, and S_OR.

Referenced by wait_for_answer().

00388 {
00389    const char *context = S_OR(chan->macrocontext, chan->context);
00390    const char *exten = S_OR(chan->macroexten, chan->exten);
00391 
00392    return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
00393 }

static void hanguptree ( struct dial_localuser outgoing,
struct ast_channel exception 
) [static]

Definition at line 325 of file app_dial.c.

References ast_hangup(), dial_localuser::chan, free, and dial_localuser::next.

00326 {
00327    /* Hang up a tree of stuff */
00328    struct dial_localuser *oo;
00329    while (outgoing) {
00330       /* Hangup any existing lines we have open */
00331       if (outgoing->chan && (outgoing->chan != exception))
00332          ast_hangup(outgoing->chan);
00333       oo = outgoing;
00334       outgoing=outgoing->next;
00335       free(oo);
00336    }
00337 }

static int load_module ( void   )  [static]

Definition at line 1935 of file app_dial.c.

References ast_register_application(), dial_exec(), and retrydial_exec().

01936 {
01937    int res;
01938 
01939    res = ast_register_application(app, dial_exec, synopsis, descrip);
01940    res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
01941    
01942    return res;
01943 }

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

Definition at line 368 of file app_dial.c.

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

Referenced by retrydial_exec(), and wait_for_answer().

00369 {
00370    char rexten[2] = { exten, '\0' };
00371 
00372    if (context) {
00373       if (!ast_goto_if_exists(chan, context, rexten, pri))
00374          return 1;
00375    } else {
00376       if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
00377          return 1;
00378       else if (!ast_strlen_zero(chan->macrocontext)) {
00379          if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
00380             return 1;
00381       }
00382    }
00383    return 0;
00384 }

static void replace_macro_delimiter ( char *  s  )  [static]

Definition at line 789 of file app_dial.c.

00790 {
00791    for (; *s; s++)
00792       if (*s == '^')
00793          *s = '|';
00794 }

static int retrydial_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 1807 of file app_dial.c.

References AST_DIGIT_ANY, ast_fileexists(), AST_FLAG_MOH, ast_log(), ast_module_user_add, ast_module_user_remove, ast_moh_start(), ast_moh_stop(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_waitstream(), context, ast_channel::data, LOG_ERROR, LOG_WARNING, onedigit_goto(), OPT_DTMF_EXIT, and pbx_builtin_getvar_helper().

Referenced by load_module().

01808 {
01809    char *announce = NULL, *dialdata = NULL;
01810    const char *context = NULL;
01811    int sleep = 0, loops = 0, res = -1;
01812    struct ast_module_user *u;
01813    struct ast_flags peerflags;
01814    
01815    if (ast_strlen_zero(data)) {
01816       ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
01817       return -1;
01818    }  
01819 
01820    u = ast_module_user_add(chan);
01821 
01822    announce = ast_strdupa(data);
01823 
01824    memset(&peerflags, 0, sizeof(peerflags));
01825 
01826    if ((dialdata = strchr(announce, '|'))) {
01827       *dialdata++ = '\0';
01828       if (sscanf(dialdata, "%d", &sleep) == 1) {
01829          sleep *= 1000;
01830       } else {
01831          ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
01832          goto done;
01833       }
01834       if ((dialdata = strchr(dialdata, '|'))) {
01835          *dialdata++ = '\0';
01836          if (sscanf(dialdata, "%d", &loops) != 1) {
01837             ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
01838             goto done;
01839          }
01840       }
01841    }
01842    
01843    if ((dialdata = strchr(dialdata, '|'))) {
01844       *dialdata++ = '\0';
01845    } else {
01846       ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
01847       goto done;
01848    }
01849       
01850    if (sleep < 1000)
01851       sleep = 10000;
01852 
01853    if (!loops)
01854       loops = -1; /* run forever */
01855    
01856    context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
01857 
01858    res = 0;
01859    while (loops) {
01860       int continue_exec;
01861 
01862       chan->data = "Retrying";
01863       if (ast_test_flag(chan, AST_FLAG_MOH))
01864          ast_moh_stop(chan);
01865 
01866       res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
01867       if (continue_exec)
01868          break;
01869 
01870       if (res == 0) {
01871          if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
01872             if (!ast_strlen_zero(announce)) {
01873                if (ast_fileexists(announce, NULL, chan->language) > 0) {
01874                   if(!(res = ast_streamfile(chan, announce, chan->language)))                      
01875                      ast_waitstream(chan, AST_DIGIT_ANY);
01876                } else
01877                   ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01878             }
01879             if (!res && sleep) {
01880                if (!ast_test_flag(chan, AST_FLAG_MOH))
01881                   ast_moh_start(chan, NULL, NULL);
01882                res = ast_waitfordigit(chan, sleep);
01883             }
01884          } else {
01885             if (!ast_strlen_zero(announce)) {
01886                if (ast_fileexists(announce, NULL, chan->language) > 0) {
01887                   if (!(res = ast_streamfile(chan, announce, chan->language)))
01888                      res = ast_waitstream(chan, "");
01889                } else
01890                   ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01891             }
01892             if (sleep) {
01893                if (!ast_test_flag(chan, AST_FLAG_MOH))
01894                   ast_moh_start(chan, NULL, NULL);
01895                if (!res)
01896                   res = ast_waitfordigit(chan, sleep);
01897             }
01898          }
01899       }
01900 
01901       if (res < 0)
01902          break;
01903       else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
01904          if (onedigit_goto(chan, context, (char) res, 1)) {
01905             res = 0;
01906             break;
01907          }
01908       }
01909       loops--;
01910    }
01911    if (loops == 0)
01912       res = 0;
01913    else if (res == 1)
01914       res = 0;
01915 
01916    if (ast_test_flag(chan, AST_FLAG_MOH))
01917       ast_moh_stop(chan);
01918  done:
01919    ast_module_user_remove(u);
01920    return res;
01921 }

static void senddialevent ( struct ast_channel src,
struct ast_channel dst 
) [static]

Definition at line 395 of file app_dial.c.

References ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event(), ast_channel::name, S_OR, and ast_channel::uniqueid.

Referenced by wait_for_answer().

00396 {
00397    /* XXX do we need also CallerIDnum ? */
00398    manager_event(EVENT_FLAG_CALL, "Dial", 
00399             "Source: %s\r\n"
00400             "Destination: %s\r\n"
00401             "CallerID: %s\r\n"
00402             "CallerIDName: %s\r\n"
00403             "SrcUniqueID: %s\r\n"
00404             "DestUniqueID: %s\r\n",
00405             src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
00406             S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
00407             dst->uniqueid);
00408 }

static int unload_module ( void   )  [static]

Definition at line 1923 of file app_dial.c.

References ast_module_user_hangup_all, and ast_unregister_application().

01924 {
01925    int res;
01926 
01927    res = ast_unregister_application(app);
01928    res |= ast_unregister_application(rapp);
01929 
01930    ast_module_user_hangup_all();
01931    
01932    return res;
01933 }

static int valid_priv_reply ( struct ast_flags opts,
int  res 
) [static]

Definition at line 798 of file app_dial.c.

References ast_test_flag, OPT_PRIVACY, and OPT_SCREENING.

00799 {
00800    if (res < '1')
00801       return 0;
00802    if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
00803       return 1;
00804    if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
00805       return 1;
00806    return 0;
00807 }

static struct ast_channel* wait_for_answer ( struct ast_channel in,
struct dial_localuser outgoing,
int *  to,
struct ast_flags peerflags,
int *  sentringing,
char *  status,
size_t  statussize,
int  busystart,
int  nochanstart,
int  congestionstart,
int  priority_jump,
int *  result 
) [static]

Definition at line 410 of file app_dial.c.

References ast_channel::_state, ast_channel::accountcode, accountcode, ast_cdr::answer, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CDR_ANSWERED, ast_cdr_noanswer(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_make_compatible(), ast_channel_sendhtml(), ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_flags, ast_copy_string(), ast_deactivate_generator(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frfree, ast_goto_if_exists(), ast_hangup(), ast_indicate(), ast_indicate_data(), ast_log(), AST_MAX_EXTENSION, AST_MAX_WATCHERS, ast_opt_priority_jumping, ast_read(), ast_request(), ast_rtp_early_bridge(), ast_rtp_make_compatible(), ast_set_callerid(), AST_STATE_UP, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_verbose(), ast_waitfor_n(), ast_write(), CAN_EARLY_BRIDGE, ast_channel::cdr, ast_channel::cdrflags, dial_localuser::chan, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, context, ast_channel::context, DIAL_NOFORWARDHTML, DIAL_STILLGOING, ast_channel::dialcontext, ast_cdr::disposition, ast_channel::exten, f, free, get_cid_name(), HANDLE_CAUSE, ast_channel::hangupcause, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macroexten, ast_channel::name, ast_channel::nativeformats, dial_localuser::next, onedigit_goto(), OPT_CALLEE_HANGUP, OPT_CALLEE_MONITOR, OPT_CALLEE_PARK, OPT_CALLEE_TRANSFER, OPT_CALLER_HANGUP, OPT_CALLER_MONITOR, OPT_CALLER_PARK, OPT_CALLER_TRANSFER, OPT_DTMF_EXIT, OPT_FORCECLID, OPT_IGNORE_FORWARDING, OPT_MUSICBACK, OPT_ORIGINAL_CLID, OPT_RINGBACK, option_debug, option_verbose, pbx_builtin_getvar_helper(), S_OR, senddialevent(), ast_channel::tech, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3.

Referenced by try_calling().

00411 {
00412    int numbusy = busystart;
00413    int numcongestion = congestionstart;
00414    int numnochan = nochanstart;
00415    int prestart = busystart + congestionstart + nochanstart;
00416    int orig = *to;
00417    struct ast_channel *peer = NULL;
00418    /* single is set if only one destination is enabled */
00419    int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
00420    
00421    if (single) {
00422       /* Turn off hold music, etc */
00423       ast_deactivate_generator(in);
00424       /* If we are calling a single channel, make them compatible for in-band tone purpose */
00425       ast_channel_make_compatible(outgoing->chan, in);
00426    }
00427    
00428    
00429    while (*to && !peer) {
00430       struct dial_localuser *o;
00431       int pos = 0;   /* how many channels do we handle */
00432       int numlines = prestart;
00433       struct ast_channel *winner;
00434       struct ast_channel *watchers[AST_MAX_WATCHERS];
00435 
00436       watchers[pos++] = in;
00437       for (o = outgoing; o; o = o->next) {
00438          /* Keep track of important channels */
00439          if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
00440             watchers[pos++] = o->chan;
00441          numlines++;
00442       }
00443       if (pos == 1) {   /* only the input channel is available */
00444          if (numlines == (numbusy + numcongestion + numnochan)) {
00445             if (option_verbose > 2)
00446                ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
00447             if (numbusy)
00448                strcpy(status, "BUSY"); 
00449             else if (numcongestion)
00450                strcpy(status, "CONGESTION");
00451             else if (numnochan)
00452                strcpy(status, "CHANUNAVAIL");
00453             if (ast_opt_priority_jumping || priority_jump)
00454                ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
00455          } else {
00456             if (option_verbose > 2)
00457                ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
00458          }
00459          *to = 0;
00460          return NULL;
00461       }
00462       winner = ast_waitfor_n(watchers, pos, to);
00463       for (o = outgoing; o; o = o->next) {
00464          struct ast_frame *f;
00465          struct ast_channel *c = o->chan;
00466 
00467          if (c == NULL)
00468             continue;
00469          if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
00470             if (!peer) {
00471                if (option_verbose > 2)
00472                   ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
00473                peer = c;
00474                ast_copy_flags(peerflags, o,
00475                          OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00476                          OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00477                          OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00478                          OPT_CALLEE_PARK | OPT_CALLER_PARK |
00479                          DIAL_NOFORWARDHTML);
00480                ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
00481                ast_copy_string(c->exten, "", sizeof(c->exten));
00482             }
00483             continue;
00484          }
00485          if (c != winner)
00486             continue;
00487          if (!ast_strlen_zero(c->call_forward)) {
00488             char tmpchan[256];
00489             char *stuff;
00490             char *tech;
00491             int cause;
00492 
00493             ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
00494             if ((stuff = strchr(tmpchan, '/'))) {
00495                *stuff++ = '\0';
00496                tech = tmpchan;
00497             } else {
00498                const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
00499                snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
00500                stuff = tmpchan;
00501                tech = "Local";
00502             }
00503             /* Before processing channel, go ahead and check for forwarding */
00504             if (option_verbose > 2)
00505                ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
00506             /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
00507             if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) {
00508                if (option_verbose > 2)
00509                   ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
00510                c = o->chan = NULL;
00511                cause = AST_CAUSE_BUSY;
00512             } else {
00513                /* Setup parameters */
00514                if ((c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause))) {
00515                   if (single)
00516                      ast_channel_make_compatible(o->chan, in);
00517                   ast_channel_inherit_variables(in, o->chan);
00518                   ast_channel_datastore_inherit(in, o->chan);
00519                } else
00520                   ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
00521             }
00522             if (!c) {
00523                ast_clear_flag(o, DIAL_STILLGOING); 
00524                HANDLE_CAUSE(cause, in);
00525             } else {
00526                ast_rtp_make_compatible(c, in, single);
00527                if (c->cid.cid_num)
00528                   free(c->cid.cid_num);
00529                c->cid.cid_num = NULL;
00530                if (c->cid.cid_name)
00531                   free(c->cid.cid_name);
00532                c->cid.cid_name = NULL;
00533 
00534                if (ast_test_flag(o, OPT_FORCECLID)) {
00535                   c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
00536                   ast_string_field_set(c, accountcode, winner->accountcode);
00537                   c->cdrflags = winner->cdrflags;
00538                } else {
00539                   c->cid.cid_num = ast_strdup(in->cid.cid_num);
00540                   c->cid.cid_name = ast_strdup(in->cid.cid_name);
00541                   ast_string_field_set(c, accountcode, in->accountcode);
00542                   c->cdrflags = in->cdrflags;
00543                }
00544 
00545                if (in->cid.cid_ani) {
00546                   if (c->cid.cid_ani)
00547                      free(c->cid.cid_ani);
00548                   c->cid.cid_ani = ast_strdup(in->cid.cid_ani);
00549                }
00550                if (c->cid.cid_rdnis) 
00551                   free(c->cid.cid_rdnis);
00552                c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
00553                if (ast_call(c, tmpchan, 0)) {
00554                   ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
00555                   ast_clear_flag(o, DIAL_STILLGOING); 
00556                   ast_hangup(c);
00557                   c = o->chan = NULL;
00558                   numnochan++;
00559                } else {
00560                   senddialevent(in, c);
00561                   /* After calling, set callerid to extension */
00562                   if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
00563                      char cidname[AST_MAX_EXTENSION] = "";
00564                      ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
00565                   }
00566                }
00567                if (single) {
00568                   ast_indicate(in, -1);
00569                }
00570             }
00571             /* Hangup the original channel now, in case we needed it */
00572             ast_hangup(winner);
00573             continue;
00574          }
00575          f = ast_read(winner);
00576          if (!f) {
00577             in->hangupcause = c->hangupcause;
00578             ast_hangup(c);
00579             c = o->chan = NULL;
00580             ast_clear_flag(o, DIAL_STILLGOING);
00581             HANDLE_CAUSE(in->hangupcause, in);
00582             continue;
00583          }
00584          if (f->frametype == AST_FRAME_CONTROL) {
00585             switch(f->subclass) {
00586             case AST_CONTROL_ANSWER:
00587                /* This is our guy if someone answered. */
00588                if (!peer) {
00589                   if (option_verbose > 2)
00590                      ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
00591                   peer = c;
00592                   if (peer->cdr) {
00593                      peer->cdr->answer = ast_tvnow();
00594                      peer->cdr->disposition = AST_CDR_ANSWERED;
00595                   }
00596                   ast_copy_flags(peerflags, o,
00597                             OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00598                             OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00599                             OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00600                             OPT_CALLEE_PARK | OPT_CALLER_PARK |
00601                             DIAL_NOFORWARDHTML);
00602                   ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
00603                   ast_copy_string(c->exten, "", sizeof(c->exten));
00604                   /* Setup RTP early bridge if appropriate */
00605                   if (CAN_EARLY_BRIDGE(peerflags, in, peer))
00606                      ast_rtp_early_bridge(in, peer);
00607                }
00608                /* If call has been answered, then the eventual hangup is likely to be normal hangup */
00609                in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00610                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00611                break;
00612             case AST_CONTROL_BUSY:
00613                if (option_verbose > 2)
00614                   ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
00615                in->hangupcause = c->hangupcause;
00616                ast_hangup(c);
00617                c = o->chan = NULL;
00618                ast_clear_flag(o, DIAL_STILLGOING); 
00619                HANDLE_CAUSE(AST_CAUSE_BUSY, in);
00620                break;
00621             case AST_CONTROL_CONGESTION:
00622                if (option_verbose > 2)
00623                   ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
00624                in->hangupcause = c->hangupcause;
00625                ast_hangup(c);
00626                c = o->chan = NULL;
00627                ast_clear_flag(o, DIAL_STILLGOING);
00628                HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
00629                break;
00630             case AST_CONTROL_RINGING:
00631                if (option_verbose > 2)
00632                   ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
00633                /* Setup early media if appropriate */
00634                if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00635                   ast_rtp_early_bridge(in, c);
00636                if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
00637                   ast_indicate(in, AST_CONTROL_RINGING);
00638                   (*sentringing)++;
00639                }
00640                break;
00641             case AST_CONTROL_PROGRESS:
00642                if (option_verbose > 2)
00643                   ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
00644                /* Setup early media if appropriate */
00645                if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00646                   ast_rtp_early_bridge(in, c);
00647                if (!ast_test_flag(outgoing, OPT_RINGBACK))
00648                   ast_indicate(in, AST_CONTROL_PROGRESS);
00649                break;
00650             case AST_CONTROL_VIDUPDATE:
00651                if (option_verbose > 2)
00652                   ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
00653                ast_indicate(in, AST_CONTROL_VIDUPDATE);
00654                break;
00655             case AST_CONTROL_SRCUPDATE:
00656                if (option_verbose > 2)
00657                   ast_verbose (VERBOSE_PREFIX_3 "%s requested a source update, passing it to %s\n", c->name, in->name);
00658                ast_indicate(in, AST_CONTROL_SRCUPDATE);
00659                break;
00660             case AST_CONTROL_PROCEEDING:
00661                if (option_verbose > 2)
00662                   ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
00663                if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00664                   ast_rtp_early_bridge(in, c);
00665                if (!ast_test_flag(outgoing, OPT_RINGBACK))
00666                   ast_indicate(in, AST_CONTROL_PROCEEDING);
00667                break;
00668             case AST_CONTROL_HOLD:
00669                if (option_verbose > 2)
00670                   ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
00671                ast_indicate(in, AST_CONTROL_HOLD);
00672                break;
00673             case AST_CONTROL_UNHOLD:
00674                if (option_verbose > 2)
00675                   ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
00676                ast_indicate(in, AST_CONTROL_UNHOLD);
00677                break;
00678             case AST_CONTROL_OFFHOOK:
00679             case AST_CONTROL_FLASH:
00680                /* Ignore going off hook and flash */
00681                break;
00682             case -1:
00683                if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
00684                   if (option_verbose > 2)
00685                      ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
00686                   ast_indicate(in, -1);
00687                   (*sentringing) = 0;
00688                }
00689                break;
00690             default:
00691                if (option_debug)
00692                   ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
00693             }
00694          } else if (single) {
00695             /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
00696             if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
00697                if (ast_write(in, f)) 
00698                   ast_log(LOG_WARNING, "Unable to forward voice frame\n");
00699             } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
00700                if (ast_write(in, f))
00701                   ast_log(LOG_WARNING, "Unable to forward image\n");
00702             } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
00703                if (ast_write(in, f))
00704                   ast_log(LOG_WARNING, "Unable to send text\n");
00705             } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
00706                if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
00707                   ast_log(LOG_WARNING, "Unable to send URL\n");
00708             }
00709          }
00710          ast_frfree(f);
00711       } /* end for */
00712       if (winner == in) {
00713          struct ast_frame *f = ast_read(in);
00714 #if 0
00715          if (f && (f->frametype != AST_FRAME_VOICE))
00716             printf("Frame type: %d, %d\n", f->frametype, f->subclass);
00717          else if (!f || (f->frametype != AST_FRAME_VOICE))
00718             printf("Hangup received on %s\n", in->name);
00719 #endif
00720          if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
00721             /* Got hung up */
00722             *to = -1;
00723             ast_cdr_noanswer(in->cdr);
00724             strcpy(status, "CANCEL");
00725             if (f)
00726                ast_frfree(f);
00727             return NULL;
00728          }
00729 
00730          if (f && (f->frametype == AST_FRAME_DTMF)) {
00731             if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
00732                const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
00733                if (onedigit_goto(in, context, (char) f->subclass, 1)) {
00734                   if (option_verbose > 2)
00735                      ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
00736                   *to=0;
00737                   ast_cdr_noanswer(in->cdr);
00738                   *result = f->subclass;
00739                   strcpy(status, "CANCEL");
00740                   ast_frfree(f);
00741                   return NULL;
00742                }
00743             }
00744 
00745             if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) && 
00746                     (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
00747                if (option_verbose > 2)
00748                   ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
00749                *to=0;
00750                ast_cdr_noanswer(in->cdr);
00751                strcpy(status, "CANCEL");
00752                ast_frfree(f);
00753                return NULL;
00754             }
00755          }
00756 
00757          /* Forward HTML stuff */
00758          if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) 
00759             if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
00760                ast_log(LOG_WARNING, "Unable to send URL\n");
00761          
00762 
00763          if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END)))  {
00764             if (ast_write(outgoing->chan, f))
00765                ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
00766          }
00767          if (single && (f->frametype == AST_FRAME_CONTROL) && 
00768             ((f->subclass == AST_CONTROL_HOLD) || 
00769              (f->subclass == AST_CONTROL_UNHOLD) || 
00770              (f->subclass == AST_CONTROL_VIDUPDATE) ||
00771              (f->subclass == AST_CONTROL_SRCUPDATE))) {
00772             if (option_verbose > 2)
00773                ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
00774             ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
00775          }
00776          ast_frfree(f);
00777       }
00778       if (!*to && (option_verbose > 2))
00779          ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
00780       if (!*to || ast_check_hangup(in)) {
00781          ast_cdr_noanswer(in->cdr);
00782       }
00783       
00784    }
00785    
00786    return peer;
00787 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, } [static]

Definition at line 1945 of file app_dial.c.

char* app = "Dial" [static]

Definition at line 71 of file app_dial.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 1945 of file app_dial.c.

char* descrip [static]

Definition at line 75 of file app_dial.c.

enum { ... } dial_exec_option_args

enum { ... } dial_exec_option_flags

struct ast_app_option dial_exec_options[128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'f' ] = { .flag = OPT_FORCECLID }, [ '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 }, [ 'j' ] = { .flag = OPT_PRIORITY_JUMP }, [ '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 }, [ 'N' ] = { .flag = OPT_SCREEN_NOCLID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR },} [static]

Definition at line 307 of file app_dial.c.

char* rapp = "RetryDial" [static]

Definition at line 215 of file app_dial.c.

char* rdescrip [static]

Definition at line 217 of file app_dial.c.

char* rsynopsis = "Place a call, retrying on failure allowing optional exit extension." [static]

Definition at line 216 of file app_dial.c.

char* synopsis = "Place a call and connect to the current channel" [static]

Definition at line 73 of file app_dial.c.


Generated on Tue Apr 28 22:50:14 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7