#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_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) |
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_info * | ast_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" |
Definition in file app_dial.c.
#define AST_MAX_WATCHERS 256 |
Definition at line 346 of file app_dial.c.
#define CAN_EARLY_BRIDGE | ( | flags, | |||
chan, | |||||
peer | ) |
Value:
(!ast_test_flag(flags, OPT_CALLEE_HANGUP | \ OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \ OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | \ OPT_CALLER_PARK | OPT_ANNOUNCE | OPT_CALLEE_MACRO) && \ !chan->audiohooks && !peer->audiohooks)
Definition at line 315 of file app_dial.c.
Referenced by wait_for_answer().
#define DIAL_NOFORWARDHTML (1 << 31) |
#define DIAL_STILLGOING (1 << 30) |
#define HANDLE_CAUSE | ( | cause, | |||
chan | ) |
anonymous enum |
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 |
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;
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] |
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 }
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.