Wed Oct 14 15:02:00 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 detect_disconnect (struct ast_channel *chan, char code, char *featurecode, int len)
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 = "361d7bb937402d51e4658efb5b4d76e4" , .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 1984 of file app_dial.c.

static void __unreg_module ( void   )  [static]

Definition at line 1984 of file app_dial.c.

static int detect_disconnect ( struct ast_channel chan,
char  code,
char *  featurecode,
int  len 
) [static]

Definition at line 799 of file app_dial.c.

References ast_feature_detect(), AST_FEATURE_DISCONNECT, ast_call_feature::feature_mask, and FEATURE_RETURN_STOREDIGITS.

Referenced by wait_for_answer().

00800 {
00801    struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
00802    struct ast_call_feature feature = { 0, };
00803    char *tmp;
00804    int res;
00805 
00806    if ((strlen(featurecode)) < (len - 2)) { 
00807       tmp = &featurecode[strlen(featurecode)];
00808       tmp[0] = code;
00809       tmp[1] = '\0';
00810    } else {
00811       featurecode[0] = 0;
00812       return -1; /* no room in featurecode buffer */
00813    }
00814 
00815    res = ast_feature_detect(chan, &features, featurecode, &feature);
00816 
00817    if (res != FEATURE_RETURN_STOREDIGITS) {
00818       featurecode[0] = '\0';
00819    }
00820    if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
00821       return 1;
00822    }
00823 
00824    return 0;
00825 }

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

Definition at line 1837 of file app_dial.c.

Referenced by load_module().

01838 {
01839    struct ast_flags peerflags;
01840 
01841    memset(&peerflags, 0, sizeof(peerflags));
01842 
01843    return dial_exec_full(chan, data, &peerflags, NULL);
01844 }

static void end_bridge_callback ( void *  data  )  [static]

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

00848 {
00849    char buf[80];
00850    time_t end;
00851    struct ast_channel *chan = data;
00852 
00853    if (!chan->cdr) {
00854       return;
00855    }
00856 
00857    time(&end);
00858 
00859    ast_channel_lock(chan);
00860    if (chan->cdr->answer.tv_sec) {
00861       snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->answer.tv_sec);
00862       pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
00863    }
00864 
00865    if (chan->cdr->start.tv_sec) {
00866       snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->start.tv_sec);
00867       pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
00868    }
00869    ast_channel_unlock(chan);
00870 }

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

Definition at line 872 of file app_dial.c.

References ast_bridge_config::end_bridge_callback_data.

Referenced by app_exec().

00872                                                                                                                                               {
00873    bconfig->end_bridge_callback_data = originator;
00874 }

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

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

00393 {
00394    const char *context = S_OR(chan->macrocontext, chan->context);
00395    const char *exten = S_OR(chan->macroexten, chan->exten);
00396 
00397    return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
00398 }

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

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

01975 {
01976    int res;
01977 
01978    res = ast_register_application(app, dial_exec, synopsis, descrip);
01979    res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
01980    
01981    return res;
01982 }

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

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

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

static void replace_macro_delimiter ( char *  s  )  [static]

Definition at line 827 of file app_dial.c.

00828 {
00829    for (; *s; s++)
00830       if (*s == '^')
00831          *s = '|';
00832 }

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

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

