Thu Mar 25 10:39:19 2010

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_SCREEN_NOINTRO, 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 , .arg_index = OPT_ARG_SCREEN_NOINTRO + 1 }, [ '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 344 of file app_dial.c.

#define CAN_EARLY_BRIDGE ( flags,
chan,
peer   ) 

Value:

Definition at line 313 of file app_dial.c.

Referenced by wait_for_answer().

#define DIAL_NOFORWARDHTML   (1 << 31)

Definition at line 265 of file app_dial.c.

Referenced by wait_for_answer().

#define DIAL_STILLGOING   (1 << 30)

Definition at line 264 of file app_dial.c.

Referenced by wait_for_answer().

#define HANDLE_CAUSE ( cause,
chan   ) 

Definition at line 346 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 233 of file app_dial.c.

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

Definition at line 267 of file app_dial.c.

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


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 2060 of file app_dial.c.

static void __unreg_module ( void   )  [static]

Definition at line 2060 of file app_dial.c.

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

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

00812 {
00813    struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
00814    struct ast_call_feature feature = { 0, };
00815    char *tmp;
00816    int res;
00817 
00818    if ((strlen(featurecode)) < (len - 2)) { 
00819       tmp = &featurecode[strlen(featurecode)];
00820       tmp[0] = code;
00821       tmp[1] = '\0';
00822    } else {
00823       featurecode[0] = 0;
00824       return -1; /* no room in featurecode buffer */
00825    }
00826 
00827    res = ast_feature_detect(chan, &features, featurecode, &feature);
00828 
00829    if (res != FEATURE_RETURN_STOREDIGITS) {
00830       featurecode[0] = '\0';
00831    }
00832    if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
00833       return 1;
00834    }
00835 
00836    return 0;
00837 }

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

Definition at line 1913 of file app_dial.c.

Referenced by load_module().

01914 {
01915    struct ast_flags peerflags;
01916 
01917    memset(&peerflags, 0, sizeof(peerflags));
01918 
01919    return dial_exec_full(chan, data, &peerflags, NULL);
01920 }

static void end_bridge_callback ( void *  data  )  [static]

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

00860 {
00861    char buf[80];
00862    time_t end;
00863    struct ast_channel *chan = data;
00864 
00865    if (!chan->cdr) {
00866       return;
00867    }
00868 
00869    time(&end);
00870 
00871    ast_channel_lock(chan);
00872    if (chan->cdr->answer.tv_sec) {
00873       snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->answer.tv_sec);
00874       pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
00875    }
00876 
00877    if (chan->cdr->start.tv_sec) {
00878       snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->start.tv_sec);
00879       pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
00880    }
00881    ast_channel_unlock(chan);
00882 }

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

Definition at line 884 of file app_dial.c.

References ast_bridge_config::end_bridge_callback_data.

Referenced by app_exec().

00884                                                                                                                                               {
00885    bconfig->end_bridge_callback_data = originator;
00886 }

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

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

00398 {
00399    const char *context = S_OR(chan->macrocontext, chan->context);
00400    const char *exten = S_OR(chan->macroexten, chan->exten);
00401 
00402    return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
00403 }

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

Definition at line 330 of file app_dial.c.

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

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

static int load_module ( void   )  [static]

Definition at line 2050 of file app_dial.c.

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

02051 {
02052    int res;
02053 
02054    res = ast_register_application(app, dial_exec, synopsis, descrip);
02055    res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
02056    
02057    return res;
02058 }

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

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

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

static void replace_macro_delimiter ( char *  s  )  [static]

Definition at line 839 of file app_dial.c.

00840 {
00841    for (; *s; s++)
00842       if (*s == '^')
00843          *s = '|';
00844 }

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

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

