Thu Feb 5 16:25:53 2009

Asterisk developer's documentation


app_dial.c File Reference

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

#include "asterisk.h"
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/say.h"
#include "asterisk/config.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/callerid.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/causes.h"
#include "asterisk/rtp.h"
#include "asterisk/cdr.h"
#include "asterisk/manager.h"
#include "asterisk/privacy.h"
#include "asterisk/stringfields.h"
#include "asterisk/global_datastores.h"

Go to the source code of this file.

Data Structures

struct  dial_localuser

Defines

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

Enumerations

enum  {
  OPT_ANNOUNCE = (1 << 0), OPT_RESETCDR = (1 << 1), OPT_DTMF_EXIT = (1 << 2), OPT_SENDDTMF = (1 << 3),
  OPT_FORCECLID = (1 << 4), OPT_GO_ON = (1 << 5), OPT_CALLEE_HANGUP = (1 << 6), OPT_CALLER_HANGUP = (1 << 7),
  OPT_PRIORITY_JUMP = (1 << 8), OPT_DURATION_LIMIT = (1 << 9), OPT_MUSICBACK = (1 << 10), OPT_CALLEE_MACRO = (1 << 11),
  OPT_SCREEN_NOINTRO = (1 << 12), OPT_SCREEN_NOCLID = (1 << 13), OPT_ORIGINAL_CLID = (1 << 14), OPT_SCREENING = (1 << 15),
  OPT_PRIVACY = (1 << 16), OPT_RINGBACK = (1 << 17), OPT_DURATION_STOP = (1 << 18), OPT_CALLEE_TRANSFER = (1 << 19),
  OPT_CALLER_TRANSFER = (1 << 20), OPT_CALLEE_MONITOR = (1 << 21), OPT_CALLER_MONITOR = (1 << 22), OPT_GOTO = (1 << 23),
  OPT_OPERMODE = (1 << 24), OPT_CALLEE_PARK = (1 << 25), OPT_CALLER_PARK = (1 << 26), OPT_IGNORE_FORWARDING = (1 << 27)
}
enum  {
  OPT_ARG_ANNOUNCE = 0, OPT_ARG_SENDDTMF, OPT_ARG_GOTO, OPT_ARG_DURATION_LIMIT,
  OPT_ARG_MUSICBACK, OPT_ARG_CALLEE_MACRO, OPT_ARG_PRIVACY, OPT_ARG_DURATION_STOP,
  OPT_ARG_OPERMODE, OPT_ARG_ARRAY_SIZE
}

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int dial_exec (struct ast_channel *chan, void *data)
static void end_bridge_callback (void *data)
static void end_bridge_callback_data_fixup (struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
static const char * get_cid_name (char *name, int namelen, struct ast_channel *chan)
static void hanguptree (struct dial_localuser *outgoing, struct ast_channel *exception)
static int load_module (void)
static int onedigit_goto (struct ast_channel *chan, const char *context, char exten, int pri)
static void replace_macro_delimiter (char *s)
static int retrydial_exec (struct ast_channel *chan, void *data)
static void senddialevent (struct ast_channel *src, struct ast_channel *dst)
static void set_dial_features (struct ast_flags *opts, struct ast_dial_features *features)
static int unload_module (void)
static int valid_priv_reply (struct ast_flags *opts, int res)
static struct ast_channelwait_for_answer (struct ast_channel *in, struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int priority_jump, int *result)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Dialing Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, }
static char * app = "Dial"
static const struct ast_module_infoast_module_info = &__mod_info
static char * descrip
enum { ... }  dial_exec_option_args
enum { ... }  dial_exec_option_flags
static struct ast_app_option dial_exec_options [128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'f' ] = { .flag = OPT_FORCECLID }, [ 'g' ] = { .flag = OPT_GO_ON }, [ 'G' ] = { .flag = OPT_GOTO , .arg_index = OPT_ARG_GOTO + 1 }, [ 'h' ] = { .flag = OPT_CALLEE_HANGUP }, [ 'H' ] = { .flag = OPT_CALLER_HANGUP }, [ 'i' ] = { .flag = OPT_IGNORE_FORWARDING }, [ 'j' ] = { .flag = OPT_PRIORITY_JUMP }, [ 'k' ] = { .flag = OPT_CALLEE_PARK }, [ 'K' ] = { .flag = OPT_CALLER_PARK }, [ 'L' ] = { .flag = OPT_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, [ 'm' ] = { .flag = OPT_MUSICBACK , .arg_index = OPT_ARG_MUSICBACK + 1 }, [ 'M' ] = { .flag = OPT_CALLEE_MACRO , .arg_index = OPT_ARG_CALLEE_MACRO + 1 }, [ 'n' ] = { .flag = OPT_SCREEN_NOINTRO }, [ 'N' ] = { .flag = OPT_SCREEN_NOCLID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR },}
static char * rapp = "RetryDial"
static char * rdescrip
static char * rsynopsis = "Place a call, retrying on failure allowing optional exit extension."
static char * synopsis = "Place a call and connect to the current channel"


