diff --git a/channels/chan_h323.c b/channels/chan_h323.c index afecf0f3db9052e1bf489c0caadd9e74e4dfe596..4c3a128615739a968c36f43fc425737b01c53dba 100755 --- a/channels/chan_h323.c +++ b/channels/chan_h323.c @@ -191,9 +191,32 @@ static void oh323_destroy(struct oh323_pvt *p) 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 @@ static struct oh323_alias *build_alias(char *name, struct ast_variable *v) 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 @@ static struct oh323_alias *build_alias(char *name, struct ast_variable *v) v = v->next; } } + return alias; } @@ -748,22 +782,21 @@ static struct oh323_pvt *oh323_alloc(int callid) 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 *find_alias(const char *source_aliases) { struct oh323_alias *a; + ast_mutex_lock(&aliasl.lock); a = aliasl.aliases; while(a) { @@ -850,6 +884,66 @@ struct oh323_alias *find_alias(const char *source_aliases) } 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 @@ int send_digit(unsigned call_reference, char digit) 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 @@ int setup_incoming_call(call_details_t cd) 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 @@ static int h323_tokens_show(int fd, int argc, char *argv[]) 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 @@ static char show_tokens_usage[] = "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 @@ static struct ast_cli_entry cli_hangup_call = { { "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_users(void) 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 @@ int load_module() 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 @@ char *key() { return ASTERISK_GPL_KEY; } - - - - diff --git a/channels/h323/ast_h323.cpp b/channels/h323/ast_h323.cpp index 44e8163503dc6cf25140929ff7db4c1c8254599a..e55b93825f5e2432256c3e57a1b0165813a3867c 100755 --- a/channels/h323/ast_h323.cpp +++ b/channels/h323/ast_h323.cpp @@ -886,10 +886,7 @@ int h323_start_listener(int listenPort, struct sockaddr_in bindaddr) 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 @@ int h323_set_alias(struct oh323_alias *alias) endPoint->AddAliasName(h323id); endPoint->RemoveAliasName(localProcess->GetUserName()); - if (!e164.IsEmpty()) { - cout << " == Adding E.164 \"" << e164 << "\" to endpoint" << endl; - endPoint->AddAliasName(e164); + if(alias->e164) { + struct e164_number *num = alias->e164; + while(num) { + if(strlen(num->number)) { + cout << " == Adding E.164 \"" << num->number << "\" to endpoint" << endl; + endPoint->AddAliasName(num->number); + } + num = num->next; + } } - if (strlen(alias->prefix)) { - p = alias->prefix; - num = strsep(&p, ","); + + if(alias->prefix) { + struct e164_number *num = alias->prefix; while(num) { - cout << " == Adding Prefix \"" << num << "\" to endpoint" << endl; - endPoint->SupportedPrefixes += PString(num); - endPoint->SetGateway(); - num = strsep(&p, ","); + if(strlen(num->number)) { + cout << " == Adding Prefix \"" << num->number << "\" to endpoint" << endl; + endPoint->SupportedPrefixes += PString(num->number); + endPoint->SetGateway(); + } + num = num->next; } } diff --git a/channels/h323/h323.conf.sample b/channels/h323/h323.conf.sample index 811647a08fa2e0f347f780e530c4967f8d04b38f..8d1e6559ba6cbdcbcd1f07387fe5b2634717b77e 100755 --- a/channels/h323/h323.conf.sample +++ b/channels/h323/h323.conf.sample @@ -49,14 +49,17 @@ allow=gsm ; Always allow GSM, it's cool :) ; 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 @@ allow=gsm ; Always allow GSM, it's cool :) ; 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