#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_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 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] |
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 }
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] |
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.