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$")
00030
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <sys/types.h>
00035
00036 #include "asterisk/module.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/logger.h"
00040 #include "asterisk/utils.h"
00041 #include "asterisk/app.h"
00042
00043 static int isnull(struct ast_channel *chan, char *cmd, char *data,
00044 char *buf, size_t len)
00045 {
00046 strcpy(buf, data && *data ? "0" : "1");
00047
00048 return 0;
00049 }
00050
00051 static int exists(struct ast_channel *chan, char *cmd, char *data, char *buf,
00052 size_t len)
00053 {
00054 strcpy(buf, data && *data ? "1" : "0");
00055
00056 return 0;
00057 }
00058
00059 static int iftime(struct ast_channel *chan, char *cmd, char *data, char *buf,
00060 size_t len)
00061 {
00062 struct ast_timing timing;
00063 char *expr;
00064 char *iftrue;
00065 char *iffalse;
00066
00067 data = ast_strip_quoted(data, "\"", "\"");
00068 expr = strsep(&data, "?");
00069 iftrue = strsep(&data, ":");
00070 iffalse = data;
00071
00072 if (ast_strlen_zero(expr) || !(iftrue || iffalse)) {
00073 ast_log(LOG_WARNING,
00074 "Syntax IFTIME(<timespec>?[<true>][:<false>])\n");
00075 return -1;
00076 }
00077
00078 if (!ast_build_timing(&timing, expr)) {
00079 ast_log(LOG_WARNING, "Invalid Time Spec.\n");
00080 return -1;
00081 }
00082
00083 if (iftrue)
00084 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
00085 if (iffalse)
00086 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
00087
00088 ast_copy_string(buf, ast_check_timing(&timing) ? iftrue : iffalse, len);
00089
00090 return 0;
00091 }
00092
00093 static int acf_if(struct ast_channel *chan, char *cmd, char *data, char *buf,
00094 size_t len)
00095 {
00096 AST_DECLARE_APP_ARGS(args1,
00097 AST_APP_ARG(expr);
00098 AST_APP_ARG(remainder);
00099 );
00100 AST_DECLARE_APP_ARGS(args2,
00101 AST_APP_ARG(iftrue);
00102 AST_APP_ARG(iffalse);
00103 );
00104 args2.iftrue = args2.iffalse = NULL;
00105
00106
00107
00108
00109
00110
00111 AST_NONSTANDARD_APP_ARGS(args1, data, '?');
00112 AST_NONSTANDARD_APP_ARGS(args2, args1.remainder, ':');
00113
00114 if (ast_strlen_zero(args1.expr) || !(args2.iftrue || args2.iffalse)) {
00115 ast_log(LOG_WARNING, "Syntax IF(<expr>?[<true>][:<false>]) (expr must be non-null, and either <true> or <false> must be non-null)\n");
00116 ast_log(LOG_WARNING, " In this case, <expr>='%s', <true>='%s', and <false>='%s'\n", args1.expr, args2.iftrue, args2.iffalse);
00117 return -1;
00118 }
00119
00120 args1.expr = ast_strip(args1.expr);
00121 if (args2.iftrue)
00122 args2.iftrue = ast_strip(args2.iftrue);
00123 if (args2.iffalse)
00124 args2.iffalse = ast_strip(args2.iffalse);
00125
00126 ast_copy_string(buf, pbx_checkcondition(args1.expr) ? (S_OR(args2.iftrue, "")) : (S_OR(args2.iffalse, "")), len);
00127
00128 return 0;
00129 }
00130
00131 static int set(struct ast_channel *chan, char *cmd, char *data, char *buf,
00132 size_t len)
00133 {
00134 char *varname;
00135 char *val;
00136
00137 varname = strsep(&data, "=");
00138 val = data;
00139
00140 if (ast_strlen_zero(varname) || !val) {
00141 ast_log(LOG_WARNING, "Syntax SET(<varname>=[<value>])\n");
00142 return -1;
00143 }
00144
00145 varname = ast_strip(varname);
00146 val = ast_strip(val);
00147 pbx_builtin_setvar_helper(chan, varname, val);
00148 ast_copy_string(buf, val, len);
00149
00150 return 0;
00151 }
00152
00153 static struct ast_custom_function isnull_function = {
00154 .name = "ISNULL",
00155 .synopsis = "NULL Test: Returns 1 if NULL or 0 otherwise",
00156 .syntax = "ISNULL(<data>)",
00157 .read = isnull,
00158 };
00159
00160 static struct ast_custom_function set_function = {
00161 .name = "SET",
00162 .synopsis = "SET assigns a value to a channel variable",
00163 .syntax = "SET(<varname>=[<value>])",
00164 .read = set,
00165 };
00166
00167 static struct ast_custom_function exists_function = {
00168 .name = "EXISTS",
00169 .synopsis = "Existence Test: Returns 1 if exists, 0 otherwise",
00170 .syntax = "EXISTS(<data>)",
00171 .read = exists,
00172 };
00173
00174 static struct ast_custom_function if_function = {
00175 .name = "IF",
00176 .synopsis =
00177 "Conditional: Returns the data following '?' if true else the data following ':'",
00178 .syntax = "IF(<expr>?[<true>][:<false>])",
00179 .read = acf_if,
00180 };
00181
00182 static struct ast_custom_function if_time_function = {
00183 .name = "IFTIME",
00184 .synopsis =
00185 "Temporal Conditional: Returns the data following '?' if true else the data following ':'",
00186 .syntax = "IFTIME(<timespec>?[<true>][:<false>])",
00187 .read = iftime,
00188 };
00189
00190 static int unload_module(void)
00191 {
00192 int res = 0;
00193
00194 res |= ast_custom_function_unregister(&isnull_function);
00195 res |= ast_custom_function_unregister(&set_function);
00196 res |= ast_custom_function_unregister(&exists_function);
00197 res |= ast_custom_function_unregister(&if_function);
00198 res |= ast_custom_function_unregister(&if_time_function);
00199
00200 return res;
00201 }
00202
00203 static int load_module(void)
00204 {
00205 int res = 0;
00206
00207 res |= ast_custom_function_register(&isnull_function);
00208 res |= ast_custom_function_register(&set_function);
00209 res |= ast_custom_function_register(&exists_function);
00210 res |= ast_custom_function_register(&if_function);
00211 res |= ast_custom_function_register(&if_time_function);
00212
00213 return res;
00214 }
00215
00216 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Logical dialplan functions");