[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