Index: channels/chan_h323.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_h323.c,v
retrieving revision 1.35
diff -u -r1.35 chan_h323.c
--- channels/chan_h323.c	15 Mar 2004 09:14:16 -0000	1.35
+++ channels/chan_h323.c	17 Mar 2004 09:41:25 -0000
@@ -191,9 +191,32 @@
 	ast_mutex_unlock(&iflock);
 }
 
+static void alias_add_e164(struct oh323_alias *alias, char *val)
+{
+	struct e164_number *tmp = alias->e164;
+
+	/* Create a new e164 number structure and chain it */
+	alias->e164 = (struct e164_number *)calloc(1, sizeof(struct e164_number));
+	alias->e164->next = tmp;
+
+	strncpy(alias->e164->number, val, E164_MAX_LENGTH-1);
+}
+
+static void alias_add_prefix(struct oh323_alias *alias, char *val)
+{
+	struct e164_number *tmp = alias->prefix;
+
+	/* Create a new e164 number structure and chain it */
+	alias->prefix = (struct e164_number *)calloc(1, sizeof(struct e164_number));
+	alias->prefix->next = tmp;
+
+	strncpy(alias->prefix->number, val, E164_MAX_LENGTH-1);
+}
+
 static struct oh323_alias *build_alias(char *name, struct ast_variable *v)
 {
 	struct oh323_alias *alias;
+	char *p, *n;
 
 	alias = (struct oh323_alias *)malloc(sizeof(struct oh323_alias));
 
@@ -203,9 +226,19 @@
 
 		while (v) {
 			if (!strcasecmp(v->name, "e164")) {
-				strncpy(alias->e164,  v->value, sizeof(alias->e164)-1);
+				p = v->value;
+				n = strsep(&p, ",");
+				while(n) {
+					alias_add_e164(alias, n);
+					n = strsep(&p, ",");
+				}
 			} else if (!strcasecmp(v->name, "prefix")) {
-				strncpy(alias->prefix,  v->value, sizeof(alias->prefix)-1);
+				p = v->value;
+				n = strsep(&p, ",");
+				while(n) {
+					alias_add_prefix(alias, n);
+					n = strsep(&p, ",");
+				}
 			} else if (!strcasecmp(v->name, "context")) {
 				strncpy(alias->context,  v->value, sizeof(alias->context)-1);
 			} else if (!strcasecmp(v->name, "secret")) {
@@ -218,6 +251,7 @@
 			v = v->next;
 		}
 	}
+
 	return alias;
 }
 
@@ -748,22 +782,21 @@
 
 static struct oh323_pvt *find_call(int call_reference)
 {  
-        struct oh323_pvt *p;
+	struct oh323_pvt *p;
 
-		ast_mutex_lock(&iflock);
-        p = iflist; 
+	ast_mutex_lock(&iflock);
+	p = iflist; 
 
-        while(p) {
-                if (p->cd.call_reference == call_reference) {
-                        /* Found the call */						
-						ast_mutex_unlock(&iflock);
-						return p;
-                }
-                p = p->next; 
-        }
-        ast_mutex_unlock(&iflock);
-		return NULL;
-        
+	while(p) {
+		if (p->cd.call_reference == call_reference) {
+			/* Found the call */						
+			ast_mutex_unlock(&iflock);
+			return p;
+		}
+		p = p->next; 
+	}
+	ast_mutex_unlock(&iflock);
+	return NULL;
 }
 
 static struct ast_channel *oh323_request(char *type, int format, void *data)
@@ -841,6 +874,7 @@
 {
 	struct oh323_alias *a;
 
+	ast_mutex_lock(&aliasl.lock);
 	a = aliasl.aliases;
 
 	while(a) {
@@ -850,6 +884,66 @@
 		}
 		a = a->next;
 	}
