36 #include "asterisk/stasis_channels.h"
701 #define BACKGROUND_SKIP (1 << 0)
702 #define BACKGROUND_NOANSWER (1 << 1)
703 #define BACKGROUND_MATCHEXTEN (1 << 2)
704 #define BACKGROUND_PLAYBACK (1 << 3)
713 #define WAITEXTEN_MOH (1 << 0)
714 #define WAITEXTEN_DIALTONE (1 << 1)
721 int pbx_builtin_raise_exception(
struct ast_channel *chan,
const char *reason)
730 static int pbx_builtin_proceeding(
struct ast_channel *chan,
const char *data)
739 static int pbx_builtin_progress(
struct ast_channel *chan,
const char *data)
748 static int pbx_builtin_ringing(
struct ast_channel *chan,
const char *data)
757 int indicate_busy(
struct ast_channel *chan,
const char *data)
762 ast_channel_lock(chan);
764 ast_channel_hangupcause_set(chan, AST_CAUSE_BUSY);
767 ast_channel_unlock(chan);
768 wait_for_hangup(chan, data);
780 ast_channel_lock(chan);
782 ast_channel_hangupcause_set(chan, AST_CAUSE_CONGESTION);
785 ast_channel_unlock(chan);
786 wait_for_hangup(chan, data);
793 static int pbx_builtin_answer(
struct ast_channel *chan,
const char *data)
802 if (ast_strlen_zero(data)) {
817 if (!ast_strlen_zero(
args.options) && !strcmp(
args.options,
"i")) {
824 static int pbx_builtin_incomplete(
struct ast_channel *chan,
const char *data)
826 const char *options = data;
830 if (!ast_strlen_zero(options) && strchr(options,
'n')) {
849 static int pbx_builtin_hangup(
struct ast_channel *chan,
const char *data)
855 if (!ast_strlen_zero(data)) {
858 if (sscanf(data,
"%30d", &cause) != 1 || cause <= 0) {
859 ast_log(LOG_WARNING,
"Invalid cause given to Hangup(): \"%s\"\n", data);
867 ast_channel_lock(chan);
869 cause = ast_channel_hangupcause(chan);
871 cause = AST_CAUSE_NORMAL_CLEARING;
874 ast_channel_hangupcause_set(chan, cause);
876 ast_channel_unlock(chan);
888 ast_verb(3,
"Goto (%s,%s,%d)\n", ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1);
895 static int pbx_builtin_gotoiftime(
struct ast_channel *chan,
const char *data)
897 char *s, *ts, *branch1, *branch2, *branch;
904 ast_log(LOG_WARNING,
"GotoIfTime requires a channel on which to operate\n");
908 if (ast_strlen_zero(data)) {
909 ast_log(LOG_WARNING,
"GotoIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?'labeliftrue':'labeliffalse'\n");
915 ast_channel_lock(chan);
917 tv.tv_sec = timesecs;
919 ast_log(LOG_WARNING,
"Using current time to evaluate\n");
923 ast_channel_unlock(chan);
927 branch1 = strsep(&ts,
":");
928 branch2 = strsep(&ts,
"");
938 if (ast_strlen_zero(branch)) {
949 static int pbx_builtin_execiftime(
struct ast_channel *chan,
const char *data)
953 static const char *
const usage =
"ExecIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?<appname>[(<appargs>)]";
955 if (ast_strlen_zero(data)) {
956 ast_log(LOG_WARNING,
"%s\n", usage);
962 s = strsep(&appname,
"?");
964 ast_log(LOG_WARNING,
"%s\n", usage);
969 ast_log(LOG_WARNING,
"Invalid Time Spec: %s\nCorrect usage: %s\n", s, usage);
981 if ((s = strchr(appname,
'('))) {
984 if ((e = strrchr(s,
')')))
987 ast_log(LOG_WARNING,
"Failed to find closing parenthesis\n");
996 static int pbx_builtin_wait(
struct ast_channel *chan,
const char *data)
1010 static int pbx_builtin_waitdigit(
struct ast_channel *chan,
const char *data)
1040 snprintf(key,
sizeof(key),
"%c", res);
1051 static int pbx_builtin_waitexten(
struct ast_channel *chan,
const char *data)
1055 char *opts[1] = { NULL };
1062 if (!ast_strlen_zero(data)) {
1066 memset(&args, 0,
sizeof(args));
1071 if (ast_test_flag(&flags, WAITEXTEN_MOH) && !opts[0] ) {
1072 ast_log(LOG_WARNING,
"The 'm' option has been specified for WaitExten without a class.\n");
1073 }
else if (ast_test_flag(&flags, WAITEXTEN_MOH)) {
1075 !ast_strlen_zero(opts[0]) ? strlen(opts[0]) + 1 : 0);
1076 }
else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE)) {
1088 }
else if (ast_channel_pbx(chan)) {
1099 }
else if (
ast_exists_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1,
1100 S_COR(ast_channel_caller(chan)->
id.
number.valid, ast_channel_caller(chan)->
id.
number.str, NULL))) {
1101 ast_verb(3,
"Timeout on %s, continuing...\n", ast_channel_name(chan));
1103 S_COR(ast_channel_caller(chan)->
id.
number.valid, ast_channel_caller(chan)->
id.
number.str, NULL))) {
1104 ast_verb(3,
"Timeout on %s, going to 't'\n", ast_channel_name(chan));
1107 S_COR(ast_channel_caller(chan)->
id.
number.valid, ast_channel_caller(chan)->
id.
number.str, NULL))) {
1110 ast_log(LOG_WARNING,
"Timeout but no rule 't' or 'e' in context '%s'\n",
1111 ast_channel_context(chan));
1116 if (ast_test_flag(&flags, WAITEXTEN_MOH))
1118 else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE))
1127 static int pbx_builtin_background(
struct ast_channel *chan,
const char *data)
1132 char *parse, exten[2] =
"";
1140 if (ast_strlen_zero(data)) {
1141 ast_log(LOG_WARNING,
"Background requires an argument (filename)\n");
1149 if (ast_strlen_zero(args.lang))
1150 args.lang = (
char *)ast_channel_language(chan);
1152 if (ast_strlen_zero(args.context)) {
1153 ast_channel_lock(chan);
1154 args.context =
ast_strdupa(ast_channel_context(chan));
1155 ast_channel_unlock(chan);
1159 if (!strcasecmp(args.options,
"skip"))
1160 flags.flags = BACKGROUND_SKIP;
1161 else if (!strcasecmp(args.options,
"noanswer"))
1162 flags.flags = BACKGROUND_NOANSWER;
1169 if (ast_test_flag(&flags, BACKGROUND_SKIP)) {
1171 }
else if (!ast_test_flag(&flags, BACKGROUND_NOANSWER)) {
1184 ast_log(LOG_WARNING,
"ast_streamfile failed on %s for %s\n", ast_channel_name(chan), (
char*)data);
1189 if (ast_test_flag(&flags, BACKGROUND_PLAYBACK)) {
1191 }
else if (ast_test_flag(&flags, BACKGROUND_MATCHEXTEN)) {
1225 S_COR(ast_channel_caller(chan)->
id.
number.valid, ast_channel_caller(chan)->
id.
number.str, NULL))
1227 S_COR(ast_channel_caller(chan)->
id.
number.valid, ast_channel_caller(chan)->
id.
number.str, NULL))) {
1228 char buf[2] = { 0, };
1229 snprintf(buf,
sizeof(buf),
"%c", res);
1230 ast_channel_exten_set(chan, buf);
1231 ast_channel_context_set(chan, args.context);
1232 ast_channel_priority_set(chan, 0);
1240 static int pbx_builtin_noop(
struct ast_channel *chan,
const char *data)
1245 static int pbx_builtin_gotoif(
struct ast_channel *chan,
const char *data)
1247 char *condition, *branch1, *branch2, *branch;
1250 if (ast_strlen_zero(data)) {
1251 ast_log(LOG_WARNING,
"Ignoring, since there is no variable to check\n");
1256 condition = strsep(&stringp,
"?");
1257 branch1 = strsep(&stringp,
":");
1258 branch2 = strsep(&stringp,
"");
1261 if (ast_strlen_zero(branch)) {
1262 ast_debug(1,
"Not taking any branch\n");
1284 ast_channel_lock(chan);
1286 ast_channel_unlock(chan);
1291 static int pbx_builtin_saynumber(
struct ast_channel *chan,
const char *data)
1300 if (ast_strlen_zero(data)) {
1301 ast_log(LOG_WARNING,
"SayNumber requires an argument (number)\n");
1305 strsep(&number,
",");
1308 ast_log(LOG_WARNING,
"argument '%s' to SayNumber could not be parsed as a number.\n", tmp);
1312 options = strsep(&number,
",");
1314 if ( strcasecmp(options,
"f") && strcasecmp(options,
"m") &&
1315 strcasecmp(options,
"c") && strcasecmp(options,
"n") ) {
1316 ast_log(LOG_WARNING,
"SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
1321 res =
ast_say_number(chan, number_val, interrupt ? AST_DIGIT_ANY :
"", ast_channel_language(chan), options);
1323 if (res < 0 && !ast_check_hangup_locked(chan)) {
1324 ast_log(LOG_WARNING,
"We were unable to say the number %s, is it too large?\n", tmp);
1327 return interrupt ? res : 0;
1330 static int pbx_builtin_sayordinal(
struct ast_channel *chan,
const char *data)
1339 if (ast_strlen_zero(data)) {
1340 ast_log(LOG_WARNING,
"SayOrdinal requires an argument (number)\n");
1344 strsep(&number,
",");
1347 ast_log(LOG_WARNING,
"argument '%s' to SayOrdinal could not be parsed as a number.\n", tmp);
1351 options = strsep(&number,
",");
1353 if ( strcasecmp(options,
"f") && strcasecmp(options,
"m") &&
1354 strcasecmp(options,
"c") && strcasecmp(options,
"n") ) {
1355 ast_log(LOG_WARNING,
"SayOrdinal gender option is either 'f', 'm', 'c' or 'n'\n");
1360 res =
ast_say_ordinal(chan, number_val, interrupt ? AST_DIGIT_ANY :
"", ast_channel_language(chan), options);
1362 if (res < 0 && !ast_check_hangup_locked(chan)) {
1363 ast_log(LOG_WARNING,
"We were unable to say the number %s, is it too large?\n", tmp);
1366 return interrupt ? res : 0;
1369 static int pbx_builtin_saydigits(
struct ast_channel *chan,
const char *data)
1380 static int pbx_builtin_saymoney(
struct ast_channel *chan,
const char *data)
1391 static int pbx_builtin_saycharacters_case(
struct ast_channel *chan,
const char *data)
1394 int sensitivity = 0;
1402 if (ast_strlen_zero(data)) {
1403 ast_log(LOG_WARNING,
"SayAlphaCase requires two arguments (options, characters)\n");
1410 if (!args.options || strlen(args.options) != 1) {
1411 ast_log(LOG_WARNING,
"SayAlphaCase options are mutually exclusive and required\n");
1415 switch (args.options[0]) {
1429 ast_log(LOG_WARNING,
"Invalid option: '%s'\n", args.options);
1438 static int pbx_builtin_saycharacters(
struct ast_channel *chan,
const char *data)
1449 static int pbx_builtin_sayphonetic(
struct ast_channel *chan,
const char *data)
1454 res = ast_say_phonetic_str(chan, data,
permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY :
"", ast_channel_language(chan));
1469 {
"Answer", pbx_builtin_answer },
1470 {
"BackGround", pbx_builtin_background },
1471 {
"Busy", indicate_busy },
1473 {
"ExecIfTime", pbx_builtin_execiftime },
1475 {
"GotoIf", pbx_builtin_gotoif },
1476 {
"GotoIfTime", pbx_builtin_gotoiftime },
1477 {
"Hangup", pbx_builtin_hangup },
1478 {
"Incomplete", pbx_builtin_incomplete },
1479 {
"NoOp", pbx_builtin_noop },
1480 {
"Proceeding", pbx_builtin_proceeding },
1481 {
"Progress", pbx_builtin_progress },
1482 {
"RaiseException", pbx_builtin_raise_exception },
1483 {
"Ringing", pbx_builtin_ringing },
1484 {
"SayAlpha", pbx_builtin_saycharacters },
1485 {
"SayAlphaCase", pbx_builtin_saycharacters_case },
1486 {
"SayDigits", pbx_builtin_saydigits },
1487 {
"SayMoney", pbx_builtin_saymoney },
1488 {
"SayNumber", pbx_builtin_saynumber },
1489 {
"SayOrdinal", pbx_builtin_sayordinal },
1490 {
"SayPhonetic", pbx_builtin_sayphonetic },
1491 {
"Wait", pbx_builtin_wait },
1492 {
"WaitDigit", pbx_builtin_waitdigit },
1493 {
"WaitExten", pbx_builtin_waitexten }
1496 static void unload_pbx_builtins(
void)
1501 for (x = 0; x < ARRAY_LEN(builtins); x++) {
1511 for (x = 0; x < ARRAY_LEN(builtins); x++) {
1513 ast_log(LOG_ERROR,
"Unable to register builtin application '%s'\n", builtins[x].name);
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
Main Channel structure associated with a channel.
int ast_check_timing2(const struct ast_timing *i, const struct timeval tv)
Evaluate a pre-constructed bitmap as to whether a particular time falls within the range specified...
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Asterisk main include file. File version handling, generic pbx functions.
int ast_build_timing(struct ast_timing *i, const char *info_in)
Construct a timing bitmap, for use in time-based conditionals.
static SQLHSTMT execute(struct odbc_obj *obj, void *data, int silent)
Common execution function for SQL queries.
Private include file for pbx.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
int pbx_checkcondition(const char *condition)
Evaluate a condition.
int ast_say_ordinal(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an ordinal number
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
ast_channel_state
ast_channel states
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int ast_say_money_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
function to pronounce monetary amounts
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
int ast_unregister_application(const char *app)
Unregister an application.
int load_pbx_builtins(void)
int ast_raw_answer(struct ast_channel *chan)
Answer a channel.
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int args
This gets set in ast_cli_register()
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
int indicate_congestion(struct ast_channel *chan, const char *data)
int raise_exception(struct ast_channel *chan, const char *reason, int priority)
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
#define ast_strdupa(s)
duplicate a string in memory from the stack
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Conversion utility functions.
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
#define ast_debug(level,...)
Log a DEBUG message.
int ast_say_character_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity)
function to pronounce character and phonetic strings
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Core PBX routines and definitions.
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
int ast_str_to_int(const char *str, int *res)
Convert the given string to a signed integer.
#define AST_PBX_INCOMPLETE
void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
int ast_pbx_exec_application(struct ast_channel *chan, const char *app_name, const char *app_args)
Execute an application.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
int ast_check_timing(const struct ast_timing *i)
Evaluate a pre-constructed bitmap as to whether the current time falls within the range specified...
static int permit_dtmf_interrupt(struct ast_channel *chan)
Determine if DTMF interruption was requested.
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
const ast_string_field name
int __ast_answer(struct ast_channel *chan, unsigned int delay)
Answer a channel, with a selectable delay before returning.
int ast_destroy_timing(struct ast_timing *i)
Deallocates memory structures associated with a timing bitmap.
Prototypes for public functions only of internal interest,.
Structure used to handle boolean flags.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
static int pbx_builtin_goto(struct ast_channel *chan, const char *data)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
int ast_answer(struct ast_channel *chan)
Answer a channel.
Internal Asterisk hangup causes.
int ast_register_application2(const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
Register an application.
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
const char * data
Description of a tone.
int ast_str2cause(const char *name) attribute_pure
Convert the string form of a cause code to a number.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
int ast_app_parse_timelen(const char *timestr, int *result, enum ast_timelen defunit)
Common routine to parse time lengths, with optional time unit specifier.
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Say numbers and dates (maybe words one day too)
Asterisk module definitions.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
int ast_waitfordigit_full(struct ast_channel *c, int ms, const char *breakon, int audiofd, int ctrlfd)
Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to mon...
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Declaration of builtin applications.
int ast_waitstream_exten(struct ast_channel *c, const char *context)
Waits for a stream to stop or digit matching a valid one digit exten to be pressed.
#define AST_APP_ARG(name)
Define an application argument.