aboutsummaryrefslogtreecommitdiffstats
path: root/pbx
diff options
context:
space:
mode:
Diffstat (limited to 'pbx')
-rwxr-xr-xpbx/pbx_dundi.c210
1 files changed, 150 insertions, 60 deletions
diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c
index c7d52979c..73e5346d0 100755
--- a/pbx/pbx_dundi.c
+++ b/pbx/pbx_dundi.c
@@ -88,7 +88,9 @@ static char *descrip =
"${DUNDTECH} and ${DUNDDEST} will contain the technology and destination\n"
"of the appropriate technology and destination to access the number. If no\n"
"answer was found, and the priority n + 101 exists, execution will continue\n"
-"at that location.\n";
+"at that location. Note that this will only occur if the global priority\n"
+"jumping option is enabled in extensions.conf. If the 'b' option is specified,\n"
+"the internal DUNDi cache will by bypassed.\n";
#define DUNDI_MODEL_INBOUND (1 << 0)
#define DUNDI_MODEL_OUTBOUND (1 << 1)
@@ -3850,58 +3852,142 @@ int dundi_query_eid(struct dundi_entity_info *dei, const char *dcontext, dundi_e
static int dundi_lookup_exec(struct ast_channel *chan, void *data)
{
- char *tmp;
- char *context = NULL;
+ char *num;
+ char *context;
char *opts;
- int res = 0;
- int results = 0;
+ int results;
int x;
int bypass = 0;
struct localuser *u;
struct dundi_result dr[MAX_RESULTS];
+ static int dep_warning = 0;
+
+ LOCAL_USER_ADD(u);
- if (!data || !strlen(data)) {
+ if (!dep_warning) {
+ ast_log(LOG_WARNING, "This application has been deprecated in favor of the DUNDILOOKUP dialplan function.\n");
+ dep_warning = 1;
+ }
+
+ if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "DUNDiLookup requires an argument (number)\n");
+ LOCAL_USER_REMOVE(u);
return 0;
}
- LOCAL_USER_ADD(u);
- tmp = ast_strdupa(data);
- if (tmp) {
- context = strchr(tmp, '|');
- if (context) {
- *context = '\0';
- context++;
- opts = strchr(context, '|');
- if (opts) {
- *opts = '\0';
- opts++;
- }
- } else
- opts = NULL;
- if (!context || !strlen(context))
- context = "e164";
- if (!opts)
- opts = "";
-
+
+ num = ast_strdupa(data);
+ if (!num) {
+ ast_log(LOG_ERROR, "Out of memory!\n");
+ LOCAL_USER_REMOVE(u);
+ return 0;
}
- results = dundi_lookup(dr, MAX_RESULTS, NULL, context, tmp, bypass);
+
+ context = strchr(num, '|');
+ if (context) {
+ *context = '\0';
+ context++;
+ opts = strchr(context, '|');
+ if (opts) {
+ *opts = '\0';
+ opts++;
+ if (strchr(opts, 'b'))
+ bypass = 1;
+ }
+ }
+
+ if (!context || ast_strlen_zero(context))
+ context = "e164";
+
+ results = dundi_lookup(dr, MAX_RESULTS, NULL, context, num, bypass);
if (results > 0) {
- sort_results(dr, results);
- for (x=0;x<results;x++) {
+ sort_results(dr, results);
+ for (x = 0; x < results; x++) {
if (ast_test_flag(dr + x, DUNDI_FLAG_EXISTS)) {
pbx_builtin_setvar_helper(chan, "DUNDTECH", dr[x].tech);
pbx_builtin_setvar_helper(chan, "DUNDDEST", dr[x].dest);
break;
- }
- }
- } else {
- if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->cid.cid_num))
- chan->priority += 100;
+ }
+ }
+ } else if (option_priority_jumping)
+ ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
+
+ LOCAL_USER_REMOVE(u);
+
+ return 0;
+}
+
+static char *dundifunc_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+{
+ char *num;
+ char *context;
+ char *opts;
+ int results;
+ int x;
+ int bypass = 0;
+ struct localuser *u;
+ struct dundi_result dr[MAX_RESULTS];
+
+ LOCAL_USER_ACF_ADD(u);
+
+ buf[0] = '\0';
+
+ if (!data || ast_strlen_zero(data)) {
+ ast_log(LOG_WARNING, "DUNDILOOKUP requires an argument (number)\n");
+ LOCAL_USER_REMOVE(u);
+ return buf;
+ }
+
+ num = ast_strdupa(data);
+ if (!num) {
+ ast_log(LOG_ERROR, "Out of memory!\n");
+ LOCAL_USER_REMOVE(u);
+ return buf;
+ }
+
+ context = strchr(num, '|');
+ if (context) {
+ *context = '\0';
+ context++;
+ opts = strchr(context, '|');
+ if (opts) {
+ *opts = '\0';
+ opts++;
+ if (strchr(opts, 'b'))
+ bypass = 1;
+ }
+ }
+
+ if (!context || ast_strlen_zero(context))
+ context = "e164";
+
+ results = dundi_lookup(dr, MAX_RESULTS, NULL, context, num, bypass);
+ if (results > 0) {
+ sort_results(dr, results);
+ for (x = 0; x < results; x++) {
+ if (ast_test_flag(dr + x, DUNDI_FLAG_EXISTS)) {
+ snprintf(buf, len, "%s/%s", dr[x].tech, dr[x].dest);
+ break;
+ }
+ }
}
+
LOCAL_USER_REMOVE(u);
- return res;
+
+ return buf;
}
+static struct ast_custom_function dundi_function = {
+ .name = "DUNDILOOKUP",
+ .synopsis = "Do a DUNDi lookup of a phone number.",
+ .syntax = "DUNDILOOKUP(number[|context[|options]])",
+ .desc = "This will do a DUNDi lookup of the given phone number.\n"
+ "If no context is given, the default will be e164. The result of\n"
+ "this function will the Technology/Resource found in the DUNDi\n"
+ "lookup. If no results were found, the result will be blank.\n"
+ "If the 'b' option is specified, the internal DUNDi cache will\n"
+ "be bypassed.\n",
+ .read = dundifunc_read,
+};
static void mark_peers(void)
{
@@ -4630,6 +4716,7 @@ int unload_module(void)
ast_cli_unregister(&cli_precache);
ast_cli_unregister(&cli_queryeid);
ast_unregister_switch(&dundi_switch);
+ ast_custom_function_unregister(&dundi_function);
res = ast_unregister_application(app);
return res;
}
@@ -4643,7 +4730,7 @@ int reload(void)
int load_module(void)
{
- int res=0;
+ int res = 0;
struct sockaddr_in sin;
char iabuf[INET_ADDRSTRLEN];
@@ -4663,24 +4750,6 @@ int load_module(void)
return -1;
}
- ast_cli_register(&cli_debug);
- ast_cli_register(&cli_store_history);
- ast_cli_register(&cli_flush);
- ast_cli_register(&cli_no_debug);
- ast_cli_register(&cli_no_store_history);
- ast_cli_register(&cli_show_peers);
- ast_cli_register(&cli_show_entityid);
- ast_cli_register(&cli_show_trans);
- ast_cli_register(&cli_show_requests);
- ast_cli_register(&cli_show_mappings);
- ast_cli_register(&cli_show_precache);
- ast_cli_register(&cli_show_peer);
- ast_cli_register(&cli_lookup);
- ast_cli_register(&cli_precache);
- ast_cli_register(&cli_queryeid);
- if (ast_register_switch(&dundi_switch))
- ast_log(LOG_ERROR, "Unable to register DUNDi switch\n");
-
set_config("dundi.conf",&sin);
netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
@@ -4700,16 +4769,37 @@ int load_module(void)
if (setsockopt(netsocket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))
ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
- if (!res) {
- res = start_network_thread();
- if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "DUNDi Ready and Listening on %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
- } else {
+ res = start_network_thread();
+ if (res) {
ast_log(LOG_ERROR, "Unable to start network thread\n");
close(netsocket);
+ return -1;
}
- res = ast_register_application(app, dundi_lookup_exec, synopsis, descrip);
- return 0;
+
+ if (option_verbose > 1)
+ ast_verbose(VERBOSE_PREFIX_2 "DUNDi Ready and Listening on %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
+
+ ast_cli_register(&cli_debug);
+ ast_cli_register(&cli_store_history);
+ ast_cli_register(&cli_flush);
+ ast_cli_register(&cli_no_debug);
+ ast_cli_register(&cli_no_store_history);
+ ast_cli_register(&cli_show_peers);
+ ast_cli_register(&cli_show_entityid);
+ ast_cli_register(&cli_show_trans);
+ ast_cli_register(&cli_show_requests);
+ ast_cli_register(&cli_show_mappings);
+ ast_cli_register(&cli_show_precache);
+ ast_cli_register(&cli_show_peer);
+ ast_cli_register(&cli_lookup);
+ ast_cli_register(&cli_precache);
+ ast_cli_register(&cli_queryeid);
+ if (ast_register_switch(&dundi_switch))
+ ast_log(LOG_ERROR, "Unable to register DUNDi switch\n");
+ ast_register_application(app, dundi_lookup_exec, synopsis, descrip);
+ ast_custom_function_register(&dundi_function);
+
+ return res;
}
char *description(void)