[asterisk-commits] branch murf/AEL2-1.2 r17103 - in
/team/murf/AEL2-1.2: ./ configs/ doc/ includ...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Apr 3 11:24:06 MST 2006
Author: murf
Date: Mon Apr 3 13:23:47 2006
New Revision: 17103
URL: http://svn.digium.com/view/asterisk?rev=17103&view=rev
Log:
am folding in the AEL2 files. Can't forget those properties!!
Added:
team/murf/AEL2-1.2/doc/ael2.txt (with props)
team/murf/AEL2-1.2/include/asterisk/ael_structs.h (with props)
team/murf/AEL2-1.2/include/asterisk/argdesc.h (with props)
team/murf/AEL2-1.2/pbx/ael.flex (with props)
team/murf/AEL2-1.2/pbx/ael.tab.c (with props)
team/murf/AEL2-1.2/pbx/ael.tab.h (with props)
team/murf/AEL2-1.2/pbx/ael.y (with props)
team/murf/AEL2-1.2/pbx/ael_lex.c (with props)
team/murf/AEL2-1.2/pbx/applist (with props)
team/murf/AEL2-1.2/pbx/argdesc.l (with props)
team/murf/AEL2-1.2/pbx/argdesc.tab.c (with props)
team/murf/AEL2-1.2/pbx/argdesc.tab.h (with props)
team/murf/AEL2-1.2/pbx/argdesc.y (with props)
team/murf/AEL2-1.2/pbx/argdesc_lex.c (with props)
team/murf/AEL2-1.2/pbx/pbx_ael2.c (with props)
team/murf/AEL2-1.2/utils/ael_main.c (with props)
team/murf/AEL2-1.2/utils/expr2.testinput (with props)
Modified:
team/murf/AEL2-1.2/ (props changed)
team/murf/AEL2-1.2/CREDITS
team/murf/AEL2-1.2/ast_expr2.fl
team/murf/AEL2-1.2/ast_expr2.h
team/murf/AEL2-1.2/ast_expr2.y
team/murf/AEL2-1.2/configs/extensions.ael.sample
team/murf/AEL2-1.2/pbx/Makefile
team/murf/AEL2-1.2/utils/Makefile
Propchange: team/murf/AEL2-1.2/
------------------------------------------------------------------------------
automerge = yessir
Propchange: team/murf/AEL2-1.2/
------------------------------------------------------------------------------
svnmerge-integrated = /branches/1.2:1-17072
Modified: team/murf/AEL2-1.2/CREDITS
URL: http://svn.digium.com/view/asterisk/team/murf/AEL2-1.2/CREDITS?rev=17103&r1=17102&r2=17103&view=diff
==============================================================================
--- team/murf/AEL2-1.2/CREDITS (original)
+++ team/murf/AEL2-1.2/CREDITS Mon Apr 3 13:23:47 2006
@@ -74,7 +74,7 @@
Steve Kann - new jitter buffer for IAX2
stevek at stevek.com
Constantine Filin - major contributions to the Asterisk Realtime Architecture
-Steve Murphy - privacy support
+Steve Murphy - privacy support, $[ ] parser upgrade, AEL2 parser upgrade
Claude Patry - bug fixes, feature enhancements, and bug marshalling
cpatry at gmail.com
Modified: team/murf/AEL2-1.2/ast_expr2.fl
URL: http://svn.digium.com/view/asterisk/team/murf/AEL2-1.2/ast_expr2.fl?rev=17103&r1=17102&r2=17103&view=diff
==============================================================================
--- team/murf/AEL2-1.2/ast_expr2.fl (original)
+++ team/murf/AEL2-1.2/ast_expr2.fl Mon Apr 3 13:23:47 2006
@@ -1,7 +1,25 @@
%{
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
/*! \file
*
- * \brief Dialplan Expression Parser
+ * \brief Dialplan Expression Lexical Scanner
*/
#include <sys/types.h>
@@ -50,6 +68,7 @@
void ast_yyset_column(int column_no, yyscan_t yyscanner);
int ast_yyget_column(yyscan_t yyscanner);
static int curlycount = 0;
+static char *expr2_token_subst(char *mess);
%}
%option prefix="ast_yy"
@@ -66,6 +85,10 @@
\| { SET_COLUMNS; SET_STRING; return TOK_OR;}
\& { SET_COLUMNS; SET_STRING; return TOK_AND;}
\= { SET_COLUMNS; SET_STRING; return TOK_EQ;}
+\|\| { SET_COLUMNS; SET_STRING; return TOK_OR;}
+\&\& { SET_COLUMNS; SET_STRING; return TOK_AND;}
+\=\= { SET_COLUMNS; SET_STRING; return TOK_EQ;}
+\=~ { SET_COLUMNS; SET_STRING; return TOK_EQTILDE;}
\> { SET_COLUMNS; SET_STRING; return TOK_GT;}
\< { SET_COLUMNS; SET_STRING; return TOK_LT;}
\>\= { SET_COLUMNS; SET_STRING; return TOK_GE;}
@@ -77,6 +100,7 @@
\/ { SET_COLUMNS; SET_STRING; return TOK_DIV;}
\% { SET_COLUMNS; SET_STRING; return TOK_MOD;}
\? { SET_COLUMNS; SET_STRING; return TOK_COND;}
+\! { SET_COLUMNS; SET_STRING; return TOK_COMPL;}
\: { SET_COLUMNS; SET_STRING; return TOK_COLON;}
\:\: { SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;}
\( { SET_COLUMNS; SET_STRING; return TOK_LP;}
@@ -91,14 +115,15 @@
[0-9]+ { SET_COLUMNS; /* the original behavior of the expression parser was to bring in numbers as a numeric string */
SET_NUMERIC_STRING;
return TOKEN;}
-[a-zA-Z0-9,.';\\_^%$#@!]+ {SET_COLUMNS; SET_STRING; return TOKEN;}
+
+[a-zA-Z0-9,.';\\_^$#@]+ {SET_COLUMNS; SET_STRING; return TOKEN;}
<var>[^{}]*\} {curlycount--; if(curlycount < 0){ BEGIN(trail); yymore();} else { yymore();}}
<var>[^{}]*\{ {curlycount++; yymore(); }
<trail>[^-\t\r \n$():?%/+=*<>!|&]* {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN;}
<trail>[-\t\r \n$():?%/+=*<>!|&] {char c = yytext[yyleng-1]; BEGIN(0); unput(c); SET_COLUMNS; SET_STRING; return TOKEN;}
<trail>\$\{ {curlycount = 0; BEGIN(var); yymore(); }
-<trail><<EOF>> {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN; /* actually, if an expr is only a variable ref, this could happen a LOT */}
+<trail><<EOF>> {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN; /*actually, if an expr is only a variable ref, this could happen a LOT */}
%%
@@ -152,16 +177,129 @@
return return_value;
}
+
+char extra_error_message[4095];
+int extra_error_message_supplied = 0;
+void ast_expr_register_extra_error_info(char *message);
+void ast_expr_clear_extra_error_info(void);
+
+void ast_expr_register_extra_error_info(char *message)
+{
+ extra_error_message_supplied=1;
+ strcpy(extra_error_message, message);
+}
+
+void ast_expr_clear_extra_error_info(void)
+{
+ extra_error_message_supplied=0;
+ extra_error_message[0] = 0;
+}
+
+static char *expr2_token_equivs1[] =
+{
+ "TOKEN",
+ "TOK_COND",
+ "TOK_COLONCOLON",
+ "TOK_OR",
+ "TOK_AND",
+ "TOK_EQ",
+ "TOK_GT",
+ "TOK_LT",
+ "TOK_GE",
+ "TOK_LE",
+ "TOK_NE",
+ "TOK_PLUS",
+ "TOK_MINUS",
+ "TOK_MULT",
+ "TOK_DIV",
+ "TOK_MOD",
+ "TOK_COMPL",
+ "TOK_COLON",
+ "TOK_EQTILDE",
+ "TOK_RP",
+ "TOK_LP"
+};
+
+static char *expr2_token_equivs2[] =
+{
+ "<token>",
+ "?",
+ "::",
+ "|",
+ "&",
+ "=",
+ ">",
+ "<",
+ ">=",
+ "<=",
+ "!=",
+ "+",
+ "-",
+ "*",
+ "/",
+ "%",
+ "!",
+ ":",
+ "=~",
+ ")",
+ "("
+};
+
+
+static char *expr2_token_subst(char *mess)
+{
+ /* calc a length, malloc, fill, and return; yyerror had better free it! */
+ int len=0,i;
+ char *p;
+ char *res, *s,*t;
+ int expr2_token_equivs_entries = sizeof(expr2_token_equivs1)/sizeof(char*);
+
+ for (p=mess; *p; p++) {
+ for (i=0; i<expr2_token_equivs_entries; i++) {
+ if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 )
+ {
+ len+=strlen(expr2_token_equivs2[i])+2;
+ p += strlen(expr2_token_equivs1[i])-1;
+ break;
+ }
+ }
+ len++;
+ }
+ res = (char*)malloc(len+1);
+ res[0] = 0;
+ s = res;
+ for (p=mess; *p;) {
+ int found = 0;
+ for (i=0; i<expr2_token_equivs_entries; i++) {
+ if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 ) {
+ *s++ = '\'';
+ for (t=expr2_token_equivs2[i]; *t;) {
+ *s++ = *t++;
+ }
+ *s++ = '\'';
+ p += strlen(expr2_token_equivs1[i]);
+ found = 1;
+ break;
+ }
+ }
+ if( !found )
+ *s++ = *p++;
+ }
+ *s++ = 0;
+ return res;
+}
+
int ast_yyerror (const char *s, yyltype *loc, struct parse_io *parseio )
{
struct yyguts_t * yyg = (struct yyguts_t*)(parseio->scanner);
char spacebuf[8000]; /* best safe than sorry */
char spacebuf2[8000]; /* best safe than sorry */
int i=0;
+ char *s2 = expr2_token_subst((char *)s);
spacebuf[0] = 0;
for(i=0;i< (int)(yytext - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);i++) spacebuf2[i] = ' '; /* uh... assuming yyg is defined, then I can use the yycolumn macro,
- which is the same thing as... get this:
+ which is the same thing as... get this:
yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]->yy_bs_column
I was tempted to just use yy_buf_pos in the STATE, but..., well:
a. the yy_buf_pos is the current position in the buffer, which
@@ -176,14 +314,15 @@
#ifdef STANDALONE3
/* easier to read in the standalone version */
- printf("ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n",
- s, parseio->string,spacebuf2);
+ printf("ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",
+ (extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
#else
- ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n",
- s, parseio->string,spacebuf2);
+ ast_log(LOG_WARNING,"ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",
+ (extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
#endif
#ifndef STANDALONE
- ast_log(LOG_WARNING,"If you have questions, please refer to doc/README.variables in the asterisk source.\n");
+ ast_log(LOG_WARNING,"If you have questions, please refer to doc/channelvariables.txt in the asterisk source.\n");
#endif
+ free(s2);
return(0);
}
Modified: team/murf/AEL2-1.2/ast_expr2.h
URL: http://svn.digium.com/view/asterisk/team/murf/AEL2-1.2/ast_expr2.h?rev=17103&r1=17102&r2=17103&view=diff
==============================================================================
--- team/murf/AEL2-1.2/ast_expr2.h (original)
+++ team/murf/AEL2-1.2/ast_expr2.h Mon Apr 3 13:23:47 2006
@@ -78,7 +78,7 @@
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 142 "ast_expr2.y"
+#line 140 "ast_expr2.y"
typedef union YYSTYPE {
struct val *val;
} YYSTYPE;
Modified: team/murf/AEL2-1.2/ast_expr2.y
URL: http://svn.digium.com/view/asterisk/team/murf/AEL2-1.2/ast_expr2.y?rev=17103&r1=17102&r2=17103&view=diff
==============================================================================
--- team/murf/AEL2-1.2/ast_expr2.y (original)
+++ team/murf/AEL2-1.2/ast_expr2.y Mon Apr 3 13:23:47 2006
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <string.h>
#include <locale.h>
+#include <unistd.h>
#include <ctype.h>
#if !defined(SOLARIS) && !defined(__CYGWIN__)
#include <err.h>
@@ -46,6 +47,8 @@
#define YYPARSE_PARAM parseio
#define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
#define YYERROR_VERBOSE 1
+extern char extra_error_message[4095];
+extern int extra_error_message_supplied;
enum valtype {
AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
@@ -124,12 +127,7 @@
some useful info about the error. Not as easy as it looks, but it
is possible. */
#define ast_yyerror(x) ast_yyerror(x,&yyloc,parseio)
-#define DESTROY(x) { \
-if ((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) \
- free((x)->u.s); \
- (x)->u.s = 0; \
- free(x); \
-}
+#define DESTROY(x) {if((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) free((x)->u.s); (x)->u.s = 0; free(x);}
%}
%pure-parser
@@ -170,6 +168,11 @@
((struct parse_io *)parseio)->val->u.s = $1->u.s;
free($1);
}
+ | {/* nothing */ ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
+ ((struct parse_io *)parseio)->val->type = AST_EXPR_string;
+ ((struct parse_io *)parseio)->val->u.s = strdup("");
+ }
+
;
expr: TOKEN { $$= $1;}
@@ -422,11 +425,40 @@
int main(int argc,char **argv) {
char s[4096];
+ char out[4096];
+ FILE *infile;
- if (ast_expr(argv[1], s, sizeof(s)))
- printf("=====%s======\n",s);
+ if( !argv[1] )
+ exit(20);
+
+ if( access(argv[1],F_OK)== 0 )
+ {
+ int ret;
+
+ infile = fopen(argv[1],"r");
+ if( !infile )
+ {
+ printf("Sorry, couldn't open %s for reading!\n", argv[1]);
+ exit(10);
+ }
+ while( fgets(s,sizeof(s),infile) )
+ {
+ if( s[strlen(s)-1] == '\n' )
+ s[strlen(s)-1] = 0;
+
+ ret = ast_expr(s, out, sizeof(out));
+ printf("Expression: %s Result: [%d] '%s'\n",
+ s, ret, out);
+ }
+ fclose(infile);
+ }
else
- printf("No result\n");
+ {
+ if (ast_expr(argv[1], s, sizeof(s)))
+ printf("=====%s======\n",s);
+ else
+ printf("No result\n");
+ }
}
#endif
@@ -650,7 +682,8 @@
struct val *r;
if (!to_integer (a)) {
- ast_log(LOG_WARNING,"non-numeric argument\n");
+ if( !extra_error_message_supplied )
+ ast_log(LOG_WARNING,"non-numeric argument\n");
if (!to_integer (b)) {
free_value(a);
free_value(b);
@@ -693,7 +726,8 @@
struct val *r;
if (!to_integer (a)) {
- ast_log(LOG_WARNING, "non-numeric argument\n");
+ if( !extra_error_message_supplied )
+ ast_log(LOG_WARNING, "non-numeric argument\n");
if (!to_integer (b)) {
free_value(a);
free_value(b);
@@ -705,7 +739,8 @@
return (r);
}
} else if (!to_integer(b)) {
- ast_log(LOG_WARNING, "non-numeric argument\n");
+ if( !extra_error_message_supplied )
+ ast_log(LOG_WARNING, "non-numeric argument\n");
free_value(b);
return (a);
}
@@ -726,7 +761,8 @@
if (!to_integer (a) ) {
free_value(a);
- ast_log(LOG_WARNING, "non-numeric argument\n");
+ if( !extra_error_message_supplied )
+ ast_log(LOG_WARNING, "non-numeric argument\n");
return make_integer(0);
}
@@ -808,7 +844,8 @@
if (!to_integer (a) || !to_integer (b)) {
free_value(a);
free_value(b);
- ast_log(LOG_WARNING, "non-numeric argument\n");
+ if( !extra_error_message_supplied )
+ ast_log(LOG_WARNING, "non-numeric argument\n");
return(make_integer(0));
}
@@ -840,12 +877,14 @@
if (!to_integer (a)) {
free_value(a);
free_value(b);
- ast_log(LOG_WARNING, "non-numeric argument\n");
+ if( !extra_error_message_supplied )
+ ast_log(LOG_WARNING, "non-numeric argument\n");
return make_integer(0);
} else if (!to_integer (b)) {
free_value(a);
free_value(b);
- ast_log(LOG_WARNING, "non-numeric argument\n");
+ if( !extra_error_message_supplied )
+ ast_log(LOG_WARNING, "non-numeric argument\n");
return make_integer(INT_MAX);
}
@@ -871,7 +910,8 @@
struct val *r;
if (!to_integer (a) || !to_integer (b)) {
- ast_log(LOG_WARNING, "non-numeric argument\n");
+ if( !extra_error_message_supplied )
+ ast_log(LOG_WARNING, "non-numeric argument\n");
free_value(a);
free_value(b);
return make_integer(0);
Modified: team/murf/AEL2-1.2/configs/extensions.ael.sample
URL: http://svn.digium.com/view/asterisk/team/murf/AEL2-1.2/configs/extensions.ael.sample?rev=17103&r1=17102&r2=17103&view=diff
==============================================================================
--- team/murf/AEL2-1.2/configs/extensions.ael.sample (original)
+++ team/murf/AEL2-1.2/configs/extensions.ael.sample Mon Apr 3 13:23:47 2006
@@ -1,6 +1,307 @@
//
// Example AEL config file
//
+//
+// Static extension configuration file, used by
+// the pbx_config module. This is where you configure all your
+// inbound and outbound calls in Asterisk.
+//
+// This configuration file is reloaded
+// - With the "extensions reload" command in the CLI
+// - With the "reload" command (that reloads everything) in the CLI
+
+// The "Globals" category contains global variables that can be referenced
+// in the dialplan with ${VARIABLE} or ${ENV(VARIABLE)} for Environmental
+// variables,
+// ${${VARIABLE}} or ${text${VARIABLE}} or any hybrid
+//
+
+globals {
+ CONSOLE="Console/dsp"; // Console interface for demo
+ //CONSOLE=Zap/1
+ //CONSOLE=Phone/phone0
+ IAXINFO=guest; // IAXtel username/password
+ //IAXINFO="myuser:mypass";
+ TRUNK="Zap/g2"; // Trunk interface
+ //
+ // Note the 'g2' in the TRUNK variable above. It specifies which group (defined
+ // in zapata.conf) to dial, i.e. group 2, and how to choose a channel to use in
+ // the specified group. The four possible options are:
+ //
+ // g: select the lowest-numbered non-busy Zap channel
+ // (aka. ascending sequential hunt group).
+ // G: select the highest-numbered non-busy Zap channel
+ // (aka. descending sequential hunt group).
+ // r: use a round-robin search, starting at the next highest channel than last
+ // time (aka. ascending rotary hunt group).
+ // R: use a round-robin search, starting at the next lowest channel than last
+ // time (aka. descending rotary hunt group).
+ //
+ TRUNKMSD=1; // MSD digits to strip (usually 1 or 0)
+ //TRUNK=IAX2/user:pass at provider
+};
+
+//
+// Any category other than "General" and "Globals" represent
+// extension contexts, which are collections of extensions.
+//
+// Extension names may be numbers, letters, or combinations
+// thereof. If an extension name is prefixed by a '_'
+// character, it is interpreted as a pattern rather than a
+// literal. In patterns, some characters have special meanings:
+//
+// X - any digit from 0-9
+// Z - any digit from 1-9
+// N - any digit from 2-9
+// [1235-9] - any digit in the brackets (in this example, 1,2,3,5,6,7,8,9)
+// . - wildcard, matches anything remaining (e.g. _9011. matches
+// anything starting with 9011 excluding 9011 itself)
+// ! - wildcard, causes the matching process to complete as soon as
+// it can unambiguously determine that no other matches are possible
+//
+// For example the extension _NXXXXXX would match normal 7 digit dialings,
+// while _1NXXNXXXXXX would represent an area code plus phone number
+// preceeded by a one.
+//
+// Each step of an extension is ordered by priority, which must
+// always start with 1 to be considered a valid extension. The priority
+// "next" or "n" means the previous priority plus one, regardless of whether
+// the previous priority was associated with the current extension or not.
+// The priority "same" or "s" means the same as the previously specified
+// priority, again regardless of whether the previous entry was for the
+// same extension. Priorities may be immediately followed by a plus sign
+// and another integer to add that amount (most useful with 's' or 'n').
+// Priorities may then also have an alias, or label, in
+// parenthesis after their name which can be used in goto situations
+//
+// Contexts contain several lines, one for each step of each
+// extension, which can take one of two forms as listed below,
+// with the first form being preferred. One may include another
+// context in the current one as well, optionally with a
+// date and time. Included contexts are included in the order
+// they are listed.
+//
+//context name {
+// exten-name => {
+// application(arg1,arg2,...);
+//
+// Timing list for includes is
+//
+// <time range>|<days of week>|<days of month>|<months>
+//
+// includes {
+// daytime|9:00-17:00|mon-fri|*|*;
+// };
+//
+// ignorepat can be used to instruct drivers to not cancel dialtone upon
+// receipt of a particular pattern. The most commonly used example is
+// of course '9' like this:
+//
+// ignorepat => 9;
+//
+// so that dialtone remains even after dialing a 9.
+//};
+
+
+//
+// Sample entries for extensions.conf
+//
+//
+context dundi-e164-canonical {
+ //
+ // List canonical entries here
+ //
+ // 12564286000 => &std-exten(6000,IAX2/foo);
+ // _125642860XX => Dial(IAX2/otherbox/${EXTEN:7});
+};
+
+context dundi-e164-customers {
+ //
+ // If you are an ITSP or Reseller, list your customers here.
+ //
+ //_12564286000 => Dial(SIP/customer1);
+ //_12564286001 => Dial(IAX2/customer2);
+};
+
+context dundi-e164-via-pstn {
+ //
+ // If you are freely delivering calls to the PSTN, list them here
+ //
+ //_1256428XXXX => Dial(Zap/g2/${EXTEN:7}); // Expose all of 256-428
+ //_1256325XXXX => Dial(Zap/g2/${EXTEN:7}); // Ditto for 256-325
+};
+
+context dundi-e164-local {
+ //
+ // Context to put your dundi IAX2 or SIP user in for
+ // full access
+ //
+ includes {
+ dundi-e164-canonical;
+ dundi-e164-customers;
+ dundi-e164-via-pstn;
+ };
+};
+
+context dundi-e164-switch {
+ //
+ // Just a wrapper for the switch
+ //
+
+ switches {
+ DUNDi/e164;
+ };
+};
+
+context dundi-e164-lookup {
+ //
+ // Locally to lookup, try looking for a local E.164 solution
+ // then try DUNDi if we don't have one.
+ //
+ includes {
+ dundi-e164-local;
+ dundi-e164-switch;
+ };
+ //
+};
+
+//
+// DUNDi can also be implemented as a Macro instead of using
+// the Local channel driver.
+//
+macro dundi-e164(exten) {
+//
+// ARG1 is the extension to Dial
+//
+ goto ${exten}|1;
+};
+
+//
+// Here are the entries you need to participate in the IAXTEL
+// call routing system. Most IAXTEL numbers begin with 1-700, but
+// there are exceptions. For more information, and to sign
+// up, please go to www.gnophone.com or www.iaxtel.com
+//
+context iaxtel700 {
+ _91700XXXXXXX => Dial(IAX2/${IAXINFO}@iaxtel.com/${EXTEN:1}@iaxtel);
+};
+
+//
+// The SWITCH statement permits a server to share the dialplain with
+// another server. Use with care: Reciprocal switch statements are not
+// allowed (e.g. both A -> B and B -> A), and the switched server needs
+// to be on-line or else dialing can be severly delayed.
+//
+context iaxprovider {
+ switches {
+ // IAX2/user:[key]@myserver/mycontext;
+ };
+};
+
+context trunkint {
+ //
+ // International long distance through trunk
+ //
+ includes {
+ dundi-e164-lookup;
+ };
+ _9011. => {
+ &dundi-e164(${EXTEN:4});
+ Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+ };
+};
+
+context trunkld {
+ //
+ // Long distance context accessed through trunk
+ //
+ includes {
+ dundi-e164-lookup;
+ };
+ _91NXXNXXXXXX => {
+ &dundi-e164(${EXTEN:1});
+ Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+ };
+};
+
+context trunklocal {
+ //
+ // Local seven-digit dialing accessed through trunk interface
+ //
+ _9NXXXXXX => {
+ Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+ };
+};
+
+context trunktollfree {
+ //
+ // Long distance context accessed through trunk interface
+ //
+
+ _91800NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+ _91888NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+ _91877NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+ _91866NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+};
+
+context international {
+ //
+ // Master context for international long distance
+ //
+ ignorepat => 9;
+ includes {
+ longdistance;
+ trunkint;
+ };
+};
+
+context longdistance {
+ //
+ // Master context for long distance
+ //
+ ignorepat => 9;
+ includes {
+ local;
+ trunkld;
+ };
+};
+
+context local {
+ //
+ // Master context for local, toll-free, and iaxtel calls only
+ //
+ ignorepat => 9;
+ includes {
+ default;
+ parkedcalls;
+ trunklocal;
+ iaxtel700;
+ trunktollfree;
+ iaxprovider;
+ };
+};
+
+//
+// You can use an alternative switch type as well, to resolve
+// extensions that are not known here, for example with remote
+// IAX switching you transparently get access to the remote
+// Asterisk PBX
+//
+// switch => IAX2/user:password at bigserver/local
+//
+// An "lswitch" is like a switch but is literal, in that
+// variable substitution is not performed at load time
+// but is passed to the switch directly (presumably to
+// be substituted in the switch routine itself)
+//
+// lswitch => Loopback/12${EXTEN}@othercontext
+//
+// An "eswitch" is like a switch but the evaluation of
+// variable substitution is performed at runtime before
+// being passed to the switch routine.
+//
+// eswitch => IAX2/context@${CURSERVER}
+
macro std-exten-ael( ext , dev ) {
Dial(${dev}/${ext},20);
@@ -21,8 +322,8 @@
s => {
Wait(1);
Answer();
- TIMEOUT(digit)=5;
- TIMEOUT(response)=10;
+ Set(TIMEOUT(digit)=5);
+ Set(TIMEOUT(response)=10);
restart:
Background(demo-congrats);
instructions:
@@ -36,12 +337,15 @@
goto s|instructions;
};
3 => {
- LANGUAGE()=fr;
+ Set(LANGUAGE()=fr);
goto s|restart;
+ };
+ 1000 => {
+ goto default|s|1;
};
500 => {
Playback(demo-abouttotry);
- Dial(IAX2/guest at misery.digium.com);
+ Dial(IAX2/guest at misery.digium.com/s at default);
Playback(demo-nogo);
goto s|instructions;
};
@@ -52,11 +356,83 @@
goto s|instructions;
};
_1234 => &std-exten-ael(${EXTEN}, "IAX2");
+ 8500 => {
+ VoicemailMain();
+ goto s|instructions;
+ };
# => {
Playback(demo-thanks);
Hangup();
};
- t => jump #;
+ t => goto #|1;
i => Playback(invalid);
};
+context default {
+
+// By default we include the demo. In a production system, you
+// probably don't want to have the demo there.
+
+ includes {
+ ael-demo;
+ };
+//
+// Extensions like the two below can be used for FWD, Nikotel, sipgate etc.
+// Note that you must have a [sipprovider] section in sip.conf whereas
+// the otherprovider.net example does not require such a peer definition
+//
+//_41X. => Dial(SIP/${EXTEN:2}@sipprovider,,r);
+//_42X. => Dial(SIP/user:passwd@${EXTEN:2}@otherprovider.net,30,rT);
+
+// Real extensions would go here. Generally you want real extensions to be
+// 4 or 5 digits long (although there is no such requirement) and start with a
+// single digit that is fairly large (like 6 or 7) so that you have plenty of
+// room to overlap extensions and menu options without conflict. You can alias
+// them with names, too, and use global variables
+
+// 6245 => {
+// hint(SIP/Grandstream1&SIP/Xlite1,Joe Schmoe); // Channel hints for presence
+// Dial(SIP/Grandstream1,20,rt); // permit transfer
+// Dial(${HINT}/5245},20,rtT); // Use hint as listed
+// switch(${DIALSTATUS}) {
+// case BUSY:
+// Voicemail(b6245);
+// return;
+// default:
+// Voicemail(u6245);
+// return;
+// };
+// };
+
+// 6361 => Dial(IAX2/JaneDoe,,rm); // ring without time limit
+// 6389 => Dial(MGCP/aaln/1 at 192.168.0.14);
+// 6394 => Dial(Local/6275/n); // this will dial ${MARK}
+
+// 6275 => &ael-stdexten(6275,${MARK}); // assuming ${MARK} is something like Zap/2
+// mark => goto 6275|1; // alias mark to 6275
+// 6536 => &ael-stdexten(6236,${WIL}); // Ditto for wil
+// wil => goto 6236|1;
+//
+// Some other handy things are an extension for checking voicemail via
+// voicemailmain
+//
+// 8500 => {
+// VoicemailMain();
+// Hangup();
+// };
+//
+// Or a conference room (you'll need to edit meetme.conf to enable this room)
+//
+// 8600 => Meetme(1234);
+//
+// Or playing an announcement to the called party, as soon it answers
+//
+// 8700 => Dial(${MARK},30,A(/path/to/my/announcemsg))
+//
+// For more information on applications, just type "show applications" at your
+// friendly Asterisk CLI prompt.
+//
+// 'show application <command>' will show details of how you
+// use that particular application in this file, the dial plan.
+//
+};
Added: team/murf/AEL2-1.2/doc/ael2.txt
URL: http://svn.digium.com/view/asterisk/team/murf/AEL2-1.2/doc/ael2.txt?rev=17103&view=auto
==============================================================================
--- team/murf/AEL2-1.2/doc/ael2.txt (added)
+++ team/murf/AEL2-1.2/doc/ael2.txt Mon Apr 3 13:23:47 2006
@@ -1,0 +1,1229 @@
+The Asterisk Extension Language - v 2
+=====================================
+
+AEL2 is a new version of the AEL compiler, written by Steve Murphy.
+
+AEL2 (like AEL) is considered an EXPERIMENTAL Version. (yet is being
+used in the field with success)
+
+AEL2 is intended to provide an actual programming language that can be
+used to write an Asterisk dialplan. It further extends AEL, and
+provides more flexible syntax, better error messages, and some missing
+functionality.
+
+AEL/AEL2 is really the merger of 4 different 'languages', or syntaxes:
+
+ * The first and most obvious is the AEL2 syntax itselft. A BNF is
+ provided near the end of this document.
+
+ * The second syntax is the Expression Syntax, which is normally
+ handled by Asterisk extension engine, as expressions enclosed in
+ $[...]. The right hand side of assignments are wrapped in $[ ... ]
+ by AEL, and so are the if and while expressions, among others.
+
+ * The third syntax is the Variable Reference Syntax, the stuff
+ enclosed in ${..} curly braces. It's a bit more involved than just
+ putting a variable name in there. You can include one of dozens of
+ 'functions', and their arguments, and there are even some string
+ manipulation notation in there.
+
+ * The last syntax that underlies AEL/AEL2, and is not used
+ directly in AEL/AEL2, is the Extension Language Syntax. The
+ extension language is what you see in extensions.conf, and AEL2
+ compiles the higher level AEL2 language into extensions and
+ priorities, and passes them via function calls into
+ Asterisk. Embedded in this language is the Application/AGI
+ commands, of which one application call per step, or priority
+ can be made. You can think of this as a "macro assembler"
+ language, that AEL2 will compile into.
+
+
+Any programmer of AEL2 should be familiar with it's syntax, of course,
+as well as the Expression syntax, and the Variable syntax.
+
+**************************
+* Asterisk in a Nutshell *
+**************************
+
+Asterisk acts as a server. Devices involved in telephony, like Zapata
+cards, or Voip phones, all indicate some context that should be
+activated in their behalf. See the config file formats for IAX, SIP,
+zapata.conf, etc. They all help describe a device, and they all
+specify a context to activate when somebody picks up a phone, or a
+call comes in from the phone company, or a voip phone, etc.
+
+Contexts
+--------
+
+Contexts are a grouping of extensions.
+
+Contexts can also include other contexts. Think of it as a sort of
+merge operation at runtime, whereby the included context's extensions
+are added to the contexts making the inclusion.
+
+Extensions and priorities
+-------------------------
+
+A Context contains zero or more Extensions. There are several
+predefined extensions. The "s" extension is the "start" extension, and
+when a device activates a context the "s" extension is the one that is
+going to be run. Other extensions are the timeout "t" extension, the
+invalid response, or "i" extension, and there's a "fax" extension. For
+instance, a normal call will activate the "s" extension, but an
+incoming FAX call will come into the "fax" extension, if it
+exists. (BTW, asterisk can tell it's a fax call by the little "beep"
+that the calling fax machine emits every so many seconds.).
+
+Extensions contain several priorities, which are individual
+instructions to perform. Some are as simple as setting a variable to a
+value. Others are as complex as initiating the Voicemail application,
+for instance. Priorities are executed in order.
+
+When the 's" extension completes, asterisk waits until the timeout for
+a response. If the response matches an extension's pattern in the
+context, then control is transferred to that extension. Usually the
+responses are tones emitted when a user presses a button on their
+phone. For instance, a context associated with a desk phone might not
+have any "s" extension. It just plays a dialtone until someone starts
+hitting numbers on the keypad, gather the number, find a matching
+extension, and begin executing it. That extension might Dial out over
+a connected telephone line for the user, and then connect the two
+lines together.
+
+The extensions can also contain "goto" or "jump" commands to skip to
+extensions in other contexts. Conditionals provide the ability to
+react to different stimiuli, and there you have it.
+
+Macros
+------
+
+Think of a macro as a combination of a context with one nameless
+extension, and a subroutine. It has arguments like a subroutine
+might. A macro call can be made within an extension, and the
+individual statements there are executed until it ends. At this point,
+execution returns to the next statement after the macro call. Macros
+can call other macros. And they work just like function calls.
+
+Applications
+------------
+
+Application calls, like "Dial()", or "Hangup()", or "Answer()", are
+available for users to use to accomplish the work of the
+dialplan. There are over 145 of them at the moment this was written,
+and the list grows as new needs and wants are uncovered. Some
+applications do fairly simple things, some provide amazingly complex
+services.
+
+Hopefully, the above objects will allow you do anything you need to in
+the Asterisk environment!
+
+
+*******************
+* Getting Started *
+*******************
+
+The AEL2 parser (pbx_ael2.so) is completely separate from the module
+that parses extensions.conf (pbx_config.so). To use AEL2, the only
+thing that has to be done is the module pbx_ael2.so must be loaded by
+Asterisk. This will be done automatically if using 'autoload=yes' in
+/etc/asterisk/modules.conf. When the module is loaded, it will look
+for 'extensions.ael2' in /etc/asterisk/. extensions.conf and
+extensions.ael and extensions.ael2 can be used in conjunction with
+each other if that is what is desired. Some users may want to keep
+extensions.conf for the features that are configured in the 'general'
+section of extensions.conf.
+
+------------------------------
+- Reloading extensions.ael2 -
+------------------------------
+
+To reload extensions.ael2, the following command can be issued at the
+CLI:
+
+ *CLI> ael2 reload
+
+
+
+*************
+* Debugging *
+*************
+
+Right at this moment, the following commands are available, but do
+nothing:
+
+Enable AEL2 contexts debug
+ *CLI> ael2 debug contexts
+
+Enable AEL2 macros debug
+ *CLI> ael2 debug macros
+
+Enable AEL2 read debug
+ *CLI> ael2 debug read
+
+Enable AEL2 tokens debug
+ *CLI> ael2 debug tokens
+
+Disable AEL2 debug messages
+ *CLI> ael2 no debug
+
+If things are going wrong in your dialplan, you can use the following
+facilities to debug your file:
+
+1. The messages log in /var/log/asterisk. (from the checks done at load time).
+2. the "show dialplan" command in asterisk
+3. the standalone executable, "aelparse" built in the utils/ dir in the source.
+
+You can also use the "aelparse" program to check your extensions.ael2
+file before feeding it to asterisk. Wouldn't it be nice to eliminate
+most errors before giving the file to asterisk?
+
+
+
+******************************
+* General Notes about Syntax *
+******************************
+
+Note that the syntax and style are a little more free-form. The
+opening '{' (curly-braces) do not have to be on the same line as the
+keyword that precedes them. Statements can be split across lines, as
+long as tokens are not broken by doing so. More than one statement can
+be included on a single line. Whatever you think is best!
+
+You can just as easily say,
+
+if(${x}=1) { NoOp(hello!); goto s|3; } else { NoOp(Goodbye!); goto s|12; }
+
+as you can say:
+
+if(${x}=1)
+{
+ NoOp(hello!);
+ goto s|3;
+}
+else
+{
+ NoOp(Goodbye!);
+ goto s|12;
+}
+
+or:
+
+if(${x}=1) {
+ NoOp(hello!);
+ goto s|3;
+} else {
+ NoOp(Goodbye!);
+ goto s|12;
+}
+
+or:
+
+if (${x}=1) {
+ NoOp(hello!); goto s|3;
+} else {
+ NoOp(Goodbye!); goto s|12;
+}
+
+or even:
+
+if
+(${x}=1)
+{
+NoOp(hello!);
+goto s|3;
+}
+else
+{
+NoOp(Goodbye!);
+goto s|12;
+}
+
+
+************
+* Keywords *
+************
+
+The AEL keywords are case-sensitive. If an application name and a
+keyword overlap, there is probably good reason, and you should
+consider replacing the application call with an AEL2 statement. If you
+do not wish to do so, you can still use the application, by using a
+capitalized letter somewhere in its name. In the Asterisk extension
+language, application names are NOT case-sensitive.
+
+The following are keywords in the AEL2 language:
+
+ * abstract
+ * context
+ * macro
+ * globals
+ * ignorepat
+ * switch
+ * if
+ * ifTime
+ * else
+ * random
+ * goto
+ * jump
+ * return
+ * break
+ * continue
+ * regexten
+ * hint
+ * for
+ * while
+ * case
+ * pattern
+ * default NOTE: the "default" keyword can be used as a context name,
+ for those who would like to do so.
+ * catch
+ * switches
+ * eswitches
+ * includes
+
+
+
+*****************
+* Applications *
+*****************
+
+The file /var/lib/asterisk/applist contains entries for over 140
+applications, including arguments, the names of variables the
+application can or will set, the options, and the list of arguments,
+optional and required. If you use an application that is not in the
+list, you can simply add one, following the syntax of other entries.
+
+Don't fall in love with the specs in the applist file. The format of
+the file, the entries themselves will change in time.
+
+
+
+
+Procedural Interface and Internals
+==================================
+
+AEL2 first parses the .ael2 file into a memory structure representing the file.
+The entire file is represented by a tree of "pval" structures linked together.
+
+This tree is then handed to the semantic check routine.
+
+Then the tree is handed to the compiler.
+
+After that, it is freed from memory.
+
+A program could be written that could build a tree of pval structures, and
+a pretty printing function is provided, that would dump the data to a file,
+or the tree could be handed to the compiler to merge the data into the
+asterisk dialplan. The modularity of the design offers several opportunities
+for developers to simplify apps to generate dialplan data.
+
+
+
+=========================
+ AEL2 BNF
+=========================
+
+
+
+(hopefully, something close to bnf).
+
+First, some basic objects
+
+------------------------
+
+<word> a lexical token consisting of characters matching this pattern: [-a-zA-Z0-9"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9"_/.!\*\+\<\>\{\}$#\[\]]*
+
+<word3-list> a concatenation of up to 3 <word>s.
+
+<collected-word> all characters encountered until the character that follows the <collected-word> in the grammar.
+
+-------------------------
+
+<file> :== <objects>
+
+<objects> :== <object>
+ | <objects> <object>
+
+
+<object> :== <context>
+ | <macro>
+ | <globals>
+ | ';'
+
+
+<context> :== 'context' <word> '{' <elements> '}'
+ | 'context' <word> '{' '}'
+ | 'context' 'default' '{' <elements> '}'
+ | 'context' 'default' '{' '}'
+ | 'abstract' 'context' <word> '{' <elements> '}'
+ | 'abstract' 'context' <word> '{' '}'
+ | 'abstract' 'context' 'default' '{' <elements> '}'
+ | 'abstract' 'context' 'default' '{' '}'
+
+
+<macro> :== 'macro' <word> '(' <arglist> ')' '{' <macro_statements> '}'
+ | 'macro' <word> '(' <arglist> ')' '{' '}'
+ | 'macro' <word> '(' ')' '{' <macro_statements> '}'
+ | 'macro' <word> '(' ')' '{' '}'
+
+
+<globals> :== 'globals' '{' <global_statements> '}'
+ | 'globals' '{' '}'
+
+
+<global_statements> :== <global_statement>
+ | <global_statements> <global_statement>
+
+
+<global_statement> :== <word> '=' <collected-word> ';'
+
+
+<arglist> :== <word>
+ | <arglist> ',' <word>
+
+
+<elements> :== <element>
+ | <elements> <element>
+
+
+<element> :== <extension>
+ | <includes>
+ | <switches>
+ | <eswitches>
+ | <ignorepat>
+ | <word> '=' <collected-word> ';'
+ | ';'
+
+
+<ignorepat> :== 'ignorepat' '=>' <word> ';'
+
+
+<extension> :== <word> '=>' <statement>
+ | 'regexten' <word> '=>' <statement>
+ | 'hint' '(' <word3-list> ')' <word> '=>' <statement>
+ | 'regexten' 'hint' '(' <word3-list> ')' <word> '=>' <statement>
+
+
+<statements> :== <statement>
[... 17399 lines stripped ...]
More information about the asterisk-commits
mailing list