00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "asterisk.h"
00028
00029 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 168549 $")
00030
00031 #include "asterisk/module.h"
00032 #include "asterisk/channel.h"
00033 #include "asterisk/pbx.h"
00034 #include "asterisk/utils.h"
00035 #include "asterisk/app.h"
00036
00037 static int isnull(struct ast_channel *chan, const char *cmd, char *data,
00038 char *buf, size_t len)
00039 {
00040 strcpy(buf, data && *data ? "0" : "1");
00041
00042 return 0;
00043 }
00044
00045 static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf,
00046 size_t len)
00047 {
00048 strcpy(buf, data && *data ? "1" : "0");
00049
00050 return 0;
00051 }
00052
00053 static int iftime(struct ast_channel *chan, const char *cmd, char *data, char *buf,
00054 size_t len)
00055 {
00056 struct ast_timing timing;
00057 char *expr;
00058 char *iftrue;
00059 char *iffalse;
00060
00061 data = ast_strip_quoted(data, "\"", "\"");
00062 expr = strsep(&data, "?");
00063 iftrue = strsep(&data, ":");
00064 iffalse = data;
00065
00066 if (ast_strlen_zero(expr) || !(iftrue || iffalse)) {
00067 ast_log(LOG_WARNING,
00068 "Syntax IFTIME(<timespec>?[<true>][:<false>])\n");
00069 return -1;
00070 }
00071
00072 if (!ast_build_timing(&timing, expr)) {
00073 ast_log(LOG_WARNING, "Invalid Time Spec.\n");
00074 return -1;
00075 }
00076
00077 if (iftrue)
00078 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
00079 if (iffalse)
00080 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
00081
00082 ast_copy_string(buf, ast_check_timing(&timing) ? S_OR(iftrue, "") : S_OR(iffalse, ""), len);
00083
00084 return 0;
00085 }
00086
00087 static int acf_if(struct ast_channel *chan, const char *cmd, char *data, char *buf,
00088 size_t len)
00089 {
00090 AST_DECLARE_APP_ARGS(args1,
00091 AST_APP_ARG(expr);
00092 AST_APP_ARG(remainder);
00093 );
00094 AST_DECLARE_APP_ARGS(args2,
00095 AST_APP_ARG(iftrue);
00096 AST_APP_ARG(iffalse);
00097 );
00098 args2.iftrue = args2.iffalse = NULL;
00099
00100
00101
00102
00103
00104
00105 AST_NONSTANDARD_APP_ARGS(args1, data, '?');
00106 AST_NONSTANDARD_APP_ARGS(args2, args1.remainder, ':');
00107
00108 if (ast_strlen_zero(args1.expr) || !(args2.iftrue || args2.iffalse)) {
00109 ast_log(LOG_WARNING, "Syntax IF(<expr>?[<true>][:<false>]) (expr must be non-null, and either <true> or <false> must be non-null)\n");
00110 ast_log(LOG_WARNING, " In this case, <expr>='%s', <true>='%s', and <false>='%s'\n", args1.expr, args2.iftrue, args2.iffalse);
00111 return -1;
00112 }
00113
00114 args1.expr = ast_strip(args1.expr);
00115 if (args2.iftrue)
00116 args2.iftrue = ast_strip(args2.iftrue);
00117 if (args2.iffalse)
00118 args2.iffalse = ast_strip(args2.iffalse);
00119
00120 ast_copy_string(buf, pbx_checkcondition(args1.expr) ? (S_OR(args2.iftrue, "")) : (S_OR(args2.iffalse, "")), len);
00121
00122 return 0;
00123 }
00124
00125 static int set(struct ast_channel *chan, const char *cmd, char *data, char *buf,
00126 size_t len)
00127 {
00128 char *varname;
00129 char *val;
00130
00131 varname = strsep(&data, "=");
00132 val = data;
00133
00134 if (ast_strlen_zero(varname) || !val) {
00135 ast_log(LOG_WARNING, "Syntax SET(<varname>=[<value>])\n");
00136 return -1;
00137 }
00138
00139 varname = ast_strip(varname);
00140 val = ast_strip(val);
00141 pbx_builtin_setvar_helper(chan, varname, val);
00142 ast_copy_string(buf, val, len);
00143
00144 return 0;
00145 }
00146
00147 static int acf_import(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
00148 {
00149 AST_DECLARE_APP_ARGS(args,
00150 AST_APP_ARG(channel);
00151 AST_APP_ARG(varname);
00152 );
00153 AST_STANDARD_APP_ARGS(args, data);
00154 buf[0] = 0;
00155 if (!ast_strlen_zero(args.varname)) {
00156 struct ast_channel *chan2 = ast_get_channel_by_name_locked(args.channel);
00157 if (chan2) {
00158 char *s = alloca(strlen(args.varname) + 4);
00159 if (s) {
00160 sprintf(s, "${%s}", args.varname);
00161 pbx_substitute_variables_helper(chan2, s, buf, len);
00162 }
00163 ast_channel_unlock(chan2);
00164 }
00165 }
00166 return 0;
00167 }
00168
00169 static struct ast_custom_function isnull_function = {
00170 .name = "ISNULL",
00171 .synopsis = "NULL Test: Returns 1 if NULL or 0 otherwise",
00172 .syntax = "ISNULL(<data>)",
00173 .read = isnull,
00174 };
00175
00176 static struct ast_custom_function set_function = {
00177 .name = "SET",
00178 .synopsis = "SET assigns a value to a channel variable",
00179 .syntax = "SET(<varname>=[<value>])",
00180 .read = set,
00181 };
00182
00183 static struct ast_custom_function exists_function = {
00184 .name = "EXISTS",
00185 .synopsis = "Existence Test: Returns 1 if exists, 0 otherwise",
00186 .syntax = "EXISTS(<data>)",
00187 .read = exists,
00188 };
00189
00190 static struct ast_custom_function if_function = {
00191 .name = "IF",
00192 .synopsis =
00193 "Conditional: Returns the data following '?' if true, else the data following ':'",
00194 .syntax = "IF(<expr>?[<true>][:<false>])",
00195 .read = acf_if,
00196 };
00197
00198 static struct ast_custom_function if_time_function = {
00199 .name = "IFTIME",
00200 .synopsis =
00201 "Temporal Conditional: Returns the data following '?' if true, else the data following ':'",
00202 .syntax = "IFTIME(<timespec>?[<true>][:<false>])",
00203 .read = iftime,
00204 };
00205
00206 static struct ast_custom_function import_function = {
00207 .name = "IMPORT",
00208 .synopsis =
00209 "Retrieve the value of a variable from another channel\n",
00210 .syntax = "IMPORT(channel,variable)",
00211 .read = acf_import,
00212 };
00213
00214 static int unload_module(void)
00215 {
00216 int res = 0;
00217
00218 res |= ast_custom_function_unregister(&isnull_function);
00219 res |= ast_custom_function_unregister(&set_function);
00220 res |= ast_custom_function_unregister(&exists_function);
00221 res |= ast_custom_function_unregister(&if_function);
00222 res |= ast_custom_function_unregister(&if_time_function);
00223 res |= ast_custom_function_unregister(&import_function);
00224
00225 return res;
00226 }
00227
00228 static int load_module(void)
00229 {
00230 int res = 0;
00231
00232 res |= ast_custom_function_register(&isnull_function);
00233 res |= ast_custom_function_register(&set_function);
00234 res |= ast_custom_function_register(&exists_function);
00235 res |= ast_custom_function_register(&if_function);
00236 res |= ast_custom_function_register(&if_time_function);
00237 res |= ast_custom_function_register(&import_function);
00238
00239 return res;
00240 }
00241
00242 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Logical dialplan functions");