+
+	ast_mutex_unlock(&aliasl.lock);
+	return a;
+}
+
+struct oh323_alias *find_e164(const char *source_aliases)
+{
+	struct oh323_alias *a;
+	struct e164_number *num;
+	int found = 0;
+
+	ast_mutex_lock(&aliasl.lock);
+	a = aliasl.aliases;
+
+	while(a && !found) {
+        	if(a->e164) {
+			num = a->e164;
+			while(num) {
+				if(!strncmp(num->number, source_aliases, E164_MAX_LENGTH)) {
+					found = 1;
+					break;
+				}
+			num = num->next;
+		}
+	}
+	if(!found)
+		a = a->next;
+	}
+	ast_mutex_unlock(&aliasl.lock);
+
+	return a;
+}
+
+struct oh323_alias *find_prefix(const char *source_aliases)
+{
+	struct oh323_alias *a;
+	struct e164_number *num;
+	int found = 0;
+
+	ast_mutex_lock(&aliasl.lock);
+
+	a = aliasl.aliases;
+
+	while(a && !found) {
+	if(a->prefix) {
+		num = a->prefix;
+		while(num) {
+			if(strlen(source_aliases) >= strlen(num->number) &&
+			   !strncmp(num->number, source_aliases, strlen(num->number))) {
+				found = 1;
+				break;
+			}
+			num = num->next;
+		}
+	}
+	if(!found)
+		a = a->next;
+	}
+	ast_mutex_unlock(&aliasl.lock);
+
 	return a;
 }
 
@@ -907,7 +1001,7 @@
 
 	ast_log(LOG_DEBUG, "Recieved Digit: %c\n", digit);
 	p = find_call(call_reference);