Detailed Description

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

Author:
Mark Spencer <markster@digium.com>

Definition in file app_dial.c.


Define Documentation

#define AST_MAX_WATCHERS   256

Definition at line 339 of file app_dial.c.

#define CAN_EARLY_BRIDGE ( flags,
chan,
peer   ) 

Value:

Definition at line 309 of file app_dial.c.

Referenced by wait_for_answer().

#define DIAL_NOFORWARDHTML   (1 << 31)

Definition at line 262 of file app_dial.c.

Referenced by wait_for_answer().

#define DIAL_STILLGOING   (1 << 30)

Definition at line 261 of file app_dial.c.

Referenced by wait_for_answer().

#define HANDLE_CAUSE ( cause,
chan   ) 

Definition at line 341 of file app_dial.c.

Referenced by wait_for_answer().


Enumeration Type Documentation

anonymous enum

Enumerator:
OPT_ANNOUNCE 
OPT_RESETCDR 
OPT_DTMF_EXIT 
OPT_SENDDTMF 
OPT_FORCECLID 
OPT_GO_ON 
OPT_CALLEE_HANGUP 
OPT_CALLER_HANGUP 
OPT_PRIORITY_JUMP 
OPT_DURATION_LIMIT 
OPT_MUSICBACK 
OPT_CALLEE_MACRO 
OPT_SCREEN_NOINTRO 
OPT_SCREEN_NOCLID 
OPT_ORIGINAL_CLID 
OPT_SCREENING 
OPT_PRIVACY 
OPT_RINGBACK 
OPT_DURATION_STOP 
OPT_CALLEE_TRANSFER 
OPT_CALLER_TRANSFER 
OPT_CALLEE_MONITOR 
OPT_CALLER_MONITOR 
OPT_GOTO 
OPT_OPERMODE 
OPT_CALLEE_PARK 
OPT_CALLER_PARK 
OPT_IGNORE_FORWARDING 

Definition at line 230 of file app_dial.c.

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

anonymous enum

Enumerator:
OPT_ARG_ANNOUNCE 
OPT_ARG_SENDDTMF 
OPT_ARG_GOTO 
OPT_ARG_DURATION_LIMIT 
OPT_ARG_MUSICBACK 
OPT_ARG_CALLEE_MACRO 
OPT_ARG_PRIVACY 
OPT_ARG_DURATION_STOP 
OPT_ARG_OPERMODE 
OPT_ARG_ARRAY_SIZE 

Definition at line 264 of file app_dial.c.

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


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 2015 of file app_dial.c.

static void __unreg_module ( void   )  [static]

Definition at line 2015 of file app_dial.c.

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

Definition at line 1868 of file app_dial.c.

Referenced by load_module().

01869 {
01870    struct ast_flags peerflags;
01871 
01872    memset(&peerflags, 0, sizeof(peerflags));
01873 
01874    return dial_exec_full(chan, data, &peerflags, NULL);
01875 }

static void end_bridge_callback ( void *  data  )  [static]

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

00836 {
00837    char buf[80];
00838    time_t end;
00839    struct ast_channel *chan = data;
00840 
00841    if (!chan->cdr) {
00842       return;
00843    }
00844 
00845    time(&end);
00846 
00847    ast_channel_lock(chan);
00848    if (chan->cdr->answer.tv_sec) {
00849       snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->answer.tv_sec);
00850       pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
00851    }
00852 
00853    if (chan->cdr->start.tv_sec) {
00854       snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->start.tv_sec);
00855       pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
00856    }
00857    ast_channel_unlock(chan);
00858 }

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

Definition at line 860 of file app_dial.c.

References ast_bridge_config::end_bridge_callback_data.

Referenced by app_exec().

00860                                                                                                                                               {
00861    bconfig->end_bridge_callback_data = originator;
00862 }

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

Definition at line 387 of file app_dial.c.

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

Referenced by wait_for_answer().

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

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

Definition at line 325 of file app_dial.c.

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

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

static int load_module ( void   )  [static]

Definition at line 2005 of file app_dial.c.

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

02006 {
02007    int res;
02008 
02009    res = ast_register_application(app, dial_exec, synopsis, descrip);
02010    res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
02011    
02012    return res;
02013 }

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

Definition at line 368 of file app_dial.c.

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

