Sat Aug 6 00:39:34 2011

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

#define CAN_EARLY_BRIDGE ( flags,
chan,
peer   ) 

Value:

Definition at line 315 of file app_dial.c.

Referenced by wait_for_answer().

#define DIAL_NOFORWARDHTML   (1 << 31)

Definition at line 267 of file app_dial.c.

Referenced by wait_for_answer().

#define DIAL_STILLGOING   (1 << 30)

Definition at line 266 of file app_dial.c.

Referenced by wait_for_answer().

#define HANDLE_CAUSE ( cause,
chan   ) 

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

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

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


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 2083 of file app_dial.c.

static void __unreg_module ( void   )  [static]

Definition at line 2083 of file app_dial.c.

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

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

00826 {
00827    struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
00828    struct ast_call_feature feature = { 0, };
00829    char *tmp;
00830    int res;
00831 
00832    if ((strlen(featurecode)) < (len - 2)) { 
00833       tmp = &featurecode[strlen(featurecode)];
00834       tmp[0] = code;
00835       tmp[1] = '\0';
00836    } else {
00837       featurecode[0] = 0;
00838       return -1; /* no room in featurecode buffer */
00839    }
00840 
00841    res = ast_feature_detect(chan, &features, featurecode, &feature);
00842 
00843    if (res != FEATURE_RETURN_STOREDIGITS) {
00844       featurecode[0] = '\0';
00845    }
00846    if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
00847       return 1;
00848    }
00849 
00850    return 0;
00851 }

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

Definition at line 1936 of file app_dial.c.

Referenced by load_module().

01937 {
01938    struct ast_flags peerflags;
01939 
01940    memset(&peerflags, 0, sizeof(peerflags));
01941 
01942    return dial_exec_full(chan, data, &peerflags, NULL);
01943 }

static void end_bridge_callback ( void *  data  )  [static]

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

00874 {
00875    char buf[80];
00876    time_t end;
00877    struct ast_channel *chan = data;
00878 
00879    if (!chan->cdr) {
00880       return;
00881    }
00882 
00883    time(&end);
00884 
00885    ast_channel_lock(chan);
00886    if (chan->cdr->answer.tv_sec) {
00887       snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->answer.tv_sec);
00888       pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
00889    }
00890 
00891    if (chan->cdr->start.tv_sec) {
00892       snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->start.tv_sec);
00893       pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
00894    }
00895    ast_channel_unlock(chan);
00896 }

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

Definition at line 898 of file app_dial.c.

References ast_bridge_config::end_bridge_callback_data.

Referenced by app_exec().

00898                                                                                                                                               {
00899    bconfig->end_bridge_callback_data = originator;
00900 }

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

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

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

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

Definition at line 332 of file app_dial.c.

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

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

static int load_module ( void   )  [static]

Definition at line 2073 of file app_dial.c.

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

02074 {
02075    int res;
02076 
02077    res = ast_register_application(app, dial_exec, synopsis, descrip);
02078    res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
02079    
02080    return res;
02081 }

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

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

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

static void replace_macro_delimiter ( char *  s  )  [static]

Definition at line 853 of file app_dial.c.

00854 {
00855    for (; *s; s++)
00856       if (*s == '^')
00857          *s = '|';
00858 }

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

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

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

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

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

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

static int unload_module ( void   )  [static]

Definition at line 2061 of file app_dial.c.

References ast_module_user_hangup_all, and ast_unregister_application().

02062 {
02063    int res;
02064 
02065    res = ast_unregister_application(app);
02066    res |= ast_unregister_application(rapp);
02067 
02068    ast_module_user_hangup_all();
02069    
02070    return res;
02071 }

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

Definition at line 862 of file app_dial.c.

References ast_test_flag, OPT_PRIVACY, and OPT_SCREENING.

00863 {
00864    if (res < '1')
00865       return 0;
00866    if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
00867       return 1;
00868    if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
00869       return 1;
00870    return 0;
00871 }

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 422 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_failed(), 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().

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


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

char* rapp = "RetryDial" [static]

Definition at line 220 of file app_dial.c.

char* rdescrip [static]

Definition at line 222 of file app_dial.c.

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

Definition at line 221 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 Sat Aug 6 00:39:34 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7