clean up DUNDiLookup application
authorRussell Bryant <russell@russellbryant.com>
Tue, 18 Oct 2005 21:03:49 +0000 (21:03 +0000)
committerRussell Bryant <russell@russellbryant.com>
Tue, 18 Oct 2005 21:03:49 +0000 (21:03 +0000)
implement 'b' option to bypass DUNDi cache for the lookup
add DUNDILOOKUP dialplan function to eventually replace the application
mark DUNDiLookup application as deprecated
don't register all of the DUNDi goodies until after everything has initialized

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6825 65c4cc65-6c06-0410-ace0-fbb531ad65f3

pbx/pbx_dundi.c

index c7d5297..73e5346 100755 (executable)
@@ -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)