#include "asterisk.h"
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/say.h"
#include "asterisk/config.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/callerid.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/causes.h"
#include "asterisk/rtp.h"
#include "asterisk/cdr.h"
#include "asterisk/manager.h"
#include "asterisk/privacy.h"
#include "asterisk/stringfields.h"
#include "asterisk/global_datastores.h"
Go to the source code of this file.
Data Structures | |
struct | dial_localuser |
Defines | |
#define | AST_MAX_WATCHERS 256 |
#define | CAN_EARLY_BRIDGE(flags, chan, peer) |
#define | DIAL_NOFORWARDHTML (1 << 31) |
#define | DIAL_STILLGOING (1 << 30) |
#define | HANDLE_CAUSE(cause, chan) |
Enumerations | |
enum | { OPT_ANNOUNCE = (1 << 0), OPT_RESETCDR = (1 << 1), OPT_DTMF_EXIT = (1 << 2), OPT_SENDDTMF = (1 << 3), OPT_FORCECLID = (1 << 4), OPT_GO_ON = (1 << 5), OPT_CALLEE_HANGUP = (1 << 6), OPT_CALLER_HANGUP = (1 << 7), OPT_PRIORITY_JUMP = (1 << 8), OPT_DURATION_LIMIT = (1 << 9), OPT_MUSICBACK = (1 << 10), OPT_CALLEE_MACRO = (1 << 11), OPT_SCREEN_NOINTRO = (1 << 12), OPT_SCREEN_NOCLID = (1 << 13), OPT_ORIGINAL_CLID = (1 << 14), OPT_SCREENING = (1 << 15), OPT_PRIVACY = (1 << 16), OPT_RINGBACK = (1 << 17), OPT_DURATION_STOP = (1 << 18), OPT_CALLEE_TRANSFER = (1 << 19), OPT_CALLER_TRANSFER = (1 << 20), OPT_CALLEE_MONITOR = (1 << 21), OPT_CALLER_MONITOR = (1 << 22), OPT_GOTO = (1 << 23), OPT_OPERMODE = (1 << 24), OPT_CALLEE_PARK = (1 << 25), OPT_CALLER_PARK = (1 << 26), OPT_IGNORE_FORWARDING = (1 << 27) } |
enum | { OPT_ARG_ANNOUNCE = 0, OPT_ARG_SENDDTMF, OPT_ARG_GOTO, OPT_ARG_DURATION_LIMIT, OPT_ARG_MUSICBACK, OPT_ARG_CALLEE_MACRO, OPT_ARG_PRIVACY, OPT_ARG_DURATION_STOP, OPT_ARG_OPERMODE, OPT_ARG_ARRAY_SIZE } |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | detect_disconnect (struct ast_channel *chan, char code, char *featurecode, int len) |
static int | dial_exec (struct ast_channel *chan, void *data) |
static void | end_bridge_callback (void *data) |
static void | end_bridge_callback_data_fixup (struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator) |
static const char * | get_cid_name (char *name, int namelen, struct ast_channel *chan) |
static void | hanguptree (struct dial_localuser *outgoing, struct ast_channel *exception) |
static int | load_module (void) |
static int | onedigit_goto (struct ast_channel *chan, const char *context, char exten, int pri) |
static void | replace_macro_delimiter (char *s) |
static int | retrydial_exec (struct ast_channel *chan, void *data) |
static void | senddialevent (struct ast_channel *src, struct ast_channel *dst) |
static int | unload_module (void) |
static int | valid_priv_reply (struct ast_flags *opts, int res) |
static struct ast_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 = "f450f61f60e761b3aa089ebed76ca8a5" , .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 }, [ '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 339 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) && \ !chan->audiohooks && !peer->audiohooks)
Definition at line 309 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 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 |
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;
static void __reg_module | ( | void | ) | [static] |
Definition at line 1984 of file app_dial.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1984 of file app_dial.c.
static int detect_disconnect | ( | struct ast_channel * | chan, | |
char | code, | |||
char * | featurecode, | |||
int | len | |||
) | [static] |
Definition at line 799 of file app_dial.c.
References ast_feature_detect(), AST_FEATURE_DISCONNECT, ast_call_feature::feature_mask, and FEATURE_RETURN_STOREDIGITS.
Referenced by wait_for_answer().
00800 { 00801 struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */ 00802 struct ast_call_feature feature = { 0, }; 00803 char *tmp; 00804 int res; 00805 00806 if ((strlen(featurecode)) < (len - 2)) { 00807 tmp = &featurecode[strlen(featurecode)]; 00808 tmp[0] = code; 00809 tmp[1] = '\0'; 00810 } else { 00811 featurecode[0] = 0; 00812 return -1; /* no room in featurecode buffer */ 00813 } 00814 00815 res = ast_feature_detect(chan, &features, featurecode, &feature); 00816 00817 if (res != FEATURE_RETURN_STOREDIGITS) { 00818 featurecode[0] = '\0'; 00819 } 00820 if (feature.feature_mask & AST_FEATURE_DISCONNECT) { 00821 return 1; 00822 } 00823 00824 return 0; 00825 }
static int dial_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 1837 of file app_dial.c.
Referenced by load_module().
01838 { 01839 struct ast_flags peerflags; 01840 01841 memset(&peerflags, 0, sizeof(peerflags)); 01842 01843 return dial_exec_full(chan, data, &peerflags, NULL); 01844 }
static void end_bridge_callback | ( | void * | data | ) | [static] |
Definition at line 847 of file app_dial.c.
References ast_cdr::answer, ast_channel_lock, ast_channel_unlock, ast_channel::cdr, pbx_builtin_setvar_helper(), and ast_cdr::start.
Referenced by app_exec().
00848 { 00849 char buf[80]; 00850 time_t end; 00851 struct ast_channel *chan = data; 00852 00853 if (!chan->cdr) { 00854 return; 00855 } 00856 00857 time(&end); 00858 00859 ast_channel_lock(chan); 00860 if (chan->cdr->answer.tv_sec) { 00861 snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->answer.tv_sec); 00862 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf); 00863 } 00864 00865 if (chan->cdr->start.tv_sec) { 00866 snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->start.tv_sec); 00867 pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf); 00868 } 00869 ast_channel_unlock(chan); 00870 }
static void end_bridge_callback_data_fixup | ( | struct ast_bridge_config * | bconfig, | |
struct ast_channel * | originator, | |||
struct ast_channel * | terminator | |||
) | [static] |
Definition at line 872 of file app_dial.c.
References ast_bridge_config::end_bridge_callback_data.
Referenced by app_exec().
00872 { 00873 bconfig->end_bridge_callback_data = originator; 00874 }
static const char* get_cid_name | ( | char * | name, | |
int | namelen, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 392 of file app_dial.c.
References ast_get_hint(), dial_localuser::chan, ast_channel::context, context, ast_channel::exten, exten, ast_channel::macrocontext, ast_channel::macroexten, and S_OR.
Referenced by wait_for_answer().
00393 { 00394 const char *context = S_OR(chan->macrocontext, chan->context); 00395 const char *exten = S_OR(chan->macroexten, chan->exten); 00396 00397 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : ""; 00398 }
static void hanguptree | ( | struct dial_localuser * | outgoing, | |
struct ast_channel * | exception | |||
) | [static] |
Definition at line 325 of file app_dial.c.
References ast_hangup(), dial_localuser::chan, free, and dial_localuser::next.
00326 { 00327 /* Hang up a tree of stuff */ 00328 struct dial_localuser *oo; 00329 while (outgoing) { 00330 /* Hangup any existing lines we have open */ 00331 if (outgoing->chan && (outgoing->chan != exception)) 00332 ast_hangup(outgoing->chan); 00333 oo = outgoing; 00334 outgoing=outgoing->next; 00335 free(oo); 00336 } 00337 }
static int load_module | ( | void | ) | [static] |
Definition at line 1974 of file app_dial.c.
References ast_register_application(), dial_exec(), and retrydial_exec().
01975 { 01976 int res; 01977 01978 res = ast_register_application(app, dial_exec, synopsis, descrip); 01979 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip); 01980 01981 return res; 01982 }
static int onedigit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
char | exten, | |||
int | pri | |||
) | [static] |
Definition at line 372 of file app_dial.c.
References ast_goto_if_exists(), ast_strlen_zero(), dial_localuser::chan, ast_channel::context, and ast_channel::macrocontext.
Referenced by retrydial_exec(), and wait_for_answer().
00373 { 00374 char rexten[2] = { exten, '\0' }; 00375 00376 if (context) { 00377 if (!ast_goto_if_exists(chan, context, rexten, pri)) 00378 return 1; 00379 } else { 00380 if (!ast_goto_if_exists(chan, chan->context, rexten, pri)) 00381 return 1; 00382 else if (!ast_strlen_zero(chan->macrocontext)) { 00383 if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri)) 00384 return 1; 00385 } 00386 } 00387 return 0; 00388 }
static void replace_macro_delimiter | ( | char * | s | ) | [static] |
static int retrydial_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 1846 of file app_dial.c.
References AST_DIGIT_ANY, ast_fileexists(), AST_FLAG_MOH, ast_log(), ast_module_user_add, ast_module_user_remove, ast_moh_start(), ast_moh_stop(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_waitstream(), context, ast_channel::data, LOG_ERROR, LOG_WARNING, onedigit_goto(), OPT_DTMF_EXIT, and pbx_builtin_getvar_helper().
Referenced by load_module().
01847 { 01848 char *announce = NULL, *dialdata = NULL; 01849 const char *context = NULL; 01850 int sleep = 0, loops = 0, res = -1; 01851 struct ast_module_user *u; 01852 struct ast_flags peerflags; 01853 01854 if (ast_strlen_zero(data)) { 01855 ast_log(LOG_WARNING, "RetryDial requires an argument!\n"); 01856 return -1; 01857 } 01858 01859 u = ast_module_user_add(chan); 01860 01861 announce = ast_strdupa(data); 01862 01863 memset(&peerflags, 0, sizeof(peerflags)); 01864 01865 if ((dialdata = strchr(announce, '|'))) { 01866 *dialdata++ = '\0'; 01867 if (sscanf(dialdata, "%d", &sleep) == 1) { 01868 sleep *= 1000; 01869 } else { 01870 ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp); 01871 goto done; 01872 } 01873 if ((dialdata = strchr(dialdata, '|'))) { 01874 *dialdata++ = '\0'; 01875 if (sscanf(dialdata, "%d", &loops) != 1) { 01876 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp); 01877 goto done; 01878 } 01879 } 01880 } 01881 01882 if (dialdata && (dialdata = strchr(dialdata, '|'))) { 01883 *dialdata++ = '\0'; 01884 } else { 01885 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp); 01886 goto done; 01887 } 01888 01889 if (sleep < 1000) 01890 sleep = 10000; 01891 01892 if (!loops) 01893 loops = -1; /* run forever */ 01894 01895 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT"); 01896 01897 res = 0; 01898 while (loops) { 01899 int continue_exec; 01900 01901 chan->data = "Retrying"; 01902 if (ast_test_flag(chan, AST_FLAG_MOH)) 01903 ast_moh_stop(chan); 01904 01905 res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec); 01906 if (continue_exec) 01907 break; 01908 01909 if (res == 0) { 01910 if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) { 01911 if (!ast_strlen_zero(announce)) { 01912 if (ast_fileexists(announce, NULL, chan->language) > 0) { 01913 if(!(res = ast_streamfile(chan, announce, chan->language))) 01914 ast_waitstream(chan, AST_DIGIT_ANY); 01915 } else 01916 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce); 01917 } 01918 if (!res && sleep) { 01919 if (!ast_test_flag(chan, AST_FLAG_MOH)) 01920 ast_moh_start(chan, NULL, NULL); 01921 res = ast_waitfordigit(chan, sleep); 01922 } 01923 } else { 01924 if (!ast_strlen_zero(announce)) { 01925 if (ast_fileexists(announce, NULL, chan->language) > 0) { 01926 if (!(res = ast_streamfile(chan, announce, chan->language))) 01927 res = ast_waitstream(chan, ""); 01928 } else 01929 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce); 01930 } 01931 if (sleep) { 01932 if (!ast_test_flag(chan, AST_FLAG_MOH)) 01933 ast_moh_start(chan, NULL, NULL); 01934 if (!res) 01935 res = ast_waitfordigit(chan, sleep); 01936 } 01937 } 01938 } 01939 01940 if (res < 0) 01941 break; 01942 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */ 01943 if (onedigit_goto(chan, context, (char) res, 1)) { 01944 res = 0; 01945 break; 01946 } 01947 } 01948 loops--; 01949 } 01950 if (loops == 0) 01951 res = 0; 01952 else if (res == 1) 01953 res = 0; 01954 01955 if (ast_test_flag(chan, AST_FLAG_MOH)) 01956 ast_moh_stop(chan); 01957 done: 01958 ast_module_user_remove(u); 01959 return res; 01960 }
static void senddialevent | ( | struct ast_channel * | src, | |
struct ast_channel * | dst | |||
) | [static] |
Definition at line 400 of file app_dial.c.
References ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event(), ast_channel::name, S_OR, and ast_channel::uniqueid.
Referenced by wait_for_answer().
00401 { 00402 /* XXX do we need also CallerIDnum ? */ 00403 manager_event(EVENT_FLAG_CALL, "Dial", 00404 "Source: %s\r\n" 00405 "Destination: %s\r\n" 00406 "CallerID: %s\r\n" 00407 "CallerIDName: %s\r\n" 00408 "SrcUniqueID: %s\r\n" 00409 "DestUniqueID: %s\r\n", 00410 src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"), 00411 S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid, 00412 dst->uniqueid); 00413 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1962 of file app_dial.c.
References ast_module_user_hangup_all, and ast_unregister_application().
01963 { 01964 int res; 01965 01966 res = ast_unregister_application(app); 01967 res |= ast_unregister_application(rapp); 01968 01969 ast_module_user_hangup_all(); 01970 01971 return res; 01972 }
static int valid_priv_reply | ( | struct ast_flags * | opts, | |
int | res | |||
) | [static] |
Definition at line 836 of file app_dial.c.
References ast_test_flag, OPT_PRIVACY, and OPT_SCREENING.
00837 { 00838 if (res < '1') 00839 return 0; 00840 if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5') 00841 return 1; 00842 if (ast_test_flag(opts, OPT_SCREENING) && res <= '4') 00843 return 1; 00844 return 0; 00845 }
static struct ast_channel* wait_for_answer | ( | struct ast_channel * | in, | |
struct dial_localuser * | outgoing, | |||
int * | to, | |||
struct ast_flags * | peerflags, | |||
int * | sentringing, | |||
char * | status, | |||
size_t | statussize, | |||
int | busystart, | |||
int | nochanstart, | |||
int | congestionstart, | |||
int | priority_jump, | |||
int * | result | |||
) | [static] |
Definition at line 415 of file app_dial.c.
References ast_channel::_state, ast_channel::accountcode, accountcode, ast_cdr::answer, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CDR_ANSWERED, ast_cdr_noanswer(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_make_compatible(), ast_channel_sendhtml(), ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_flags, ast_copy_string(), ast_deactivate_generator(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frfree, ast_goto_if_exists(), ast_hangup(), ast_indicate(), ast_indicate_data(), ast_log(), AST_MAX_EXTENSION, AST_MAX_WATCHERS, ast_opt_priority_jumping, ast_read(), ast_request(), ast_rtp_early_bridge(), ast_rtp_make_compatible(), ast_set_callerid(), AST_STATE_UP, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_verbose(), ast_waitfor_n(), ast_write(), CAN_EARLY_BRIDGE, ast_channel::cdr, ast_channel::cdrflags, dial_localuser::chan, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, context, ast_channel::context, detect_disconnect(), DIAL_NOFORWARDHTML, DIAL_STILLGOING, ast_channel::dialcontext, ast_cdr::disposition, ast_channel::exten, f, FEATURE_MAX_LEN, free, get_cid_name(), HANDLE_CAUSE, ast_channel::hangupcause, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macroexten, ast_channel::name, ast_channel::nativeformats, dial_localuser::next, onedigit_goto(), OPT_CALLEE_HANGUP, OPT_CALLEE_MONITOR, OPT_CALLEE_PARK, OPT_CALLEE_TRANSFER, OPT_CALLER_HANGUP, OPT_CALLER_MONITOR, OPT_CALLER_PARK, OPT_CALLER_TRANSFER, OPT_DTMF_EXIT, OPT_FORCECLID, OPT_IGNORE_FORWARDING, OPT_MUSICBACK, OPT_ORIGINAL_CLID, OPT_RINGBACK, option_debug, option_verbose, pbx_builtin_getvar_helper(), S_OR, senddialevent(), ast_channel::tech, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3.
Referenced by try_calling().
00416 { 00417 int numbusy = busystart; 00418 int numcongestion = congestionstart; 00419 int numnochan = nochanstart; 00420 int prestart = busystart + congestionstart + nochanstart; 00421 int orig = *to; 00422 struct ast_channel *peer = NULL; 00423 /* single is set if only one destination is enabled */ 00424 int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK); 00425 00426 char featurecode[FEATURE_MAX_LEN + 1] = { 0, }; 00427 00428 if (single) { 00429 /* Turn off hold music, etc */ 00430 ast_deactivate_generator(in); 00431 /* If we are calling a single channel, make them compatible for in-band tone purpose */ 00432 ast_channel_make_compatible(outgoing->chan, in); 00433 } 00434 00435 00436 while (*to && !peer) { 00437 struct dial_localuser *o; 00438 int pos = 0; /* how many channels do we handle */ 00439 int numlines = prestart; 00440 struct ast_channel *winner; 00441 struct ast_channel *watchers[AST_MAX_WATCHERS]; 00442 00443 watchers[pos++] = in; 00444 for (o = outgoing; o; o = o->next) { 00445 /* Keep track of important channels */ 00446 if (ast_test_flag(o, DIAL_STILLGOING) && o->chan) 00447 watchers[pos++] = o->chan; 00448 numlines++; 00449 } 00450 if (pos == 1) { /* only the input channel is available */ 00451 if (numlines == (numbusy + numcongestion + numnochan)) { 00452 if (option_verbose > 2) 00453 ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan); 00454 if (numbusy) 00455 strcpy(status, "BUSY"); 00456 else if (numcongestion) 00457 strcpy(status, "CONGESTION"); 00458 else if (numnochan) 00459 strcpy(status, "CHANUNAVAIL"); 00460 if (ast_opt_priority_jumping || priority_jump) 00461 ast_goto_if_exists(in, in->context, in->exten, in->priority + 101); 00462 } else { 00463 if (option_verbose > 2) 00464 ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan); 00465 } 00466 *to = 0; 00467 return NULL; 00468 } 00469 winner = ast_waitfor_n(watchers, pos, to); 00470 for (o = outgoing; o; o = o->next) { 00471 struct ast_frame *f; 00472 struct ast_channel *c = o->chan; 00473 00474 if (c == NULL) 00475 continue; 00476 if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) { 00477 if (!peer) { 00478 if (option_verbose > 2) 00479 ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name); 00480 peer = c; 00481 ast_copy_flags(peerflags, o, 00482 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | 00483 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP | 00484 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | 00485 OPT_CALLEE_PARK | OPT_CALLER_PARK | 00486 DIAL_NOFORWARDHTML); 00487 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext)); 00488 ast_copy_string(c->exten, "", sizeof(c->exten)); 00489 } 00490 continue; 00491 } 00492 if (c != winner) 00493 continue; 00494 if (!ast_strlen_zero(c->call_forward)) { 00495 char tmpchan[256]; 00496 char *stuff; 00497 char *tech; 00498 int cause; 00499 00500 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan)); 00501 if ((stuff = strchr(tmpchan, '/'))) { 00502 *stuff++ = '\0'; 00503 tech = tmpchan; 00504 } else { 00505 const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT"); 00506 if (ast_strlen_zero(forward_context)) { 00507 forward_context = NULL; 00508 } 00509 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context); 00510 stuff = tmpchan; 00511 tech = "Local"; 00512 } 00513 /* Before processing channel, go ahead and check for forwarding */ 00514 if (option_verbose > 2) 00515 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name); 00516 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */ 00517 if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) { 00518 if (option_verbose > 2) 00519 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff); 00520 c = o->chan = NULL; 00521 cause = AST_CAUSE_BUSY; 00522 } else { 00523 /* Setup parameters */ 00524 if ((c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause))) { 00525 if (single) 00526 ast_channel_make_compatible(o->chan, in); 00527 ast_channel_inherit_variables(in, o->chan); 00528 ast_channel_datastore_inherit(in, o->chan); 00529 } else 00530 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause); 00531 } 00532 if (!c) { 00533 ast_clear_flag(o, DIAL_STILLGOING); 00534 HANDLE_CAUSE(cause, in); 00535 } else { 00536 ast_rtp_make_compatible(c, in, single); 00537 if (c->cid.cid_num) 00538 free(c->cid.cid_num); 00539 c->cid.cid_num = NULL; 00540 if (c->cid.cid_name) 00541 free(c->cid.cid_name); 00542 c->cid.cid_name = NULL; 00543 00544 if (ast_test_flag(o, OPT_FORCECLID)) { 00545 c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten)); 00546 ast_string_field_set(c, accountcode, winner->accountcode); 00547 c->cdrflags = winner->cdrflags; 00548 } else { 00549 c->cid.cid_num = ast_strdup(in->cid.cid_num); 00550 c->cid.cid_name = ast_strdup(in->cid.cid_name); 00551 ast_string_field_set(c, accountcode, in->accountcode); 00552 c->cdrflags = in->cdrflags; 00553 } 00554 00555 if (in->cid.cid_ani) { 00556 if (c->cid.cid_ani) 00557 free(c->cid.cid_ani); 00558 c->cid.cid_ani = ast_strdup(in->cid.cid_ani); 00559 } 00560 if (c->cid.cid_rdnis) 00561 free(c->cid.cid_rdnis); 00562 c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten)); 00563 if (ast_call(c, tmpchan, 0)) { 00564 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan); 00565 ast_clear_flag(o, DIAL_STILLGOING); 00566 ast_hangup(c); 00567 c = o->chan = NULL; 00568 numnochan++; 00569 } else { 00570 senddialevent(in, c); 00571 /* After calling, set callerid to extension */ 00572 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) { 00573 char cidname[AST_MAX_EXTENSION] = ""; 00574 ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL); 00575 } 00576 } 00577 if (single) { 00578 ast_indicate(in, -1); 00579 } 00580 } 00581 /* Hangup the original channel now, in case we needed it */ 00582 ast_hangup(winner); 00583 continue; 00584 } 00585 f = ast_read(winner); 00586 if (!f) { 00587 in->hangupcause = c->hangupcause; 00588 ast_hangup(c); 00589 c = o->chan = NULL; 00590 ast_clear_flag(o, DIAL_STILLGOING); 00591 HANDLE_CAUSE(in->hangupcause, in); 00592 continue; 00593 } 00594 if (f->frametype == AST_FRAME_CONTROL) { 00595 switch(f->subclass) { 00596 case AST_CONTROL_ANSWER: 00597 /* This is our guy if someone answered. */ 00598 if (!peer) { 00599 if (option_verbose > 2) 00600 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name); 00601 peer = c; 00602 if (peer->cdr) { 00603 peer->cdr->answer = ast_tvnow(); 00604 peer->cdr->disposition = AST_CDR_ANSWERED; 00605 } 00606 ast_copy_flags(peerflags, o, 00607 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | 00608 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP | 00609 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | 00610 OPT_CALLEE_PARK | OPT_CALLER_PARK | 00611 DIAL_NOFORWARDHTML); 00612 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext)); 00613 ast_copy_string(c->exten, "", sizeof(c->exten)); 00614 /* Setup RTP early bridge if appropriate */ 00615 if (CAN_EARLY_BRIDGE(peerflags, in, peer)) 00616 ast_rtp_early_bridge(in, peer); 00617 } 00618 /* If call has been answered, then the eventual hangup is likely to be normal hangup */ 00619 in->hangupcause = AST_CAUSE_NORMAL_CLEARING; 00620 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 00621 break; 00622 case AST_CONTROL_BUSY: 00623 if (option_verbose > 2) 00624 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name); 00625 in->hangupcause = c->hangupcause; 00626 ast_hangup(c); 00627 c = o->chan = NULL; 00628 ast_clear_flag(o, DIAL_STILLGOING); 00629 HANDLE_CAUSE(AST_CAUSE_BUSY, in); 00630 break; 00631 case AST_CONTROL_CONGESTION: 00632 if (option_verbose > 2) 00633 ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name); 00634 in->hangupcause = c->hangupcause; 00635 ast_hangup(c); 00636 c = o->chan = NULL; 00637 ast_clear_flag(o, DIAL_STILLGOING); 00638 HANDLE_CAUSE(AST_CAUSE_CONGESTION, in); 00639 break; 00640 case AST_CONTROL_RINGING: 00641 if (option_verbose > 2) 00642 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name); 00643 /* Setup early media if appropriate */ 00644 if (single && CAN_EARLY_BRIDGE(peerflags, in, c)) 00645 ast_rtp_early_bridge(in, c); 00646 if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) { 00647 ast_indicate(in, AST_CONTROL_RINGING); 00648 (*sentringing)++; 00649 } 00650 break; 00651 case AST_CONTROL_PROGRESS: 00652 if (option_verbose > 2) 00653 ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name); 00654 /* Setup early media if appropriate */ 00655 if (single && CAN_EARLY_BRIDGE(peerflags, in, c)) 00656 ast_rtp_early_bridge(in, c); 00657 if (!ast_test_flag(outgoing, OPT_RINGBACK)) 00658 ast_indicate(in, AST_CONTROL_PROGRESS); 00659 break; 00660 case AST_CONTROL_VIDUPDATE: 00661 if (option_verbose > 2) 00662 ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name); 00663 ast_indicate(in, AST_CONTROL_VIDUPDATE); 00664 break; 00665 case AST_CONTROL_SRCUPDATE: 00666 if (option_verbose > 2) 00667 ast_verbose (VERBOSE_PREFIX_3 "%s requested a source update, passing it to %s\n", c->name, in->name); 00668 ast_indicate(in, AST_CONTROL_SRCUPDATE); 00669 break; 00670 case AST_CONTROL_PROCEEDING: 00671 if (option_verbose > 2) 00672 ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name); 00673 if (single && CAN_EARLY_BRIDGE(peerflags, in, c)) 00674 ast_rtp_early_bridge(in, c); 00675 if (!ast_test_flag(outgoing, OPT_RINGBACK)) 00676 ast_indicate(in, AST_CONTROL_PROCEEDING); 00677 break; 00678 case AST_CONTROL_HOLD: 00679 if (option_verbose > 2) 00680 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name); 00681 ast_indicate(in, AST_CONTROL_HOLD); 00682 break; 00683 case AST_CONTROL_UNHOLD: 00684 if (option_verbose > 2) 00685 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name); 00686 ast_indicate(in, AST_CONTROL_UNHOLD); 00687 break; 00688 case AST_CONTROL_OFFHOOK: 00689 case AST_CONTROL_FLASH: 00690 /* Ignore going off hook and flash */ 00691 break; 00692 case -1: 00693 if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) { 00694 if (option_verbose > 2) 00695 ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name); 00696 ast_indicate(in, -1); 00697 (*sentringing) = 0; 00698 } 00699 break; 00700 default: 00701 if (option_debug) 00702 ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass); 00703 } 00704 } else if (single) { 00705 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */ 00706 if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) { 00707 if (ast_write(in, f)) 00708 ast_log(LOG_WARNING, "Unable to forward voice frame\n"); 00709 } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) { 00710 if (ast_write(in, f)) 00711 ast_log(LOG_WARNING, "Unable to forward image\n"); 00712 } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) { 00713 if (ast_write(in, f)) 00714 ast_log(LOG_WARNING, "Unable to send text\n"); 00715 } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) { 00716 if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1) 00717 ast_log(LOG_WARNING, "Unable to send URL\n"); 00718 } 00719 } 00720 ast_frfree(f); 00721 } /* end for */ 00722 if (winner == in) { 00723 struct ast_frame *f = ast_read(in); 00724 #if 0 00725 if (f && (f->frametype != AST_FRAME_VOICE)) 00726 printf("Frame type: %d, %d\n", f->frametype, f->subclass); 00727 else if (!f || (f->frametype != AST_FRAME_VOICE)) 00728 printf("Hangup received on %s\n", in->name); 00729 #endif 00730 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) { 00731 /* Got hung up */ 00732 *to = -1; 00733 ast_cdr_noanswer(in->cdr); 00734 strcpy(status, "CANCEL"); 00735 if (f) 00736 ast_frfree(f); 00737 return NULL; 00738 } 00739 00740 if (f && (f->frametype == AST_FRAME_DTMF)) { 00741 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) { 00742 const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT"); 00743 if (onedigit_goto(in, context, (char) f->subclass, 1)) { 00744 if (option_verbose > 2) 00745 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass); 00746 *to=0; 00747 ast_cdr_noanswer(in->cdr); 00748 *result = f->subclass; 00749 strcpy(status, "CANCEL"); 00750 ast_frfree(f); 00751 return NULL; 00752 } 00753 } 00754 00755 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) && 00756 detect_disconnect(in, f->subclass, featurecode, sizeof(featurecode))) { 00757 if (option_verbose > 2) 00758 ast_verbose(VERBOSE_PREFIX_3 "User requested call disconnect.\n"); 00759 *to=0; 00760 ast_cdr_noanswer(in->cdr); 00761 strcpy(status, "CANCEL"); 00762 ast_frfree(f); 00763 return NULL; 00764 } 00765 } 00766 00767 /* Forward HTML stuff */ 00768 if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) 00769 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1) 00770 ast_log(LOG_WARNING, "Unable to send URL\n"); 00771 00772 00773 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) { 00774 if (ast_write(outgoing->chan, f)) 00775 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n"); 00776 } 00777 if (single && (f->frametype == AST_FRAME_CONTROL) && 00778 ((f->subclass == AST_CONTROL_HOLD) || 00779 (f->subclass == AST_CONTROL_UNHOLD) || 00780 (f->subclass == AST_CONTROL_VIDUPDATE) || 00781 (f->subclass == AST_CONTROL_SRCUPDATE))) { 00782 if (option_verbose > 2) 00783 ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name); 00784 ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen); 00785 } 00786 ast_frfree(f); 00787 } 00788 if (!*to && (option_verbose > 2)) 00789 ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig); 00790 if (!*to || ast_check_hangup(in)) { 00791 ast_cdr_noanswer(in->cdr); 00792 } 00793 00794 } 00795 00796 return peer; 00797 }
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 1984 of file app_dial.c.
char* app = "Dial" [static] |
Definition at line 71 of file app_dial.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1984 of file app_dial.c.
char* descrip [static] |
Definition at line 75 of file app_dial.c.
enum { ... } dial_exec_option_args |
enum { ... } dial_exec_option_flags |
struct ast_app_option dial_exec_options[128] = { [ 'A' ] = { .flag = OPT_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'C' ] = { .flag = OPT_RESETCDR }, [ 'd' ] = { .flag = OPT_DTMF_EXIT }, [ 'D' ] = { .flag = OPT_SENDDTMF , .arg_index = OPT_ARG_SENDDTMF + 1 }, [ 'f' ] = { .flag = OPT_FORCECLID }, [ 'g' ] = { .flag = OPT_GO_ON }, [ 'G' ] = { .flag = OPT_GOTO , .arg_index = OPT_ARG_GOTO + 1 }, [ 'h' ] = { .flag = OPT_CALLEE_HANGUP }, [ 'H' ] = { .flag = OPT_CALLER_HANGUP }, [ 'i' ] = { .flag = OPT_IGNORE_FORWARDING }, [ 'j' ] = { .flag = OPT_PRIORITY_JUMP }, [ 'k' ] = { .flag = OPT_CALLEE_PARK }, [ 'K' ] = { .flag = OPT_CALLER_PARK }, [ 'L' ] = { .flag = OPT_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, [ 'm' ] = { .flag = OPT_MUSICBACK , .arg_index = OPT_ARG_MUSICBACK + 1 }, [ 'M' ] = { .flag = OPT_CALLEE_MACRO , .arg_index = OPT_ARG_CALLEE_MACRO + 1 }, [ 'n' ] = { .flag = OPT_SCREEN_NOINTRO }, [ 'N' ] = { .flag = OPT_SCREEN_NOCLID }, [ 'o' ] = { .flag = OPT_ORIGINAL_CLID }, [ 'O' ] = { .flag = OPT_OPERMODE , .arg_index = OPT_ARG_OPERMODE + 1 }, [ 'p' ] = { .flag = OPT_SCREENING }, [ 'P' ] = { .flag = OPT_PRIVACY , .arg_index = OPT_ARG_PRIVACY + 1 }, [ 'r' ] = { .flag = OPT_RINGBACK }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR },} [static] |
Definition at line 307 of file app_dial.c.
char* rapp = "RetryDial" [static] |
Definition at line 215 of file app_dial.c.
char* rdescrip [static] |
Definition at line 217 of file app_dial.c.
char* rsynopsis = "Place a call, retrying on failure allowing optional exit extension." [static] |
Definition at line 216 of file app_dial.c.
char* synopsis = "Place a call and connect to the current channel" [static] |
Definition at line 73 of file app_dial.c.