Referenced by retrydial_exec(), and wait_for_answer().

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

static void replace_macro_delimiter ( char *  s  )  [static]

Definition at line 786 of file app_dial.c.

00787 {
00788    for (; *s; s++)
00789       if (*s == '^')
00790          *s = '|';
00791 }

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

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

01878 {
01879    char *announce = NULL, *dialdata = NULL;
01880    const char *context = NULL;
01881    int sleep = 0, loops = 0, res = -1;
01882    struct ast_module_user *u;
01883    struct ast_flags peerflags;
01884    
01885    if (ast_strlen_zero(data)) {
01886       ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
01887       return -1;
01888    }  
01889 
01890    u = ast_module_user_add(chan);
01891 
01892    announce = ast_strdupa(data);
01893 
01894    memset(&peerflags, 0, sizeof(peerflags));
01895 
01896    if ((dialdata = strchr(announce, '|'))) {
01897       *dialdata++ = '\0';
01898       if (sscanf(dialdata, "%d", &sleep) == 1) {
01899          sleep *= 1000;
01900       } else {
01901          ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
01902          goto done;
01903       }
01904       if ((dialdata = strchr(dialdata, '|'))) {
01905          *dialdata++ = '\0';
01906          if (sscanf(dialdata, "%d", &loops) != 1) {
01907             ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
01908             goto done;
01909          }
01910       }
01911    }
01912    
01913    if ((dialdata = strchr(dialdata, '|'))) {
01914       *dialdata++ = '\0';
01915    } else {
01916       ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
01917       goto done;
01918    }
01919       
01920    if (sleep < 1000)
01921       sleep = 10000;
01922 
01923    if (!loops)
01924       loops = -1; /* run forever */
01925    
01926    context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
01927 
01928    res = 0;
01929    while (loops) {
01930       int continue_exec;
01931 
01932       chan->data = "Retrying";
01933       if (ast_test_flag(chan, AST_FLAG_MOH))
01934          ast_moh_stop(chan);
01935 
01936       res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
01937       if (continue_exec)
01938          break;
01939 
01940       if (res == 0) {
01941          if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
01942             if (!ast_strlen_zero(announce)) {
01943                if (ast_fileexists(announce, NULL, chan->language) > 0) {
01944                   if(!(res = ast_streamfile(chan, announce, chan->language)))                      
01945                      ast_waitstream(chan, AST_DIGIT_ANY);
01946                } else
01947                   ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01948             }
01949             if (!res && sleep) {
01950                if (!ast_test_flag(chan, AST_FLAG_MOH))
01951                   ast_moh_start(chan, NULL, NULL);
01952                res = ast_waitfordigit(chan, sleep);
01953             }
01954          } else {
01955             if (!ast_strlen_zero(announce)) {
01956                if (ast_fileexists(announce, NULL, chan->language) > 0) {
01957                   if (!(res = ast_streamfile(chan, announce, chan->language)))
01958                      res = ast_waitstream(chan, "");
01959                } else
01960                   ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01961             }
01962             if (sleep) {
01963                if (!ast_test_flag(chan, AST_FLAG_MOH))
01964                   ast_moh_start(chan, NULL, NULL);
01965                if (!res)
01966                   res = ast_waitfordigit(chan, sleep);
01967             }
01968          }
01969       }
01970 
01971       if (res < 0)
01972          break;
01973       else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
01974          if (onedigit_goto(chan, context, (char) res, 1)) {
01975             res = 0;
01976             break;
01977          }
01978       }
01979       loops--;
01980    }
01981    if (loops == 0)
01982       res = 0;
01983    else if (res == 1)
01984       res = 0;
01985 
01986    if (ast_test_flag(chan, AST_FLAG_MOH))
01987       ast_moh_stop(chan);
01988  done:
01989    ast_module_user_remove(u);
01990    return res;
01991 }

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

Definition at line 395 of file app_dial.c.

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

Referenced by wait_for_answer().

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

static void set_dial_features ( struct ast_flags opts,
struct ast_dial_features features 
) [static]

Definition at line 806 of file app_dial.c.

References ast_app_options2str(), ast_copy_flags, AST_FEATURE_AUTOMON, AST_FEATURE_DISCONNECT, AST_FEATURE_PARKCALL, AST_FEATURE_REDIRECT, ast_set_flag, ast_test_flag, dial_exec_options, ast_dial_features::features_callee, ast_dial_features::features_caller, ast_flags::flags, OPT_CALLEE_HANGUP, OPT_CALLEE_MONITOR, OPT_CALLEE_PARK, OPT_CALLEE_TRANSFER, OPT_CALLER_HANGUP, OPT_CALLER_MONITOR, OPT_CALLER_PARK, OPT_CALLER_TRANSFER, and ast_dial_features::options.

