mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-25 15:08:53 +00:00
Properly deal with E.164 and Prefix routing
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2458 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -191,9 +191,32 @@ static void oh323_destroy(struct oh323_pvt *p)
|
|||||||
ast_mutex_unlock(&iflock);
|
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)
|
static struct oh323_alias *build_alias(char *name, struct ast_variable *v)
|
||||||
{
|
{
|
||||||
struct oh323_alias *alias;
|
struct oh323_alias *alias;
|
||||||
|
char *p, *n;
|
||||||
|
|
||||||
alias = (struct oh323_alias *)malloc(sizeof(struct oh323_alias));
|
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) {
|
while (v) {
|
||||||
if (!strcasecmp(v->name, "e164")) {
|
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")) {
|
} 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")) {
|
} else if (!strcasecmp(v->name, "context")) {
|
||||||
strncpy(alias->context, v->value, sizeof(alias->context)-1);
|
strncpy(alias->context, v->value, sizeof(alias->context)-1);
|
||||||
} else if (!strcasecmp(v->name, "secret")) {
|
} 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;
|
v = v->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return alias;
|
return alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,7 +797,6 @@ static struct oh323_pvt *find_call(int call_reference)
|
|||||||
}
|
}
|
||||||
ast_mutex_unlock(&iflock);
|
ast_mutex_unlock(&iflock);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ast_channel *oh323_request(char *type, int format, void *data)
|
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;
|
struct oh323_alias *a;
|
||||||
|
|
||||||
|
ast_mutex_lock(&aliasl.lock);
|
||||||
a = aliasl.aliases;
|
a = aliasl.aliases;
|
||||||
|
|
||||||
while(a) {
|
while(a) {
|
||||||
@@ -850,6 +884,66 @@ struct oh323_alias *find_alias(const char *source_aliases)
|
|||||||
}
|
}
|
||||||
a = a->next;
|
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;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1000,8 +1094,15 @@ int setup_incoming_call(call_details_t cd)
|
|||||||
if ((!strcasecmp(cd.sourceIp, gatekeeper)) && (gkroute == -1) && (usingGk == 1)) {
|
if ((!strcasecmp(cd.sourceIp, gatekeeper)) && (gkroute == -1) && (usingGk == 1)) {
|
||||||
|
|
||||||
if (strlen(cd.call_dest_e164)) {
|
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->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 {
|
} else {
|
||||||
alias = find_alias(cd.call_dest_alias);
|
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;
|
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[] =
|
static char trace_usage[] =
|
||||||
"Usage: h.323 trace <level num>\n"
|
"Usage: h.323 trace <level num>\n"
|
||||||
@@ -1405,6 +1548,10 @@ static char show_tokens_usage[] =
|
|||||||
"Usage: h.323 show tokens\n"
|
"Usage: h.323 show tokens\n"
|
||||||
" Print out all active call 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 =
|
static struct ast_cli_entry cli_trace =
|
||||||
{ { "h.323", "trace", NULL }, h323_do_trace, "Enable H.323 Stack Tracing", trace_usage };
|
{ { "h.323", "trace", NULL }, h323_do_trace, "Enable H.323 Stack Tracing", trace_usage };
|
||||||
static struct ast_cli_entry cli_no_trace =
|
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 };
|
{ { "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 =
|
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 };
|
{ { "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)
|
int reload_config(void)
|
||||||
@@ -1612,12 +1760,26 @@ void delete_users(void)
|
|||||||
void delete_aliases(void)
|
void delete_aliases(void)
|
||||||
{
|
{
|
||||||
struct oh323_alias *alias, *aliaslast;
|
struct oh323_alias *alias, *aliaslast;
|
||||||
|
struct e164_number *num, *numlast;
|
||||||
|
|
||||||
/* Delete all users */
|
/* Delete all users */
|
||||||
ast_mutex_lock(&aliasl.lock);
|
ast_mutex_lock(&aliasl.lock);
|
||||||
for (alias=aliasl.aliases;alias;) {
|
for (alias=aliasl.aliases;alias;) {
|
||||||
aliaslast = alias;
|
aliaslast = alias;
|
||||||
alias=alias->next;
|
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);
|
free(aliaslast);
|
||||||
}
|
}
|
||||||
aliasl.aliases=NULL;
|
aliasl.aliases=NULL;
|
||||||
@@ -1775,6 +1937,7 @@ int load_module()
|
|||||||
ast_cli_register(&cli_gk_cycle);
|
ast_cli_register(&cli_gk_cycle);
|
||||||
ast_cli_register(&cli_hangup_call);
|
ast_cli_register(&cli_hangup_call);
|
||||||
ast_cli_register(&cli_show_tokens);
|
ast_cli_register(&cli_show_tokens);
|
||||||
|
ast_cli_register(&cli_show_aliases);
|
||||||
|
|
||||||
oh323_rtp.type = type;
|
oh323_rtp.type = type;
|
||||||
ast_rtp_proto_register(&oh323_rtp);
|
ast_rtp_proto_register(&oh323_rtp);
|
||||||
@@ -1907,7 +2070,3 @@ char *key()
|
|||||||
{
|
{
|
||||||
return ASTERISK_GPL_KEY;
|
return ASTERISK_GPL_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -886,10 +886,7 @@ int h323_start_listener(int listenPort, struct sockaddr_in bindaddr)
|
|||||||
|
|
||||||
int h323_set_alias(struct oh323_alias *alias)
|
int h323_set_alias(struct oh323_alias *alias)
|
||||||
{
|
{
|
||||||
char *p;
|
|
||||||
char *num;
|
|
||||||
PString h323id(alias->name);
|
PString h323id(alias->name);
|
||||||
PString e164(alias->e164);
|
|
||||||
|
|
||||||
if (!h323_end_point_exist()) {
|
if (!h323_end_point_exist()) {
|
||||||
cout << "ERROR: [h323_set_alias] No Endpoint, this is bad!" << endl;
|
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->AddAliasName(h323id);
|
||||||
endPoint->RemoveAliasName(localProcess->GetUserName());
|
endPoint->RemoveAliasName(localProcess->GetUserName());
|
||||||
|
|
||||||
if (!e164.IsEmpty()) {
|
if(alias->e164) {
|
||||||
cout << " == Adding E.164 \"" << e164 << "\" to endpoint" << endl;
|
struct e164_number *num = alias->e164;
|
||||||
endPoint->AddAliasName(e164);
|
|
||||||
}
|
|
||||||
if (strlen(alias->prefix)) {
|
|
||||||
p = alias->prefix;
|
|
||||||
num = strsep(&p, ",");
|
|
||||||
while(num) {
|
while(num) {
|
||||||
cout << " == Adding Prefix \"" << num << "\" to endpoint" << endl;
|
if(strlen(num->number)) {
|
||||||
endPoint->SupportedPrefixes += PString(num);
|
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();
|
endPoint->SetGateway();
|
||||||
num = strsep(&p, ",");
|
}
|
||||||
|
num = num->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -49,14 +49,17 @@ allow=gsm ; Always allow GSM, it's cool :)
|
|||||||
; Default context gets used in siutations where you are using
|
; Default context gets used in siutations where you are using
|
||||||
; the GK routed model or no type=user was found. This gives you
|
; 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
|
; 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
|
;context=default
|
||||||
;
|
;
|
||||||
; H.323 Alias definitions
|
; H.323 Alias definitions
|
||||||
;
|
;
|
||||||
; Type 'h323' will register aliases to the endpoint
|
; 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
|
; Example: if someone calls time@your.asterisk.box.com
|
||||||
; Asterisk will send the call to the extension 'time'
|
; 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
|
; Keyword's 'prefix' and 'e164' are only make sense when
|
||||||
; used with a gatekeeper. You can specify either a prefix
|
; used with a gatekeeper. You can specify either a prefix
|
||||||
; or E.164 this endpoint is responsible for terminating.
|
; 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
|
; Example: The H.323 alias 'det-gw' will tell the gatekeeper
|
||||||
; to route any call with the prefix 1248 to this alias. Keyword
|
; to route any call with the prefix 1248 to this alias. Keyword
|
||||||
|
Reference in New Issue
Block a user