01847 {
01848    char *announce = NULL, *dialdata = NULL;
01849    const char *context = NULL;
01850    int sleep = 0, loops = 0, res = -1;
01851    struct ast_module_user *u;
01852    struct ast_flags peerflags;
01853    
01854    if (ast_strlen_zero(data)) {
01855       ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
01856       return -1;
01857    }  
01858 
01859    u = ast_module_user_add(chan);
01860 
01861    announce = ast_strdupa(data);
01862 
01863    memset(&peerflags, 0, sizeof(peerflags));
01864 
01865    if ((dialdata = strchr(announce, '|'))) {
01866       *dialdata++ = '\0';
01867       if (sscanf(dialdata, "%30d", &sleep) == 1) {
01868          sleep *= 1000;
01869       } else {
01870          ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
01871          goto done;
01872       }
01873       if ((dialdata = strchr(dialdata, '|'))) {
01874          *dialdata++ = '\0';
01875          if (sscanf(dialdata, "%30d", &loops) != 1) {
01876             ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
01877             goto done;
01878          }
01879       }
01880    }
01881    
01882    if (dialdata && (dialdata = strchr(dialdata, '|'))) {
01883       *dialdata++ = '\0';
01884    } else {
01885       ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
01886       goto done;
01887    }
01888       
01889    if (sleep < 1000)
01890       sleep = 10000;
01891 
01892    if (!loops)
01893       loops = -1; /* run forever */
01894    
01895    context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
01896 
01897    res = 0;
01898    while (loops) {
01899       int continue_exec;
01900 
01901       chan->data = "Retrying";
01902       if (ast_test_flag(chan, AST_FLAG_MOH))
01903          ast_moh_stop(chan);
01904 
01905       res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
01906       if (continue_exec)
01907          break;
01908 
01909       if (res == 0) {
01910          if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
01911             if (!ast_strlen_zero(announce)) {
01912                if (ast_fileexists(announce, NULL, chan->language) > 0) {
01913                   if(!(res = ast_streamfile(chan, announce, chan->language)))                      
01914                      ast_waitstream(chan, AST_DIGIT_ANY);
01915                } else
01916                   ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01917             }
01918             if (!res && sleep) {
01919                if (!ast_test_flag(chan, AST_FLAG_MOH))
01920                   ast_moh_start(chan, NULL, NULL);
01921                res = ast_waitfordigit(chan, sleep);
01922             }
01923          } else {
01924             if (!ast_strlen_zero(announce)) {
01925                if (ast_fileexists(announce, NULL, chan->language) > 0) {
01926                   if (!(res = ast_streamfile(chan, announce, chan->language)))
01927                      res = ast_waitstream(chan, "");
01928                } else
01929                   ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01930             }
01931             if (sleep) {
01932                if (!ast_test_flag(chan, AST_FLAG_MOH))
01933                   ast_moh_start(chan, NULL, NULL);
01934                if (!res)
01935                   res = ast_waitfordigit(chan, sleep);
01936             }
01937          }
01938       }
01939 
01940       if (res < 0)
01941          break;
01942       else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
01943          if (onedigit_goto(chan, context, (char) res, 1)) {
01944             res = 0;
01945             break;
01946          }
01947       }
01948       loops--;
01949    }
01950    if (loops == 0)
01951       res = 0;
01952    else if (res == 1)
01953       res = 0;
01954 
01955    if (ast_test_flag(chan, AST_FLAG_MOH))
01956       ast_moh_stop(chan);
01957  done:
01958    ast_module_user_remove(u);
01959    return res;
01960 }

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

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

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

static int unload_module ( void   )  [static]

Definition at line 1962 of file app_dial.c.

References ast_module_user_hangup_all, and ast_unregister_application().

01963 {
01964    int res;
01965 
01966    res = ast_unregister_application(app);
01967    res |= ast_unregister_application(rapp);
01968 
01969    ast_module_user_hangup_all();
01970    
01971    return res;
01972 }

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

Definition at line 836 of file app_dial.c.

References ast_test_flag, OPT_PRIVACY, and OPT_SCREENING.

00837 {
00838    if (res < '1')
00839       return 0;
00840    if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
00841       return 1;
00842    if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
00843       return 1;
00844    return 0;
00845 }

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 415 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, detect_disconnect(), DIAL_NOFORWARDHTML, DIAL_STILLGOING, ast_channel::dialcontext, ast_cdr::disposition, ast_channel::exten, f, FEATURE_MAX_LEN, 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().

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


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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 1984 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 1984 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 Wed Oct 14 15:02:00 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7