-	
+
 	if (!p) {
 		ast_log(LOG_ERROR, "Private structure not found in send_digit.\n");
 		return -1;
@@ -1000,8 +1094,15 @@
 	if ((!strcasecmp(cd.sourceIp, gatekeeper)) && (gkroute == -1) && (usingGk == 1)) {
 		
 		if (strlen(cd.call_dest_e164)) {
+			alias = find_e164(cd.call_dest_e164);
+			if(!alias)
+				alias = find_prefix(cd.call_dest_e164);
+            
+			if(!alias)
+				ast_log(LOG_WARNING, "Call for '%s' could not be routed to a context, sending to default.\n", cd.call_dest_e164);
+
 			strncpy(p->exten, cd.call_dest_e164, sizeof(p->exten)-1);
-			strncpy(p->context, default_context, sizeof(p->context)-1); 
+			strncpy(p->context, (alias?alias->context:default_context), sizeof(p->context)-1); 
 		} else {
 			alias = find_alias(cd.call_dest_alias);
 		
@@ -1372,6 +1473,48 @@
 	return RESULT_SUCCESS;
 }
 
+static int h323_show_aliases(int fd, int argc, char *argv[])
+{
+	struct oh323_alias *alias;
+	struct e164_number *num;
+
+	if (argc != 3) {
+		return RESULT_SHOWUSAGE;
+	}
+	ast_cli(fd, "H323 Configured Aliases/E164/Prefixes:\n");
+
+	ast_mutex_lock(&aliasl.lock);
+	alias = aliasl.aliases;
+
+	if(!alias) {
+		ast_cli(fd, "  Nothing configured!\n");
+		ast_mutex_unlock(&aliasl.lock);
+		return RESULT_SUCCESS;
+	}
+
+	ast_cli(fd, "%-20s %-5s %-20s %-20s\n", "Alias", "Type", "E164", "Context");
+
+	while(alias) {
+		ast_cli(fd, "%-20s %-5s %-20s %-20s\n", alias->name, "id", "", alias->context);
+
+		num = alias->e164;
+		while(num) {
+			ast_cli(fd, "%-20s %-5s %-20s %-20s\n", alias->name, "e164", num->number, alias->context);
+			num = num->next;
+		}
+
+		num = alias->prefix;
+		while(num) {
+			ast_cli(fd, "%-20s %-5s %-20s %-20s\n", alias->name, "pfx", num->number, alias->context);
+			num = num->next;
+		}
+
+		alias = alias->next;
+	}
+
+	ast_mutex_unlock(&aliasl.lock);
+	return RESULT_SUCCESS;
+}
 
 static char trace_usage[] = 
 "Usage: h.323 trace <level num>\n"
@@ -1405,6 +1548,10 @@
 "Usage: h.323 show tokens\n"
 "       Print out all active call tokens\n";
 
+static char show_aliases_usage[] =
+"Usage: h.323 show aliases\n"
+"       Print out all configured aliases\n";
+
 static struct ast_cli_entry  cli_trace =
 	{ { "h.323", "trace", NULL }, h323_do_trace, "Enable H.323 Stack Tracing", trace_usage };
 static struct ast_cli_entry  cli_no_trace =
@@ -1421,7 +1568,8 @@
 	{ { "h.323", "hangup", NULL }, h323_ep_hangup, "Manually try to hang up a call", show_hangup_usage };
 static struct ast_cli_entry  cli_show_tokens =
 	{ { "h.323", "show", "tokens", NULL }, h323_tokens_show, "Manually try to hang up a call", show_tokens_usage };
-
+static struct ast_cli_entry  cli_show_aliases =
+    { { "h.323", "show", "aliases", NULL }, h323_show_aliases, "Show configured aliases", show_aliases_usage };
 
 
 int reload_config(void)
@@ -1612,12 +1760,26 @@
 void delete_aliases(void)
 {
 	struct oh323_alias *alias, *aliaslast;
-		
+	struct e164_number *num, *numlast;
+    
 	/* Delete all users */
 	ast_mutex_lock(&aliasl.lock);
 	for (alias=aliasl.aliases;alias;) {
 		aliaslast = alias;
 		alias=alias->next;
+        
+		for(num=aliaslast->e164;num;) {
+			numlast = num;
+			num = num->next;
+			free(num);
+		}
+
+		for(num=aliaslast->prefix;num;) {
+			numlast = num;
+			num = num->next;
+			free(num);
+		}
+
 		free(aliaslast);
 	}
 	aliasl.aliases=NULL;
@@ -1775,7 +1937,8 @@
 		ast_cli_register(&cli_gk_cycle);
 		ast_cli_register(&cli_hangup_call);
 		ast_cli_register(&cli_show_tokens);
-
+		ast_cli_register(&cli_show_aliases);
+        
 		oh323_rtp.type = type;
 		ast_rtp_proto_register(&oh323_rtp);
 
@@ -1907,7 +2070,3 @@
 {
 	return ASTERISK_GPL_KEY;
 }
-
-
-
-
Index: channels/h323/chan_h323.h
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/h323/chan_h323.h,v
retrieving revision 1.19
diff -u -r1.19 chan_h323.h
--- channels/h323/chan_h323.h	4 Mar 2004 01:57:32 -0000	1.19
+++ channels/h323/chan_h323.h	17 Mar 2004 09:41:25 -0000
@@ -70,15 +70,22 @@
 	struct oh323_peer *next;
 };
 
+/* a place to store a list of e164 numbers */
+#define E164_MAX_LENGTH 40
+struct e164_number {
+	char number[E164_MAX_LENGTH]; /* the E.164 number */
+	struct e164_number *next;
+};
+
 /* structure to hold the H.323 aliases which get registered to 
    the H.323 endpoint and gatekeeper */
 struct oh323_alias {
 	char name[80];
-	char e164[20];				/* tells a GK to route this E.164 to this alias */
-	char prefix[500];			/* tells a GK this alias supports these prefixes */
+	struct e164_number *e164;		/* exact e164 numbers list */
+	struct e164_number *prefix;		/* e164 number prefixes list */
 	char secret[20];			/* the H.235 password to send to the GK for authentication */
 	char context[80];
-	struct oh323_alias *next;	
+	struct oh323_alias *next;
 };
 
 /** call_option struct is filled from the 
Index: channels/h323/ast_h323.cpp
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/h323/ast_h323.cpp,v
retrieving revision 1.35
diff -u -r1.35 ast_h323.cpp
--- channels/h323/ast_h323.cpp	4 Mar 2004 06:11:23 -0000	1.35
+++ channels/h323/ast_h323.cpp	17 Mar 2004 09:41:25 -0000
@@ -886,10 +886,7 @@
    
 int h323_set_alias(struct oh323_alias *alias)
 {
-	char *p;
-	char *num;
 	PString h323id(alias->name);
-	PString e164(alias->e164);
 	
 	if (!h323_end_point_exist()) {
 		cout << "ERROR: [h323_set_alias] No Endpoint, this is bad!" << endl;
@@ -900,18 +897,26 @@
 	endPoint->AddAliasName(h323id);	
 	endPoint->RemoveAliasName(localProcess->GetUserName());
 
-	if (!e164.IsEmpty()) {
-		cout << "  == Adding E.164 \"" << e164 << "\" to endpoint" << endl;
-		endPoint->AddAliasName(e164);
-	}
-	if (strlen(alias->prefix)) {
-		p = alias->prefix;
-		num = strsep(&p, ",");
+	if(alias->e164) {
+		struct e164_number *num = alias->e164;
 		while(num) {
-	        cout << "  == Adding Prefix \"" << num << "\" to endpoint" << endl;
-			endPoint->SupportedPrefixes += PString(num);
-			endPoint->SetGateway();
-	        num = strsep(&p, ",");		
+			if(strlen(num->number)) {
+				cout << "  == Adding E.164 \"" << num->number << "\" to endpoint" << endl;
+				endPoint->AddAliasName(num->number);
+			}
+			num = num->next;
+		}
+	}
+
+	if(alias->prefix) {
+		struct e164_number *num = alias->prefix;
+		while(num) {
+			if(strlen(num->number)) {
+				cout << "  == Adding Prefix \"" << num->number << "\" to endpoint" << endl;
+				endPoint->SupportedPrefixes += PString(num->number);
+				endPoint->SetGateway();
+			}
+			num = num->next;
 		}
 	}
 
Index: channels/h323/h323.conf.sample
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/h323/h323.conf.sample,v
retrieving revision 1.8
diff -u -r1.8 h323.conf.sample
--- channels/h323/h323.conf.sample	24 Dec 2003 22:36:57 -0000	1.8
+++ channels/h323/h323.conf.sample	17 Mar 2004 09:41:25 -0000
@@ -49,14 +49,17 @@
 ; Default context gets used in siutations where you are using 
 ; the GK routed model or no type=user was found. This gives you 
 ; the ability to either play an invalid message or to simply not 
-; use user authentication at all.
+; use user authentication at all. Also, if a call is accepted for
+; a prefix or e164 number that cannot be matched to any of the
+; following sections, it will be sent here.
 ;
 ;context=default
 ;
 ; H.323 Alias definitions
 ;
 ; Type 'h323' will register aliases to the endpoint
-; and Gatekeeper, if there is one.
+; and Gatekeeper, if there is one. It will also offer
+; itself as a gateway for prefixes.
 ;
 ; Example: if someone calls time@your.asterisk.box.com
 ; Asterisk will send the call to the extension 'time' 
@@ -69,6 +72,11 @@
 ; Keyword's 'prefix' and 'e164' are only make sense when
 ; used with a gatekeeper. You can specify either a prefix 
 ; or E.164 this endpoint is responsible for terminating.
+; In the case of a prefix or e164, the context specified
+; in that section will receive the called extension. E164
+; numbers are matched before prefixes, so you can have
+; a prefix covering a general case, and a specific E164 in
+; another context.
 ; 
 ; Example: The H.323 alias 'det-gw' will tell the gatekeeper
 ; to route any call with the prefix 1248 to this alias. Keyword
