diff options
-rwxr-xr-x | pbx/pbx_dundi.c | 210 |
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) |