01923 {
01924    char *announce = NULL, *dialdata = NULL;
01925    const char *context = NULL;
01926    int sleep = 0, loops = 0, res = -1;
01927    struct ast_module_user *u;
01928    struct ast_flags peerflags;
01929    
01930    if (ast_strlen_zero(data)) {
01931       ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
01932       return -1;
01933    }  
01934 
01935    u = ast_module_user_add(chan);
01936 
01937    announce = ast_strdupa(data);
01938 
01939    memset(&peerflags, 0, sizeof(peerflags));
01940 
01941    if ((dialdata = strchr(announce, '|'))) {
01942       *dialdata++ = '\0';
01943       if (sscanf(dialdata, "%30d", &sleep) == 1) {
01944          sleep *= 1000;
01945       } else {
01946          ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
01947          goto done;
01948       }
01949       if ((dialdata = strchr(dialdata, '|'))) {
01950          *dialdata++ = '\0';
01951          if (sscanf(dialdata, "%30d", &loops) != 1) {
01952             ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
01953             goto done;
01954          }
01955       }
01956    }
01957    
01958    if (dialdata && (dialdata = strchr(dialdata, '|'))) {
01959       *dialdata++ = '\0';
01960    } else {
01961       ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
01962       goto done;
01963    }
01964       
01965    if (sleep < 1000)
01966       sleep = 10000;
01967 
01968    if (!loops)
01969       loops = -1; /* run forever */
01970    
01971    context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
01972 
01973    res = 0;
01974    while (loops) {
01975       int continue_exec;
01976 
01977       chan->data = "Retrying";
01978       if (ast_test_flag(chan, AST_FLAG_MOH))
01979          ast_moh_stop(chan);
01980 
01981       res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
01982       if (continue_exec)
01983          break;
01984 
01985       if (res == 0) {
01986          if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
01987             if (!ast_strlen_zero(announce)) {
01988                if (ast_fileexists(announce, NULL, chan->language) > 0) {
01989                   if(!(res = ast_streamfile(chan, announce, chan->language)))                      
01990                      ast_waitstream(chan, AST_DIGIT_ANY);
01991                } else
01992                   ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01993             }
01994             if (!res && sleep) {
01995                if (!ast_test_flag(chan, AST_FLAG_MOH))
01996                   ast_moh_start(chan, NULL, NULL);
01997                res = ast_waitfordigit(chan, sleep);
01998             }
01999          } else {
02000             if (!ast_strlen_zero(announce)) {
02001                if (ast_fileexists(announce, NULL, chan->language) > 0) {
02002                   if (!(res = ast_streamfile(chan, announce, chan->language)))
02003                      res = ast_waitstream(chan, "");
02004                } else
02005                   ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
02006             }
02007             if (sleep) {
02008                if (!ast_test_flag(chan, AST_FLAG_MOH))
02009                   ast_moh_start(chan, NULL, NULL);
02010                if (!res)
02011                   res = ast_waitfordigit(chan, sleep);
02012             }
02013          }
02014       }
02015 
02016       if (res < 0)
02017          break;
02018       else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
02019          if (onedigit_goto(chan, context, (char) res, 1)) {
02020             res = 0;
02021             break;
02022          }
02023       }
02024       loops--;
02025    }
02026    if (loops == 0)
02027       res = 0;
02028    else if (res == 1)
02029       res = 0;
02030 
02031    if (ast_test_flag(chan, AST_FLAG_MOH))
02032       ast_moh_stop(chan);
02033  done:
02034    ast_module_user_remove(u);
02035    return res;
02036 }

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

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

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

static int unload_module ( void   )  [static]

Definition at line 2038 of file app_dial.c.

References ast_module_user_hangup_all, and ast_unregister_application().

02039 {
02040    int res;
02041 
02042    res = ast_unregister_application(app);
02043    res |= ast_unregister_application(rapp);
02044 
02045    ast_module_user_hangup_all();
02046    
02047    return res;
02048 }

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

Definition at line 848 of file app_dial.c.

References ast_test_flag, OPT_PRIVACY, and OPT_SCREENING.

00849 {
00850    if (res < '1')
00851       return 0;
00852    if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
00853       return 1;
00854    if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
00855       return 1;
00856    return 0;
00857 }

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 420 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().

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


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 2060 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 2060 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 , .arg_index = OPT_ARG_SCREEN_NOINTRO + 1 }, [ '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 311 of file app_dial.c.

char* rapp = "RetryDial" [static]

Definition at line 218 of file app_dial.c.

char* rdescrip [static]

Definition at line 220 of file app_dial.c.

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

Definition at line 219 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 Thu Mar 25 10:39:19 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7