00807 {
00808    struct ast_flags perm_opts = {.flags = 0};
00809 
00810    ast_copy_flags(&perm_opts, opts,
00811       OPT_CALLER_TRANSFER | OPT_CALLER_PARK | OPT_CALLER_MONITOR | OPT_CALLER_HANGUP |
00812       OPT_CALLEE_TRANSFER | OPT_CALLEE_PARK | OPT_CALLEE_MONITOR | OPT_CALLEE_HANGUP);
00813 
00814    memset(features->options, 0, sizeof(features->options));
00815 
00816    ast_app_options2str(dial_exec_options, &perm_opts, features->options, sizeof(features->options));
00817    if (ast_test_flag(&perm_opts, OPT_CALLEE_TRANSFER))
00818       ast_set_flag(&(features->features_callee), AST_FEATURE_REDIRECT);
00819    if (ast_test_flag(&perm_opts, OPT_CALLER_TRANSFER))
00820       ast_set_flag(&(features->features_caller), AST_FEATURE_REDIRECT);
00821    if (ast_test_flag(&perm_opts, OPT_CALLEE_HANGUP))
00822       ast_set_flag(&(features->features_callee), AST_FEATURE_DISCONNECT);
00823    if (ast_test_flag(&perm_opts, OPT_CALLER_HANGUP))
00824       ast_set_flag(&(features->features_caller), AST_FEATURE_DISCONNECT);
00825    if (ast_test_flag(&perm_opts, OPT_CALLEE_MONITOR))
00826       ast_set_flag(&(features->features_callee), AST_FEATURE_AUTOMON);
00827    if (ast_test_flag(&perm_opts, OPT_CALLER_MONITOR))
00828       ast_set_flag(&(features->features_caller), AST_FEATURE_AUTOMON);
00829    if (ast_test_flag(&perm_opts, OPT_CALLEE_PARK))
00830       ast_set_flag(&(features->features_callee), AST_FEATURE_PARKCALL);
00831    if (ast_test_flag(&perm_opts, OPT_CALLER_PARK))
00832       ast_set_flag(&(features->features_caller), AST_FEATURE_PARKCALL);
00833 }

static int unload_module ( void   )  [static]

Definition at line 1993 of file app_dial.c.

References ast_module_user_hangup_all, and ast_unregister_application().

01994 {
01995    int res;
01996 
01997    res = ast_unregister_application(app);
01998    res |= ast_unregister_application(rapp);
01999 
02000    ast_module_user_hangup_all();
02001    
02002    return res;
02003 }

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

Definition at line 795 of file app_dial.c.

References ast_test_flag, OPT_PRIVACY, and OPT_SCREENING.

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

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

Definition at line 410 of file app_dial.c.

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

Referenced by try_calling().

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


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Dialing Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, } [static]

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

char* descrip [static]

Definition at line 75 of file app_dial.c.

enum { ... } dial_exec_option_args

enum { ... } dial_exec_option_flags

struct ast_app_option dial_exec_options[128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'f' ] = { .flag = OPT_FORCECLID }, [ 'g' ] = { .flag = OPT_GO_ON }, [ 'G' ] = { .flag = OPT_GOTO , .arg_index = OPT_ARG_GOTO + 1 }, [ 'h' ] = { .flag = OPT_CALLEE_HANGUP }, [ 'H' ] = { .flag = OPT_CALLER_HANGUP }, [ 'i' ] = { .flag = OPT_IGNORE_FORWARDING }, [ 'j' ] = { .flag = OPT_PRIORITY_JUMP }, [ 'k' ] = { .flag = OPT_CALLEE_PARK }, [ 'K' ] = { .flag = OPT_CALLER_PARK }, [ 'L' ] = { .flag = OPT_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, [ 'm' ] = { .flag = OPT_MUSICBACK , .arg_index = OPT_ARG_MUSICBACK + 1 }, [ 'M' ] = { .flag = OPT_CALLEE_MACRO , .arg_index = OPT_ARG_CALLEE_MACRO + 1 }, [ 'n' ] = { .flag = OPT_SCREEN_NOINTRO }, [ 'N' ] = { .flag = OPT_SCREEN_NOCLID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR },} [static]

Definition at line 307 of file app_dial.c.

Referenced by set_dial_features().

char* rapp = "RetryDial" [static]

Definition at line 215 of file app_dial.c.

char* rdescrip [static]

Definition at line 217 of file app_dial.c.

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

Definition at line 216 of file app_dial.c.

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

Definition at line 73 of file app_dial.c.


Generated on Thu Feb 5 16:25:53 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7